私の要件
注:Android API 15以降をサポートする必要があります。
PreferenceFragmentで、PreferenceScreenをPreferenceCategoryに動的に追加しています。
PreferenceScreen as = mgr.createPreferenceScreen(context);
as.setTitle(name);
myCategory.addPreference(as);
設定アクティビティがレンダリングする場合、これらのPreferenceScreenは、行にタイトルのみが表示されてレンダリングされます。下の画像を参照してください。
この行に表示されるものをカスタマイズしたいと思います。理想的には、下に要約があり、タイトル/要約の左側にアイコンがあり、特定の行に右側にアイコンがあるタイトルが必要です。以下のモックアップ画像を参照してください。
PreferenceScreen.setWidgetLayoutResource(int widgetLayoutResId)
設定アクティビティで次のコードを使用して、「setWidgetLayoutResource」を使用して行レイアウトの右側にアイコン(および「setSummary」の要約)を追加できることを知っています。
PreferenceScreen as = mgr.createPreferenceScreen(context);
as.setTitle(name);
as.setSummary(summary);
as.setWidgetLayoutResource(R.layout.as_widget);
myCategory.addPreference(as);
ここで、「as_widget.xml」は
<?xml version="1.0" encoding="utf-8"?>
<ImageView
xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:src="@drawable/ic_action_favorite"/>
これにより、次のようなUIが生成されます
これにより、私は自分が望むものに近づきますが、それでも私が望むものとは正確には一致しません(行の先頭にあるアイコンがありません)。
PreferenceScreen.setLayoutResource(int layoutResId)
これを使えば、行全体のレンダリングを制御できると思います。私は次のようなstackoverflowでこれの例を見てきました
私の理解では、指定するレイアウトファイルには次のものが必要です。
ただし、これを実行しようとすると、Android Studioは「@ + Android:id/summary」を強調表示し、「シンボル '@ + Android:id/summary'を解決できません」というエラーが表示されます。アプリケーションの場合実行すると、行が完全に空白になります。
私のJavaは
PreferenceScreen as = mgr.createPreferenceScreen(context);
as.setTitle(name);
as.setSummary(summary);
as.setLayoutResource(R.layout.as_row_layout);
myCategory.addPreference(as);
そして私のレイアウトは
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:id="@Android:id/widget_frame"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:minHeight="?android:attr/listPreferredItemHeight"
Android:gravity="center_vertical"
Android:paddingRight="?android:attr/scrollbarSize">
<ImageView
Android:id="@+id/icon1"
Android:src="@drawable/ic_action_email"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_gravity="center" />
<RelativeLayout
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_marginLeft="15dip"
Android:layout_marginRight="6dip"
Android:layout_marginTop="6dip"
Android:layout_marginBottom="6dip"
Android:layout_weight="1">
<TextView Android:id="@+Android:id/title"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:singleLine="true"
Android:textAppearance="?android:attr/textAppearanceLarge"
Android:ellipsize="Marquee"
Android:fadingEdge="horizontal" />
<TextView Android:id="@+Android:id/summary"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_below="@Android:id/title"
Android:layout_alignLeft="@Android:id/title"
Android:textAppearance="?android:attr/textAppearanceSmall"
Android:textColor="?android:attr/textColorSecondary"
Android:maxLines="4" />
</RelativeLayout>
<ImageView
Android:id="@+id/icon2"
Android:src="@drawable/ic_action_favorite"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_gravity="center" />
</LinearLayout>
PreferenceScreenの拡張
拡張されたPreferenceScreenを調べて、レンダリング方法を上書きしましたが、このクラスは現在最終版になっているため、そのようにするインターネット上のすべての例を使用することはできません。
私はこれをうまく機能させることができました。
Preference
クラスは、レイアウトとしてcom.Android.internal.R.layout.preference
を使用します。これには、左側にアイコンのImageViewが含まれ、次にタイトルと要約のテキストビュー、最後に右側にwidget_frame
レイアウトが含まれます。
「PreferenceScreen.setIcon(..)
」を呼び出すことにより、アイコン画像ビューに配置するようにドローアブルを設定できます。 PreferenceScreen.setWidgetLayoutResource("...")
を呼び出すことで、レイアウトをwidget_frame
レイアウトに配置するように設定できます。私の場合、画像を含むImageViewレイアウトを配置します。
これが私のJavaコードです。
PreferenceScreen as = mgr.createPreferenceScreen(context);
as.setTitle(name);
as.setSummary(summary);
// add an icon to the PreferenceScreen,
// this is rendered on the left hand side of the row
accountScreen.setIcon(R.drawable.my_pref_icon);
// specify the layout to inflate into the widget area on the
// right hand side of the row, this layout is just my image
as.setWidgetLayoutResource(R.layout.as_widget);
myCategory.addPreference(as);
これにより、次のようなレイアウトが生成されます
このレイアウトの問題は、アイコンがアイコンのない以下の設定のテキストと整列しないことです。
これは、PreferenceScreen
のレイアウトも指定することで解決できます。 Androidのpreference.xml
をプロジェクトにコピーし(ユースケースに合わせて名前を変更)、ImageViewを変更して左のパディングとマージンを0dpにしました。
から
<ImageView
Android:id="@+Android:id/icon"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_gravity="center"
/>
に
<ImageView
Android:id="@+Android:id/icon"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_gravity="center"
Android:paddingLeft="0dp"
Android:layout_marginLeft="0dp"/>
次に、PreferenceScreenのレイアウトにpreference.xml
のコピーを指定しました。だから私のJavaは今
PreferenceScreen as = mgr.createPreferenceScreen(context);
as.setTitle(name);
as.setSummary(summary);
// add an icon to the PreferenceScreen,
// this is rendered on the left hand side of the row
accountScreen.setIcon(R.drawable.my_pref_icon);
// specify the layout to inflate into the widget area on the
// right hand side of the row, this layout is just my image
as.setWidgetLayoutResource(R.layout.as_widget);
// specify the layout for the preference screen row when it is
// rendered as a row in a preference activity/fragment
as.setLayoutResource(R.layout.preference_row_layout);
myCategory.addPreference(as);
PreferenceScreen.setLayoutResource
を使用する最初の試みが機能しなかった理由は、指定したレイアウトが正しくなかったためだと思います。間違ったレイアウトには全体のレイアウトがあり、IDは@Android:id/widget_frame
でした。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:id="@Android:id/widget_frame" ...>
.....
</LinearLayout>
正しいレイアウトにはメインレイアウトのIDは必要ありませんが、子ビューを含む必要があります。IDは@+Android:id/icon
、@+Android:id/title
、@+Android:id/summary
、@+Android:id/widget_frame
、つまり.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
....>
<ImageView Android:id="@+Android:id/icon" ....>
....
<TextView Android:id="@+Android:id/title" ...>
....
<TextView Android:id="@+Android:id/summary" ...>
....
<LinearLayout Android:id="@+Android:id/widget_frame" ..>
....
</LinearLayout>
Preference.onCreateView(parent)
をオーバーライドして、設定のレイアウトをカスタマイズすることもできます。以下の例では、匿名の内部クラスを使用して赤の設定を行います。
screen.addPreference(
new Preference(context) {
@Override
protected View onCreateView(ViewGroup parent) {
View view = super.onCreateView(parent);
view.setBackgroundColor(Color.RED);
return view;
}
});