【问题标题】:Customizing the layout of a PreferenceScreen自定义 PreferenceScreen 的布局
【发布时间】:2015-01-30 16:42:29
【问题描述】:

我的要求

注意:我需要支持 Android API 15 及更高版本。

在我的 PreferenceFragment 中,我动态地将 PreferenceScreen 添加到 PreferenceCategory。

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

当设置 Activity 呈现这些 PreferenceScreens 时,它们的行中只有一个标题,请参见下图。

我想自定义此行中显示的内容。理想情况下,我希望标题下方有一个摘要,标题/摘要左侧有一个图标,并且在某些行的右侧有一个图标。请参阅下面的样机图片。

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上见过这样的例子,比如

据我了解,您指定的布局文件必须具有以下内容

  • 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 以覆盖它的呈现方式,但似乎这个类现在已经完成,所以互联网上所有这样做的例子都不能使用。

【问题讨论】:

    标签: android layout preference preferencescreen customizing


    【解决方案1】:

    我已经设法让它工作了。

    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>
    
    【解决方案2】:

    您还可以通过覆盖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;
                }
            });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-01-22
      • 1970-01-01
      • 1970-01-01
      • 2013-05-07
      • 1970-01-01
      • 1970-01-01
      • 2018-08-02
      • 2015-04-05
      相关资源
      最近更新 更多