自定义PreferenceScreen的布局 [英] Customizing the layout of a PreferenceScreen
问题描述
我的要求
注意:我需要支持Android API 15及更高版本.
在我的PreferenceFragment中,我正在将PreferenceScreen动态地添加到PreferenceCategory中.
In my PreferenceFragment I am dynamically adding PreferenceScreen's to a PreferenceCategory.
PreferenceScreen as = mgr.createPreferenceScreen(context);
as.setTitle(name);
myCategory.addPreference(as);
当设置活动"渲染这些PreferenceScreen时,仅在其行中显示了标题,请参见下图.
When the settings Activity renders these PreferenceScreens are rendered with just a title in it's row, see the image below.
我想自定义此行中显示的内容.理想情况下,我希望标题下面带有一个摘要,标题/摘要的左侧是一个图标,而在某些行上,右侧则是一个图标.请参见下面的样机图片.
I want to customize what is shown in this row. Ideally I would like to have a title with a summary below, an icon to the left of the title/summary and on certain rows an icon on the right hand side. See the mockup image below.
PreferenceScreen.setWidgetLayoutResource(int widgetLayoutResId)
PreferenceScreen.setWidgetLayoutResource(int widgetLayoutResId)
我知道我可以在设置活动中使用以下代码,使用"setWidgetLayoutResource"在行布局的右侧添加图标(以及带有"setSummary"的摘要)
I know I can use "setWidgetLayoutResource" to add an icon to the right of the row layout (and a summary with "setSummary") using the following code in my settings activity
PreferenceScreen as = mgr.createPreferenceScreen(context);
as.setTitle(name);
as.setSummary(summary);
as.setWidgetLayoutResource(R.layout.as_widget);
myCategory.addPreference(as);
"as_widget.xml"所在的位置
where "as_widget.xml" is
<?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
this will produce UI like the following
这使我更接近我想要的东西,但仍然不是我想要的东西(在行首缺少该图标).
This gets me closer to what I would like but still not exactly what I would like (missing the icon at the beginning of the row).
PreferenceScreen.setLayoutResource(int layoutResId)
PreferenceScreen.setLayoutResource(int layoutResId)
我相信,如果我使用它,那么我可以控制整个行的呈现.我已经在stackoverflow上看到了这样的示例,例如
I believe if I use this, then I can control the rendering of the whole row. I have seen examples of this on stackoverflow, such as
- Setting preference layout and changing the attribute in it
- Creating a custom layout for preferences
据我了解,您指定的布局文件必须具有以下内容
From my understanding the layout file you specify has to have the following
- 其ID为"@android:id/widget_frame"的根视图
- 一个ID为android:id ="@ + android:id/title"的视图(这是 放置在PreferenceScreen.setTitle中指定的字符串)
- 一个ID为android:id ="@ + android:id/summary"的视图(在此处 放置在PreferenceScreen.setSummary中指定的字符串)
- its root View with the id "@android:id/widget_frame"
- a view with the id android:id="@+android:id/title" (this is where the string specified in PreferenceScreen.setTitle is placed)
- a view with the id android:id="@+android:id/summary" (this is where the string specified in PreferenceScreen.setSummary is placed)
但是,当我尝试执行此操作时,Android Studio突出显示"@ + android:id/summary",错误为无法解析符号'@ + android:id/summary'.当应用程序运行时,我的行会完全呈现空白.
However when I try and do this, Android Studio highlights "@+android:id/summary" with the error "Can not resolve symbol '@+android:id/summary'. When the application runs my rows are rendered completely blank.
我的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来覆盖它的呈现方式,但看来该类现在已经定型了,因此无法使用Internet上以这种方式进行操作的所有示例.
I looked at extended PreferenceScreen to overwrite how it renders, but it appears this class has now been made final so all examples on the internet that do it that way can not be used.
推荐答案
我设法使它正常工作.
Preference
类使用com.android.internal.R.layout.preference
作为其布局.它在左侧包含一个ImageView图标,然后在标题和摘要文本视图中包含一个图标,最后在右侧包含一个widget_frame
布局.
The Preference
class uses com.android.internal.R.layout.preference
as its layout. This contains an ImageView for an icon on the left hand side, then the title and summary textviews and finally a widget_frame
Layout on the right hand side.
通过调用"PreferenceScreen.setIcon(..)
",可以将可绘制对象设置为放置在图标图像视图中.通过调用PreferenceScreen.setWidgetLayoutResource("...")
,您可以将布局设置为放置在widget_frame
布局中,在我的情况下,我将放置一个包含图像的ImageView布局.
By calling "PreferenceScreen.setIcon(..)
" you can set the drawable to place in the icon image view. By calling PreferenceScreen.setWidgetLayoutResource("...")
you can set the layout to place in the widget_frame
layout, in my case I put an ImageView layout containing my image.
这是我的Java代码.
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 produces a layout like the following
这种布局的问题是图标未与下面没有图标的首选项文本对齐.
The problem with this layout is that the icons do not left align with the text of the preferences below which have no icons.
这也可以通过指定PreferenceScreen
的布局来解决.我将Android的preference.xml
复制到了我的项目中(针对我的用例对其进行了适当的命名),然后更改了ImageView的左侧填充和空白值为0dp.
This can be resolved by specifying the layout for the PreferenceScreen
as well. I copied Android's preference.xml
into my project (renaming it appropriately for my usecase) and I changing the ImageView to have a left padding and margin of 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现在是
I then specified my copy of preference.xml
for the PreferenceScreen's layout. So my java is now
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
,即
I believe the reason my original attempt at using PreferenceScreen.setLayoutResource
was not working was because the layout I specified was incorrect. The incorrect layout had the whole layout with an id of @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>
正确的布局不需要主布局的ID,但需要包含ID为@+android:id/icon
,@+android:id/title
,@+android:id/summary
,@+android:id/widget_frame
的子视图,即
The correct layout does not need an id for the main layout, but needs to contain child views with ids of @+android:id/icon
, @+android:id/title
, @+android:id/summary
, @+android:id/widget_frame
, i.e.
<?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>
这篇关于自定义PreferenceScreen的布局的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!