ListPreference

本文介绍如何自定义Android Preference的UI样式,特别是针对ListPreference和EditTextPreference的问题,通过创建自定义类实现更友好的用户体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[size=medium][color=olive]preference_with_value.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:gravity="center_vertical"
android:paddingRight="?android:attr/scrollbarSize">

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

<LinearLayout
android:id="@+id/preference_first_line"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical">

<TextView android:id="@+android:id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="15dip"
android:layout_weight="1"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceLarge"
android:ellipsize="marquee"
android:fadingEdge="horizontal" />

<TextView android:id="@+id/preference_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="10"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceSmall"
android:gravity="right"
android:ellipsize="end" />

</LinearLayout>

<TextView android:id="@+android:id/summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/preference_first_line"
android:layout_alignLeft="@android:id/title"
android:textAppearance="?android:attr/textAppearanceSmall"
android:maxLines="2" />

</RelativeLayout>

</LinearLayout>

Code in Activity:

final ListPreference listPref = ...
listPref.setLayoutResource(R.layout.preference_with_value);
listPref.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
public boolean onPreferenceChange(Preference preference, Object newValue) {
TextView textView = (TextView) findViewById(R.id.preference_value);
int index = listPref.findIndexOfValue(newValue.toString());
if (index != -1) {
textView.setText(listPref.getEntries()[index]);
}
return true;
}
});

We can also write ListPreferenceWithValue and EditTextPreferenceWithValue classes to automate the above code:
package com.example;

import android.content.Context;
import android.preference.EditTextPreference;
import android.util.AttributeSet;
import android.view.View;
import android.widget.TextView;

public class EditTextPreferenceWithValue extends EditTextPreference {

private TextView mValueText;

public EditTextPreferenceWithValue(Context context, AttributeSet attrs) {
super(context, attrs);
setLayoutResource(R.layout.preference_with_value);
}

public EditTextPreferenceWithValue(Context context) {
super(context);
setLayoutResource(R.layout.preference_with_value);
}

@Override
protected void onBindView(View view) {
super.onBindView(view);
mValueText = (TextView) view.findViewById(R.id.preference_value);
if (mValueText != null) {
mValueText.setText(getText());
}
}

@Override
public void setText(String text) {
super.setText(text);
if (mValueText != null) {
mValueText.setText(getText());
}
}

}

preference_with_value.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:gravity="center_vertical"
android:paddingRight="?android:attr/scrollbarSize">

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

<LinearLayout
android:id="@+id/preference_first_line"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical">

<TextView android:id="@+android:id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="15dip"
android:layout_weight="1"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceLarge"
android:ellipsize="marquee"
android:fadingEdge="horizontal" />

<TextView android:id="@+id/preference_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="10"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceSmall"
android:gravity="right"
android:ellipsize="end" />

</LinearLayout>

<TextView android:id="@+android:id/summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/preference_first_line"
android:layout_alignLeft="@android:id/title"
android:textAppearance="?android:attr/textAppearanceSmall"
android:maxLines="2" />

</RelativeLayout>

</LinearLayout>

Code in Activity:

final ListPreference listPref = ...
listPref.setLayoutResource(R.layout.preference_with_value);
listPref.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
public boolean onPreferenceChange(Preference preference, Object newValue) {
TextView textView = (TextView) findViewById(R.id.preference_value);
int index = listPref.findIndexOfValue(newValue.toString());
if (index != -1) {
textView.setText(listPref.getEntries()[index]);
}
return true;
}
});

We can also write ListPreferenceWithValue and EditTextPreferenceWithValue classes to automate the above code:
package com.example;

import android.content.Context;
import android.preference.EditTextPreference;
import android.util.AttributeSet;
import android.view.View;
import android.widget.TextView;

public class EditTextPreferenceWithValue extends EditTextPreference {

private TextView mValueText;

public EditTextPreferenceWithValue(Context context, AttributeSet attrs) {
super(context, attrs);
setLayoutResource(R.layout.preference_with_value);
}

public EditTextPreferenceWithValue(Context context) {
super(context);
setLayoutResource(R.layout.preference_with_value);
}

@Override
protected void onBindView(View view) {
super.onBindView(view);
mValueText = (TextView) view.findViewById(R.id.preference_value);
if (mValueText != null) {
mValueText.setText(getText());
}
}

@Override
public void setText(String text) {
super.setText(text);
if (mValueText != null) {
mValueText.setText(getText());
}
}

}


Android Preference API already provide a unified UI style for preferences. However, for ListPreference, I feel some inconvenience about its default behaviors:

In the preference screen, the user can't see the current selected value of a ListPreference;
When the user selects an item in a list preference popup, the popup is dismissed immediately, without any UI feedback about which item has been selected.
I noticed that some applications change the behavior by displaying the current selected value in the place of the summary of the preference, which looks better to me. However, this causes there's no place to display the summary.

I think it might be better to display the current selected value at the right side of the ListPreference.

EditTextPreference has the similar problems. [/color][/size]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值