[Android L] unbind SwitchPreference from Preference
By default, the event processing of the SwitchPreference and CheckBoxPreference controls in Android is bound with the events in the entire region of the Preference. However, it is sometimes necessary to process the events separately, that is, the status of SwitchPreference is not changed when you click the entire region of Preference. The switch status of SwitchPreference is handled only when you click SwitchPreference. For example, you can click a dialog box in the entire region of Preference or jump to a page, when you click SwitchPreference, the switch status is changed. The dialog box is not displayed or the switch is not redirected. how can we implement such a requirement? The following describes several common implementation methods:
Both SwitchPreference and CheckBoxPreference are inherited from TwoStatePreference. The following describes SwitchPreference only. The implementation of CheckBoxPreference is the same.
1. inherit SwitchPreference and re-write a Preference
Import android. content. Context; Import android. preference. SwitchPreference; Import android. util. AttributeSet; Import android. util. Log; Import android. view. View; Import android. view. ViewGroup; Import android. widget. Switch;
Import com. wtk. gesture. utils. MyLogger;
Public class SmartSwitchPreference extends SwitchPreference { Private static final String CLASS_TAG = MyLogger. APP_TAG +/+ SmartSwitchPreference. class. getSimpleName ();
Public SmartSwitchPreference (Context context, AttributeSet attrs, int defStyle ){ Super (context, attrs, defStyle ); }
Public SmartSwitchPreference (Context context, AttributeSet attrs ){ Super (context, attrs ); }
Public SmartSwitchPreference (Context context ){ Super (context ); }
@ Override Protected void onClick (){ Log. d (CLASS_TAG, onClick ()); }
// The following code is not required before Android L (5.0). It must be available on Android L. Otherwise, the switch cannot obtain the click event. // I spent a lot of time searching for the cause: porting from KK to L does not work. Therefore, the following section must be included in the L version. @ Override Protected View onCreateView (ViewGroup parent ){ View view = super. onCreateView (parent ); Switch v = (Switch) view. findViewById (com. android. internal. R. id. switchWidget ); If (v! = Null ){ V. setClickable (true ); } Return view; } } |
Disadvantage: If you run on Android L, it is only applicable to the source code environment, because com. android. internal. R. id. switchWidget is private
Second, use the switch control to implement
Call the setWidgetLayoutResource method of Preference to replace the control.
1. Layout file: smart_gesture_switch.xml
Android: id = @ + id/prefrence_switch_id Android: layout_width = fill_parent Android: layout_height = fill_parent> |
The Switch in the preceding layout can also be replaced with Checkbox or RadioButton.
2. Reference smart_gesture_switch layout: GestureSwitchPreference. java
Import android. content. Context; Import android. preference. SwitchPreference; Import android. util. AttributeSet; Import android. view. View; Import android. widget. CompoundButton; Import android. widget. CompoundButton. OnCheckedChangeListener; Import android. widget. Switch; Import android. widget. Toast;
Import com. wtk. gesture. quick. R; Import com. wtk. gesture. utils. MyLogger;
Public class GestureSwitchPreference extends SwitchPreference { Private static final String CLASS_TAG = MyLogger. APP_TAG +/+ GestureSwitchPreference. class. getSimpleName ();
Private Switch mSwitch; Private boolean mChecked = false; Private Context mContext;
//////////////////////////////////////// ////// Custom Listenr Start // Private OnRadioButtonCheckedListener mOnRadioButtonCheckedListener; // // Public interface OnRadioButtonCheckedListener { // Public void OnRadioButtonChecked (boolean isScreenOffView ); //} // // Public void setOnRadioButtonCheckedListener (OnRadioButtonCheckedListener // Listener ){ // MOnRadioButtonCheckedListener = listener; //} // //////////////////////////////////////// ///// Custom Listenr End
Public GestureSwitchPreference (Context context, AttributeSet attrs, int defStyle ){ Super (context, attrs, defStyle ); MContext = context; }
Public GestureSwitchPreference (Context context, AttributeSet attrs ){ Super (context, attrs ); MContext = context; // Call the setWidgetLayoutResource method to update the widgetLayout of the preference, that is, update the control area. SetWidgetLayoutResource (R. layout. smart_gesture_switch ); }
Public GestureSwitchPreference (Context context ){ Super (context ); MContext = context; // Call the setWidgetLayoutResource method to update the widgetLayout of the preference, that is, update the control area. SetWidgetLayoutResource (R. layout. smart_gesture_switch ); }
@ Override Protected void onBindView (View view ){ MSwitch = (Switch) view. findViewById (R. id. prefrence_switch_id ); // View indicates the entire preference area. You can listen to the event of this view, that is, the Click Event of the entire preference area. View. setOnClickListener (new View. OnClickListener (){
@ Override Public void onClick (View v ){ // TODO Auto-generated method stub ShowToast (section-all ); // Call the custom listener A method here. The Listener A interface should be implemented by using the GestureSwitchPreference class. // Preference click events in the entire region. Note: For definitions of listener A, refer to the definition of OnRadioButtonCheckedListener interface. } });
// Switch Click Event If (mSwitch! = Null ){ MSwitch. setOnCheckedChangeListener (new OnCheckedChangeListener (){
@ Override Public void onCheckedChanged (CompoundButton button, boolean checked ){ MChecked = checked; ShowToast (only-switch-section ); // Call the custom listener B method. The Listener B interface should be implemented by using the GestureSwitchPreference class. // The switch Click Event of preference. Note: For definitions of listener B, refer to the definition of OnRadioButtonCheckedListener interface. } }); } SetChecked (mChecked ); Super. onBindView (view ); }
Public boolean isChecked (){ Return mChecked; }
Public void setChecked (boolean bChecked ){ MChecked = bChecked; If (mSwitch! = Null ){ MSwitch. setChecked (bChecked ); } }
Private void showToast (String info ){ Toast mToast = null; If (mToast = null ){ MToast = Toast. makeText (Message context, info, 5000 ); } MToast. setText (info ); MToast. show (); } } |
3. Reference GestureSwitchPreference: smart_quick_gesture_settings.xml
Android: key = GestureSwitchPreference
Android: summary = summary
Android: title = title/>
|
4. Main Interface: SmartQuickGestureSettings. java
Public class SmartQuickGestureSettings extends PreferenceActivity { Private static final String TAG = MyLogger. APP_TAG +/+ SmartQuickGestureSettings. class. getSimpleName ();
@ Override Protected void onCreate (Bundle savedInstanceState ){ Super. onCreate (savedInstanceState ); AddPreferencesFromResource (R. xml. smart_quick_gesture_settings ); } } |
5 .:
Click preference for the entire region
Click switch:
The shortcomings of the above implementation methods are:
A large amount of code
B needs to actively maintain the status of the switch. Otherwise, the switch status is still in the original status when it exits and enters the switch again.
Three extensions: Fully customized Preference Layout
1. SmartGesturePrefrence. java
Import android. content. Context; Import android. preference. Preference; Import android. util. AttributeSet; Import android. view. View; Import android. widget. RadioButton; Import android. widget. RadioGroup; Import android. widget. RadioGroup. OnCheckedChangeListener; Import android. widget. Toast;
Import com. wtk. gesture. quick. R; Import com. wtk. gesture. utils. MyLogger;
Public class SmartGesturePrefrence extends Preference { Private static final String CLASS_TAG = MyLogger. APP_TAG +/+ SmartGesturePrefrence. class. getSimpleName (); Public static boolean isScreenOffBtn = true; // default display gesture view Private Context mContext;
Private OnRadioButtonCheckedListener mOnRadioButtonCheckedListener;
Public interface OnRadioButtonCheckedListener { Public void OnRadioButtonChecked (boolean isScreenOffView ); }
Public void setOnRadioButtonCheckedListener (OnRadioButtonCheckedListener listener ){ MOnRadioButtonCheckedListener = listener; }
Public SmartGesturePrefrence (Context context ){ This (context, null ); }
Public SmartGesturePrefrence (Context context, AttributeSet attrs ){ This (context, attrs, 0 ); MContext = context; }
Public SmartGesturePrefrence (Context context, AttributeSet attrs, int defStyle ){ Super (context, attrs, defStyle ); MContext = context; SetLayoutResource (R. layout. gesture_preference_layout ); }
@ Override Protected void onBindView (final View view ){ Super. onBindView (view ); RadioGroup mRadioGroup = (RadioGroup) view. findViewById (R. id. radiogroup_gesture );
RadioButton mScreenOffButton = (RadioButton) view. findViewById (R. id. btn_screen_off ); RadioButton mPhoneCallingButton = (RadioButton) view. findViewById (R. id. btn_phone_calling );
If (isScreenOffBtn ){ MScreenOffButton. setChecked (true ); } Else { MPhoneCallingButton. setChecked (true ); }
MRadioGroup. setOnCheckedChangeListener (new OnCheckedChangeListener (){
@ Override Public void onCheckedChanged (RadioGroup group, int checkedId ){
Switch (checkedId ){ Case R. id. btn_screen_off: IsScreenOffBtn = true; If (mOnRadioButtonCheckedListener! = Null ){ MOnRadioButtonCheckedListener. OnRadioButtonChecked (true ); } ShowToast (screen_off ); Break;
Case R. id. btn_phone_calling: IsScreenOffBtn = false; If (mOnRadioButtonCheckedListener! = Null ){ MOnRadioButtonCheckedListener. OnRadioButtonChecked (false ); } ShowToast (phone_calling ); Break; } } }); }
Private void showToast (String info ){ Toast mToast = null; If (mToast = null ){ MToast = Toast. makeText (Message context, info, 5000 ); } MToast. setText (info ); MToast. show (); } } |
2. gesture_preference_layout.xml
Android: layout_width = match_parent Android: layout_height = wrap_content Android: gravity = center_vertical Android: minHeight = 20dp Android: orientation = vertical Android: paddingEnd =? Android: attr/scrollbarSize Android: paddingStart =? Android: attr/scrollbarSize> Android: id = @ + id/radiogroup_gesture Android: layout_width = wrap_content Android: layout_height = 52dip Android: layout_marginLeft = 0dip Android: layout_marginRight = 0dip Android: layout_marginTop = 6dip Android: background = @ android: color/black Android: gravity = center_vertical Android: orientation = horizontal> Android: id = @ + id/btn_screen_off Android: layout_width = wrap_content Android: layout_height = wrap_content Android: background = @ drawable/zzz_radio_selector Android: button = @ null Android: gravity = center Android: text = @ string/title_mode_idle Android: textSize = 16sp/> Android: layout_width = match_parent Android: layout_height = match_parent Android: contentDescription = @ null Android: scaleType = centerCrop Android: src = @ drawable/zzz_gesture_tab_space/> Android: id = @ + id/btn_phone_calling Android: layout_width = wrap_content Android: layout_height = wrap_content Android: background = @ drawable/zzz_radio_selector Android: button = @ null Android: gravity = center Android: text = @ string/title_mode_call Android: textSize = 16sp/> Android: id = @ + id/hint_info Android: layout_width = wrap_content Android: layout_height = wrap_content Android: layout_marginLeft = 6dip Android: layout_marginRight = 6dip Android: ellipsize = marquee Android: fadingEdge = horizontal Android: singleLine = true Android: text = @ string/gesture_operate_description Android: textAppearance =? Android: attr/textAppearanceSmall Android: visibility = gone/> |
3 .: