我正在尝试显示一个switchPreference,它允许用户根据英里或公里显示距离。我使用的是SwitchPreferenceCompat支持库。根据该库,我可以使用textSwitchOff和textSwitchOn向交换机添加文本。我只想向我的交换机添加"km“或"miles”,以便用户知道显示的是哪个指标。
根据this doc的说法,我所需要的只是以下代码:
<android.support.v7.preference.PreferenceCategory
android:layout="@layout/preferences_category"
android:title="Distance" >
<android.support.v7.preference.SwitchPreferenceCompat android:title="KM or Miles"
android:key="kmormiles"
android:switchTextOff="miles"
android:switchTextOn="km"
android:defaultValue="true"/>
</android.support.v7.preference.PreferenceCategory>然而,交换机看起来就像一个普通的交换机,交换机本身没有额外的文本。

如何让它与textOn和textOff一起显示?
我还尝试了以下几种方法:
addPreferencesFromResource(R.xml.preferences);
kmormiles = (SwitchPreferenceCompat) findPreference("kmormiles");
kmormiles.setSwitchTextOff("Km");
kmormiles.setSwitchTextOn("miles");还是不管用。我在两个不同的genymotion模拟器上尝试它,API16和API21。
发布于 2016-02-23 05:58:55
因为SwitchPreferenceCompat默认使用SwitchCompat小部件,所以Android Switch widget textOn and textOff not working in Lollipop在这里也有一个应用程序。和第一个语句
默认情况下,
文本不会显示在Material theme下,因为switch小部件资源不能很好地处理文本。
也解释了为什么结果看起来一点都不好。
SwitchPreferenceCompat类本身不提供设置是否显示开/关文本的可能性。因此,让它工作的一种方法是重写onBindViewHolder(PreferenceViewHolder)方法,以编程方式设置它。
另一种可能是更好的方法是利用主题机制,无论如何,您都必须与preference compat库一起使用。您不能直接为视图设置任何属性,但可以定义与android:widgetLayout一起使用的布局。所以只需创建您自己的偏好主题覆盖
<style name="MyPreferenceThemeOverlay" parent="PreferenceThemeOverlay">
<item name="switchPreferenceCompatStyle">@style/MySwitchPreferenceCompat</item>
</style>使用您自己的切换首选项样式
<style name="MySwitchPreferenceCompat" parent="Preference.SwitchPreferenceCompat">
<item name="android:widgetLayout">@layout/pref_stack</item>
</style>使用稍微修改过的default switch layout
<android.support.v7.widget.SwitchCompat
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/switchWidget"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@null"
android:clickable="false"
android:focusable="false"
app:showText="true" />您应该记住的另一件事是compat功能本身。显式地使用android.support.v7.preference.SwitchPreferenceCompat,你将永远不会得到像当前唯一可用的替代android.support.v14.preference.SwitchPreferenceCompat那样更适合充气装置自动知道的更新设备的版本。不过,这可能会涉及到你方更多的工作。
编辑:这是发帖者实施上述建议的结果,正如他正确地提到的,结果看起来一点也不好:


发布于 2019-04-09 02:47:06
基于tynn重写OnBindViewHolder方法的选择,我已经实现了它,并且它正在工作。因此,我将在这里发布带有解释性注释的代码,以防有人想要使用它。
注意:我是在Xamarin.Android上开发我的应用程序,所以代码是用C#编写的,但是把它翻译成Java (或Kotlin)应该很直观。
CustomSwitchPreferenceWidget.cs
namespace KeepTravelling.Ui
{
class CustomSwitchPreferenceWidget : SwitchPreferenceCompat
{
private int TitleId = 0;
private bool IsTitleFound => TitleId > 0; //equivalent to bool IsTitleFound(){ return TitleId > 0};
public string TextWhenOn { get; set; }//getters and setters
public string TextWhenOff { get; set; }
public CustomSwitchPreferenceWidget(Context context, IAttributeSet attrs) : base(context, attrs)
{
TypedArray attrsArray = context.ObtainStyledAttributes(attrs, Resource.Styleable.CustomSwitchPreferenceWidget);
TextWhenOn = attrsArray.GetString(Resource.Styleable.CustomSwitchPreferenceWidget_textWhenOn);
TextWhenOff = attrsArray.GetString(Resource.Styleable.CustomSwitchPreferenceWidget_textWhenOff);
}
//Method that will search through holder element for a view with id = "title"
//Once found it will store it in TitleId member
private void FindTitleId(PreferenceViewHolder holder)
{
//Base element is a LinearLayout, but you can check it again to make sure it is
LinearLayout layout = (LinearLayout)holder.ItemView;
for (int i = 0; i < layout.ChildCount; i++)
{
var item = layout.GetChildAt(i);
if (item.GetType().ToString().Contains("Layout")) //check if child element is a layout view
{
ViewGroup group = (ViewGroup)item;
for (int j = 0; j < group.ChildCount; j++)
{
var nestedItem = group.GetChildAt(j);
string entryName = Context.Resources.GetResourceEntryName(nestedItem.Id);
if (entryName.Equals("title"))//we are looking for the TextView with id = "title"
{
//If we found it, store in TitleId member and return from the method
TitleId = nestedItem.Id;
return;
}
if (nestedItem.GetType().ToString().Contains("Layout"))
{
ViewGroup nestedGroup = (ViewGroup)nestedItem;
for (int k = 0; k < nestedGroup.ChildCount; k++)//3 levels should be enough and it actually never arrive here
{
var nestedNestedItem = nestedGroup.GetChildAt(k);
string nestedEntryName = Context.Resources.GetResourceEntryName(nestedNestedItem.Id);
if (entryName.Equals("title"))
{
TitleId = nestedNestedItem.Id;
return;
}
}
}
}
}
}
}
public override void OnBindViewHolder(PreferenceViewHolder holder)
{
base.OnBindViewHolder(holder);
//Check if we already have found it
if (!IsTitleFound)
{
//If not => find it!!
FindTitleId(holder);
//If for some reason it is not found, return from method
if (!IsTitleFound) return;
}
AppCompatTextView title = (AppCompatTextView)holder.FindViewById(TitleId);
if (title != null)
{
if (MChecked)//MChecked value is self-explanatory
{
title.Text = TextWhenOn;
}
else
{
title.Text = TextWhenOff;
}
}
}
}}
然后必须在values/attrs.xml中声明属性,如下所示:
Resources/values/attrs.xml
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<declare-styleable name="CustomSwitchPreferenceWidget">
<attr name="textWhenOn" format="string"/>
<attr name="textWhenOff" format="string"/>
</declare-styleable>
</resources>现在,您可以在布局中使用它们(在我的示例中,我在首选项文件中使用它):Resources/xml/preferences.axml
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:customAttrs="http://schemas.android.com/apk/res-auto2">
<!-- More items -->
<!-- ... -->
<KeepTravelling.Ui.CustomSwitchPreferenceWidget
android:defaultValue="true"
android:title="Start location service"
android:key="start_stop_option"
android:summary="If this option is turned off the service won't be running and thus you will not get new locations."
customAttrs:textWhenOn="Text when ON"
customAttrs:textWhenOff="Text when OFF">
</KeepTravelling.Ui.CustomSwitchPreferenceWidget>
</PreferenceScreen>注意,您应该声明您正在使用的xml名称空间,这样它就不会与android的名称空间匹配。URL不需要存在,它只需要是在项目中唯一的任何字符串。
结果是:

请随时提出任何问题。
编辑:使代码泛型,因此它可以用于任何目的。
https://stackoverflow.com/questions/35415907
复制相似问题