setOnPreferenceChangeListener 不适用于自定义复选框首选项

发布于 2024-12-11 15:44:13 字数 2146 浏览 0 评论 0原文

我对 CheckBoxPreference 做了一个简单的扩展,这样我就可以拥有自己的自定义视图,并且标题左侧有一个图像图标。代码如下:

public class CustomCheckBoxPreference extends CheckBoxPreference {

private Drawable icon;

public CustomCheckBoxPreference(Context context, AttributeSet attrs) {
    super(context, attrs);
    TypedArray arr = context.obtainStyledAttributes(attrs, R.styleable.CustomCheckBoxPreference, 0, 0);
    icon = arr.getDrawable(R.styleable.CustomCheckBoxPreference_icon);
    setLayoutResource(R.layout.custom_checkbox_pref);
}

@Override
protected void onBindView(View view) {
    super.onBindView(view);
    ImageView prefsIcon = (ImageView) view.findViewById(R.id.prefs_icon);
    prefsIcon.setImageDrawable(icon);
}

问题是,由于某种原因,我设置为任何 CustomCheckboxPreferenceOnPreferenceChangeListener 没有效果并且没有存储。我尝试重写一些 android 方法来实现调用 super,然后打印一行以查看调用了什么。值得注意的是,callChangeListener 不会被调用。正是这个方法导致了 onPreferenceChanged 的回调。我尝试在 setChecked 内部调用 onPreferenceChanged 只是为了看看会发生什么,并且 OnPreferenceChangeListener 为空:

            getOnPreferenceChangeListener().onPreferenceChange(this, checked);

这就是我设置preferencechangelistener的方式:

        mTwitterPref.setChecked(!mTwitter.needsAuth());
    mTwitterPref.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
        @Override
        public boolean onPreferenceChange(Preference preference, Object newValue) {
            System.out.println("Twitter Preference Changed!");
            if ((Boolean) newValue) {
                if (mTwitter.needsAuth()) {
                    System.out.println("We Need To Login To Twitter!");
                    IntentUtils.startActivityForResult(ProfileAccountsActivity.this,
                            TwLoginActivity.class, ACTIVITY_OAUTH);
                }
            } else {
              showDialog(DIALOG_LOGOUT_TWITTER);
            }
            return false;
        }
    });

我有点困惑至于为什么 preferencechangelistener 无法正常工作,因为我只覆盖了 onBindView 和构造函数;我在两者中都称之为超级。有什么想法吗?

I made a simple extension of CheckBoxPreference so that I could have my own custom view with an image icon to the left of the title. The code is below:

public class CustomCheckBoxPreference extends CheckBoxPreference {

private Drawable icon;

public CustomCheckBoxPreference(Context context, AttributeSet attrs) {
    super(context, attrs);
    TypedArray arr = context.obtainStyledAttributes(attrs, R.styleable.CustomCheckBoxPreference, 0, 0);
    icon = arr.getDrawable(R.styleable.CustomCheckBoxPreference_icon);
    setLayoutResource(R.layout.custom_checkbox_pref);
}

@Override
protected void onBindView(View view) {
    super.onBindView(view);
    ImageView prefsIcon = (ImageView) view.findViewById(R.id.prefs_icon);
    prefsIcon.setImageDrawable(icon);
}

The problem is that for some reason the OnPreferenceChangeListener I set to any CustomCheckboxPreference has no effect and is not stored. I tried overriding some of the android methods for the implementation calling super and then printing a line to see what gets called. Notably callChangeListener does not get called. It is this method that leads to the callback for onPreferenceChanged. I tried throwing in a call to onPreferenceChanged inside of setChecked just to see what would happen and the OnPreferenceChangeListener is null:

            getOnPreferenceChangeListener().onPreferenceChange(this, checked);

This is how I set the preferencechangelistener:

