setOnPreferenceChangeListener不适用于自定义checkboxpreference

时间:2011-10-25 21:49:47

标签: android preferences

我对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);
}

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

            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和构造函数;我两个都叫超级。有什么想法吗?

3 个答案:

答案 0 :(得分:4)

在CheckBox上设置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" />

此主题的更多信息:Clickable rows on custom ArrayAdapter

答案 1 :(得分:0)

我在自定义按钮上遇到了同样的问题。我尝试了@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");             
        }
    });
}   
}

我希望它可以帮助别人。

答案 2 :(得分:0)

我找到了解决方案! 在我的例子中,我将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工作正常!