1. 程式人生 > >SwitchPreference響應點選事件

SwitchPreference響應點選事件

問題背景

需要響應SwitchPreference(CheckBoxPreference的升級版)的點選事件,但是在點選之後,checkbox先變化,然後再彈出我們需要的流程。這個顯然跟使用者體驗有出入了。
使用者一般假設,當我們設定完畢之後,這個checkbox狀態才會改變。

初始方案

在onPreferenceClick裡面對點選的Preference的key進行判斷,並進入我們彈出的新流程。這個會產生上面所說的問題,即checkbox會在我們新流程彈出之前就改變了。

解決流程

檢視Preference程式碼

因為所有的基本流程都是在Preference裡面定義好了,不同的Preference只是在UI或者獨有的狀態改變上自定義而已。所以Preference流程是關鍵,重要函式是performClick。

//簡化如下
public void performClick(){
    onClick();
    if(mOnClickListener != null && mOnClickListener.onPreferenceClick(this)){return;}
}

注意呼叫順序,先呼叫onClick,後呼叫onPreferenceClick函式。
這個onClick函式類似一個佔位函數了。我們看看SwitchPreference裡面該函式的定義。

檢視SwitchPreference原始碼

其實需要檢視的是它的基類TwoStatePreference。

//TwoStatePreference.java
protected void onClick(){
    super.onClick();
    final boolean newValue = !isChecked();
    if(callChangedListener(newValue)){
        setChecked(newValue);
    }
}

其實這個callChangedListener函式是在Preference裡面定義的,如下:

protected boolean callChangeListener(Object newValue) {
    return
mOnChangeListener == null ? true : mOnChangeListener.onPreferenceChange(this, newValue); }

解決方法

所以,可以知道實際上先呼叫onPreferenceChange函式,然後才設定checkbox的狀態,最後才會呼叫onPreferenceClick。
所以如果要在checkbox狀態改變之前進行操作,必須在onPreferenceChange函式中進行處理。如果返回false,那麼就不會改變這個checkbox的狀態啦。