        mTwitterPref.setChecked(!mTwitter.needsAuth());
    mTwitterPref.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
        @Override
        public boolean onPreferenceChange(Preference preference, Object newValue) {
            System.out.println("Twitter Preference Changed!");
            if ((Boolean) newValue) {
                if (mTwitter.needsAuth()) {
                    System.out.println("We Need To Login To Twitter!");
                    IntentUtils.startActivityForResult(ProfileAccountsActivity.this,
                            TwLoginActivity.class, ACTIVITY_OAUTH);
                }
            } else {
              showDialog(DIALOG_LOGOUT_TWITTER);
            }
            return false;
        }
    });

I am a bit confused as to why the preferencechangelistener is not working properly as I only overwrite onBindView and the constructor; I call super in both. Any thoughts?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

述情 2024-12-18 15:44:13

在复选框上设置 android:focusable="false" 和 android:clickable="false":

<CheckBox
    android:id="@+android:id/checkbox"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" 
    android:focusable="false"
    android:clickable="false" />

有关此线程的更多信息:自定义 ArrayAdapter 上的可点击行

Set android:focusable="false" and android:clickable="false" on the CheckBox:

<CheckBox
    android:id="@+android:id/checkbox"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" 
    android:focusable="false"
    android:clickable="false" />

More info on this thread: Clickable rows on custom ArrayAdapter

夜司空 2024-12-18 15:44:13

我对自定义按钮也有同样的问题。我尝试了@jeanh 提供的解决方案,它有效。但我的按钮没有被按下,只有它周围的区域被突出显示。此外,如果你有几个按钮怎么办?显然,这个解决方案行不通。因此,我决定深入挖掘,我的解决方案如下:

xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/widget_frame" android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="15dp"
android:paddingTop="5dp"
android:paddingRight="10dp"
android:paddingBottom="5dp"    
>
<!-- define my button -->
<Button android:id="@android:id/title"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textSize="17sp"
        android:typeface="sans"
        android:textStyle="bold"
        android:textColor="#000000"
></Button>    

</RelativeLayout>

Java 类:

public class ButtonPreference extends Preference {

    private final String TAG = getClass().getName();

    public interface ButtonListener {      
        public void onCustomClick();
    }

    public ButtonListener buttonListener;

    public void setButtonListener(ButtonListener buttonListener){
        this.buttonListener = buttonListener;
    }

    public ButtonPreference(Context context, AttributeSet attrs) {
        super(context, attrs);       
    }

    public ButtonPreference(Context context, AttributeSet attrs, int  defStyle) {
        super(context, attrs, defStyle);        
    }

    @Override
    protected View onCreateView(ViewGroup parent){

        RelativeLayout layout =  null;

        try {
            LayoutInflater mInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            layout = (RelativeLayout)mInflater.inflate(R.layout.button_preference, parent, false);
            //FIND OUR BUTTON IN LAYOUT
            Button button = (Button) layout.findViewById(android.R.id.title);
            if(button!=null){
            Log.e(TAG, "button found");
            button.setOnClickListener(new OnClickListener() {                   
                @Override
                public void onClick(View v) {                       
                    if(buttonListener!=null){                           
                        buttonListener.onCustomClick(); //INVOKE OUR EVENT!
                    }
                }
            });
            }            
       }
       catch(Exception e)
       {
           Log.e(TAG, "Error creating info preference", e);
       }        
       return layout;        
   }    
}

如何使用它?简单的!

public class WallpaperSettings extends PreferenceActivity {

protected void onCreate(Bundle savedInstanceState) {        
    super.onCreate(savedInstanceState);
    addPreferencesFromResource(R.xml.prefs);    

    ButtonPreference defaultSettingsButton = (ButtonPreference) findPreference(EngineCore.pref+"defaultSettings");      
    defaultSettingsButton.setButtonListener(new ButtonListener() {          
        @Override
        public void onCustomClick() {
            Gdx.app.log("ButtonListener", "onCustomClick");             
        }
    });
}   
}

我希望它对其他人有帮助。

I had the same issue with custom button. I tried the solution provided by @jeanh and it works. But my button was not pressed, only area around it was highlighted. Moreover, what if you have a few buttons? Obviously, that this solution won't work. So, I decided to dig deeper and my solution was below:

xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/widget_frame" android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="15dp"
android:paddingTop="5dp"
android:paddingRight="10dp"
android:paddingBottom="5dp"    
>
<!-- define my button -->
<Button android:id="@android:id/title"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textSize="17sp"
        android:typeface="sans"
        android:textStyle="bold"
        android:textColor="#000000"
></Button>    

</RelativeLayout>

Java class:

public class ButtonPreference extends Preference {

    private final String TAG = getClass().getName();

    public interface ButtonListener {      
        public void onCustomClick();
    }

    public ButtonListener buttonListener;

    public void setButtonListener(ButtonListener buttonListener){
        this.buttonListener = buttonListener;
    }

    public ButtonPreference(Context context, AttributeSet attrs) {
        super(context, attrs);       
    }

    public ButtonPreference(Context context, AttributeSet attrs, int  defStyle) {
        super(context, attrs, defStyle);        
    }

    @Override
    protected View onCreateView(ViewGroup parent){

        RelativeLayout layout =  null;

        try {
            LayoutInflater mInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            layout = (RelativeLayout)mInflater.inflate(R.layout.button_preference, parent, false);
            //FIND OUR BUTTON IN LAYOUT
            Button button = (Button) layout.findViewById(android.R.id.title);
            if(button!=null){
            Log.e(TAG, "button found");
            button.setOnClickListener(new OnClickListener() {                   
                @Override
                public void onClick(View v) {                       
                    if(buttonListener!=null){                           
                        buttonListener.onCustomClick(); //INVOKE OUR EVENT!
                    }
                }
            });
            }            
       }
       catch(Exception e)
       {
           Log.e(TAG, "Error creating info preference", e);
       }        
       return layout;        
   }    
}

HOW TO USE IT? Simple!

public class WallpaperSettings extends PreferenceActivity {

protected void onCreate(Bundle savedInstanceState) {        
    super.onCreate(savedInstanceState);
    addPreferencesFromResource(R.xml.prefs);    

    ButtonPreference defaultSettingsButton = (ButtonPreference) findPreference(EngineCore.pref+"defaultSettings");      
    defaultSettingsButton.setButtonListener(new ButtonListener() {          
        @Override
        public void onCustomClick() {
            Gdx.app.log("ButtonListener", "onCustomClick");             
        }
    });
}   
}

I hope it helps someone else.

失与倦" 2024-12-18 15:44:13

我找到了解决方案!
就我而言,我将 DialogPreference 扩展到我的自定义 Dialog 类,

public class SvDialogPreference extends DialogPreference

我也感到困惑,因为在 PreferenceFragment 中, onPreferenceChange 从未起作用。

SvDialogPreference pref= (SvDialogPreference) findPreference("mainKey");
if( pref != null ) {
pref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
// Never execute !
}}

为了解决这个问题。我在 onDialogClosed 中调用了“super.callChangeListener”。

public class SvDialogPreference extends DialogPreference{
....
@Override
protected void onDialogClosed(boolean positiveResult) {

double InputValue = Double.parseDouble(KEY.getText().toString());
     super.callChangeListener(InputValue);
     super.onDialogClosed(positiveResult);
}

现在,onPreferenceChange 工作得很好!

I found solution !
In my case, I extends DialogPreference to my custom Dialog class,

public class SvDialogPreference extends DialogPreference

I also confuse, because in PreferenceFragment, onPreferenceChange never worked.

SvDialogPreference pref= (SvDialogPreference) findPreference("mainKey");
if( pref != null ) {
pref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
// Never execute !
}}

To resolve this. I called "super.callChangeListener" in onDialogClosed.

public class SvDialogPreference extends DialogPreference{
....
@Override
protected void onDialogClosed(boolean positiveResult) {

double InputValue = Double.parseDouble(KEY.getText().toString());
     super.callChangeListener(InputValue);
     super.onDialogClosed(positiveResult);
}

Now, onPreferenceChange worked fine !

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文