Preferences Screen Layout Customization

My requirements

Note. I need to support Android API 15 onwards.

In my PreferenceFragment, I dynamically add PreferenceScreen to the PreferenceCategory.

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

When the Activity settings display these PreferenceScreens, they are only displayed with a heading in a row, see image below. PreferenceScreen shown in a settings activity

I want to customize what is shown on this line. Ideally, I would like to have a headline with the summary below, an icon to the left of the heading / summary, and on some lines an icon to the right. See Layout Image below.

Desired rendering of my Preference Screen

PreferenceScreen.setWidgetLayoutResource (int widgetLayoutResId)

I know that I can use "setWidgetLayoutResource" to add an icon to the right of the line layout (and a resume with "setSummary"), using the following code in my settings.

 PreferenceScreen as = mgr.createPreferenceScreen(context); as.setTitle(name); as.setSummary(summary); as.setWidgetLayoutResource(R.layout.as_widget); myCategory.addPreference(as); 

where "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"/> 

this will create a user interface as shown below. Layout using setWidgetLayoutResource

This brings me closer to what I would like, but still not quite what I would like (there is no icon at the beginning of the line).

PreferenceScreen.setLayoutResource (int layoutResId)

I believe that if I use this, then I can control the rendering of the entire string. I saw examples of this in stackoverflow, for example

  • Setting preferences and changing the attribute in it
  • Create a custom layout for settings

In my opinion, the specified layout file should have the following

  • its root view with id "@android: id / widget_frame"
  • view with id android: id = "@ + android: id / title" (this is where the line specified in PreferenceScreen.setTitle)
  • view with id android: id = "@ + android: id / summary" (this is where the line specified in PreferenceScreen.setSummary is placed)

However, when I try to do this, Android Studio emits “@ + android: id / summary” with the error “Unable to resolve the character“ @ + android: id / summary. ”When the application launches my lines, they appear completely empty.

My java

 PreferenceScreen as = mgr.createPreferenceScreen(context); as.setTitle(name); as.setSummary(summary); as.setLayoutResource(R.layout.as_row_layout); myCategory.addPreference(as); 

And my layout

 <?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> 

Preference Screen Extension

I looked at the extended PreferenceScreen to overwrite its rendering, but it seems that this class has become final, so all the examples on the Internet that do it this way cannot be used.

+8
android layout preferencescreen
source share
2 answers

I managed to get this job.

The Preference class uses com.android.internal.R.layout.preference as its layout. This contains the ImageView for the icon on the left side, then the title and pivot text images, and finally the widget_frame layout on the right side.

By calling " PreferenceScreen.setIcon(..) ", you can set the portable to be placed as an icon image. By calling PreferenceScreen.setWidgetLayoutResource("...") , you can set the layout for placement in the widget_frame layout, in my case I placed the ImageView layout containing my image.

Here is my java code.

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

This creates a layout similar to the following unaligned icons

The problem with this layout is that the icons do not match the settings text below, which do not have icons.

This can be resolved by specifying the layout for PreferenceScreen . I copied Android preference.xml to my project (renaming it accordingly for my usecase) and I change ImageView to left pad and 0dp field.

FROM

 <ImageView android:id="@+android:id/icon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" /> 

to

 <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"/> 

Then I pointed out my copy of preference.xml for the PreferenceScreen layout. So now my 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); 

I believe that the reason my initial attempt to use PreferenceScreen.setLayoutResource did not work was because the specified layout was incorrect. The wrong layout had the whole layout with the identifier @android:id/widget_frame , i.e.

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/widget_frame" ...> ..... </LinearLayout> 

For the correct layout, you do not need an identifier for the main layout, but it must contain child views with the identifiers @+android:id/icon , @+android:id/title , @+android:id/summary , @+android:id/widget_frame , those.

 <?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> 
+13
source share

You can also customize the Preferences layout by overriding Preference.onCreateView(parent) . The example below uses an anonymous inner class for red preferences.

  screen.addPreference( new Preference(context) { @Override protected View onCreateView(ViewGroup parent) { View view = super.onCreateView(parent); view.setBackgroundColor(Color.RED); return view; } }); 
0
source share

All Articles