web-dev-qa-db-ja.com

PreferenceScreenのレイアウトのカスタマイズ

私の要件

注:Android API 15以降をサポートする必要があります。

PreferenceFragmentで、PreferenceScreenをPreferenceCategoryに動的に追加しています。

PreferenceScreen as = mgr.createPreferenceScreen(context);
as.setTitle(name); 
myCategory.addPreference(as);

設定アクティビティがレンダリングする場合、これらのPreferenceScreenは、行にタイトルのみが表示されてレンダリングされます。下の画像を参照してください。 PreferenceScreen shown in a settings activity

この行に表示されるものをカスタマイズしたいと思います。理想的には、下に要約があり、タイトル/要約の左側にアイコンがあり、特定の行に右側にアイコンがあるタイトルが必要です。以下のモックアップ画像を参照してください。

Desired rendering of my Preference Screen

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が生成されます Layout using setWidgetLayoutResource

これにより、私は自分が望むものに近づきますが、それでも私が望むものとは正確には一致しません(行の先頭にあるアイコンがありません)。

PreferenceScreen.setLayoutResource(int layoutResId)

これを使えば、行全体のレンダリングを制御できると思います。私は次のようなstackoverflowでこれの例を見てきました

私の理解では、指定するレイアウトファイルには次のものが必要です。

  • iDが「@Android:id/widget_frame」のルートビュー
  • iDがAndroid:id = "@ + Android:id/title"のビュー(これは、PreferenceScreen.setTitleで指定された文字列が配置される場所です)
  • iDがAndroid:id = "@ + Android:id/summary"のビュー(これは、PreferenceScreen.setSummaryで指定された文字列が配置される場所です)

ただし、これを実行しようとすると、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を調べて、レンダリング方法を上書きしましたが、このクラスは現在最終版になっているため、そのようにするインターネット上のすべての例を使用することはできません。

13
se22as

私はこれをうまく機能させることができました。

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);

これにより、次のようなレイアウトが生成されます unaligned icons

このレイアウトの問題は、アイコンがアイコンのない以下の設定のテキストと整列しないことです。

これは、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>
18
se22as

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;
            }
        });
0
Roger Keays