Android 具有自定义布局的SwitchPreference侦听器
我试图在设置页面中使用SwitchPreference,但无法让侦听器正常工作。我使用自定义小部件布局来设置开关的样式,因为我找不到如何使用主题来实现这一点。在my settings.xml中,我有以下内容:Android 具有自定义布局的SwitchPreference侦听器,android,preferencefragment,android-switch,Android,Preferencefragment,Android Switch,我试图在设置页面中使用SwitchPreference,但无法让侦听器正常工作。我使用自定义小部件布局来设置开关的样式,因为我找不到如何使用主题来实现这一点。在my settings.xml中,我有以下内容: <SwitchPreference android:key="uitestmode" android:summary="Enable to display test data in fragments" andr
<SwitchPreference
android:key="uitestmode"
android:summary="Enable to display test data in fragments"
android:title="UI Test Mode"
android:widgetLayout="@layout/widget_custom_switch_on_off" >
</SwitchPreference>
以及我的交换机的自定义布局:
<?xml version="1.0" encoding="utf-8"?>
<Switch xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/custom_switch_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:textColor="@android:color/white"
android:textIsSelectable="false"
android:textSize="18sp"
android:textOn="On"
android:textOff="Off"
android:textStyle="bold"
android:thumb="@drawable/carcast_switch_inner_holo_dark"
android:track="@drawable/carcast_switch_track_holo_dark" />
我遇到的问题是,当我单击开关时,侦听器没有被调用。有人知道为什么以及如何修复吗?我遇到了同样的问题,我的解决方案与以下类似:
public class MySwitchPreference extends SwitchPreference {
public MySwitchPreference(Context context) {
super(context, null);
}
public MySwitchPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MySwitchPreference(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
protected void onBindView(View view) {
// Clean listener before invoke SwitchPreference.onBindView
ViewGroup viewGroup= (ViewGroup)view;
clearListenerInViewGroup(viewGroup);
super.onBindView(view);
final Switch mySwitch = (Switch) view.findViewById(R.id.custom_switch_item);
Boolean initVal = this.getPersistedBoolean(false);
if (initVal) {
mySwitch.setChecked(true);
}
this.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
//Do your things here, toggling the switch and so on
return true;
}
});
}
private void clearListenerInViewGroup(ViewGroup viewGroup) {
if (null == viewGroup) {
return;
}
int count = viewGroup.getChildCount();
for(int n = 0; n < count; ++n) {
View childView = viewGroup.getChildAt(n);
if(childView instanceof Switch) {
final Switch switchView = (Switch) childView;
switchView.setOnCheckedChangeListener(null);
return;
} else if (childView instanceof ViewGroup){
ViewGroup childGroup = (ViewGroup)childView;
clearListenerInViewGroup(childGroup);
}
}
}
}
public类MySwitchPreference扩展了SwitchPreference{
公共MySwitchPreference(上下文){
super(上下文,null);
}
公共MySwitchPreference(上下文、属性集属性){
超级(上下文,attrs);
}
公共MySwitchPreference(上下文、属性集属性、int-defStyle){
超级(上下文、属性、定义样式);
}
受保护的void onBindView(视图){
//在调用SwitchPreference.onBindView之前清除侦听器
ViewGroup ViewGroup=(ViewGroup)视图;
clearListenerInViewGroup(视图组);
super.onBindView(视图);
最终开关mySwitch=(开关)view.findViewById(R.id.custom\u开关\u项);
Boolean initVal=this.getPersistedBoolean(false);
if(initVal){
mySwitch.setChecked(true);
}
this.setOnPreferenceChangeListener(新的OnPreferenceChangeListener(){
@凌驾
公共布尔onPreferenceChange(首选项首选项,对象newValue){
//在这里做你的事情,拨动开关等等
返回true;
}
});
}
私有void clearListenerInViewGroup(视图组视图组){
如果(null==viewGroup){
返回;
}
int count=viewGroup.getChildCount();
对于(int n=0;n
希望这能帮助你。直到我用这种方法解决了这个问题,我才找到任何解决方案。–根据答案,但同时适用于Switch和SwitchCompat。SwitchView的id应该是
@android:id/Switch\u widget
,而不是@+id/custom\u Switch\u item
或任何其他自定义id
在SwitchPreference
类的源代码中,我们可以找到以下代码:
View-switchView=View.findviewbyd(AndroidResources.ANDROID\R\u-SWITCH\u小部件);
在AndroidResources
中:
static final int-ANDROID\u-R\u-SWITCH\u WIDGET=ANDROID.R.id.SWITCH\u WIDGET;
因此,只有id=@android:id/switch\u小部件才能正确找到
下面是关于SwitchPreference的widgetLayout的演示:
嘿,里克凯斯,我用过这个,你觉得这个解决方案很有魅力。但是我想要一些额外的功能。不确定我是否需要为它制作一个新的主题,但可能是Nelson b。奥斯汀也想要这个。我想要的是我的偏好在点击时改变(你的改变是什么),而且是可滑动的,让这个改变成为我的偏好。通过将android:clickable更改为true,可以使其可滑动。但是他的计划破坏了你以前的解决方案。你知道怎么做吗?亲切问候,,Jeroen@Jeroen我自己没有机会尝试,但我想你可能想尝试以下几点:1。将android:clickable设置为true。2.设置为开关,并手动更新首选项。这可能会有帮助。谢谢,这就是解决方案
public class MySwitchPreference extends SwitchPreference {
public MySwitchPreference(Context context) {
super(context, null);
}
public MySwitchPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MySwitchPreference(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
protected void onBindView(View view) {
// Clean listener before invoke SwitchPreference.onBindView
ViewGroup viewGroup= (ViewGroup)view;
clearListenerInViewGroup(viewGroup);
super.onBindView(view);
final Switch mySwitch = (Switch) view.findViewById(R.id.custom_switch_item);
Boolean initVal = this.getPersistedBoolean(false);
if (initVal) {
mySwitch.setChecked(true);
}
this.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
//Do your things here, toggling the switch and so on
return true;
}
});
}
private void clearListenerInViewGroup(ViewGroup viewGroup) {
if (null == viewGroup) {
return;
}
int count = viewGroup.getChildCount();
for(int n = 0; n < count; ++n) {
View childView = viewGroup.getChildAt(n);
if(childView instanceof Switch) {
final Switch switchView = (Switch) childView;
switchView.setOnCheckedChangeListener(null);
return;
} else if (childView instanceof ViewGroup){
ViewGroup childGroup = (ViewGroup)childView;
clearListenerInViewGroup(childGroup);
}
}
}
}