【问题标题】:setOnPreferenceChangeListener not working for custom checkboxpreferencesetOnPreferenceChangeListener 不适用于自定义复选框首选项
【发布时间】:2018-02-14 17:58:10
【问题描述】:

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

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 没有效果并且没有被存储。我尝试为调用 super 的实现覆盖一些 android 方法,然后打印一行以查看调用了什么。值得注意的是 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 和构造函数;我两个都叫超级。有什么想法吗?

【问题讨论】:

  • 您希望在选中复选框时更新首选项?你不需要在你的复选框上设置一个 onCheckChangedListener 吗?

标签: android preferences


【解决方案1】:

在 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

【讨论】:

    【解决方案2】:

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

    我希望它可以帮助别人。

    【讨论】:

      【解决方案3】:

      我找到了解决方案! 就我而言,我将 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 工作正常!

      【讨论】:

        猜你喜欢
        • 2019-07-22
        • 2011-04-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多