Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> [Android L]解除SwitchPreference與Preference的綁定事件

[Android L]解除SwitchPreference與Preference的綁定事件

編輯:關於Android編程


需求描述

默認情況,Android的兩個控件SwitchPreference和CheckBoxPreference的事件處理是和Preference整個區域的事件綁定在一起的,然而,有時需要將其事件分開處理,即點擊Preference整個區域時,不會改變SwitchPreference狀態,僅當點擊SwitchPreference時才去處理SwitchPreference的開關狀態,如點擊Preference整個區域彈出一個對話框或跳轉到某個界面,點擊SwitchPreference時僅是改變開關狀態,不彈出對話框或不跳轉.這樣的需求該如何實現呢?下面將會列舉幾個常用實現方法:

SwitchPreference和CheckBoxPreference都是繼承自TwoStatePreference,下面僅以SwitchPreference介紹,CheckBoxPreference的實現方式是一樣的.

 

 

一 繼承SwitchPreference重新復寫一個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());
}

//下面這段代碼,在Android L版本(5.0)之前是不需要的,在Android L版本上必須要有,否則switch獲取不到點擊事件
//此處廢了我不少時間查找原因:從KK移植到L上面就不起作用了.因此L版本上面必須要有下面這段
@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;
}
}

不足之處:如果在Android L上面運行,僅適用於源碼環境,因為com.android.internal.R.id.switchWidget是私有的


二 通過switch控件實現

 

調用Preference的setWidgetLayoutResource方法實現控件替換


1. Layout布局文件:smart_gesture_switch.xml

android:id=@+id/prefrence_switch_id
android:layout_width=fill_parent
android:layout_height=fill_parent >

 

上面布局中的Switch也可以替換成Checkbox or RadioButton

2. 引用smart_gesture_switch布局: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;
//通過調用setWidgetLayoutResource方法來更新preference的widgetLayout,即更新控件區域
setWidgetLayoutResource(R.layout.smart_gesture_switch);
}

public GestureSwitchPreference(Context context) {
super(context);
mContext = context;
//通過調用setWidgetLayoutResource方法來更新preference的widgetLayout,即更新控件區域
setWidgetLayoutResource(R.layout.smart_gesture_switch);
}

@Override
protected void onBindView(View view) {
mSwitch = (Switch) view.findViewById(R.id.prefrence_switch_id);
//view即是代表的preference整個區域,可以對該view進行事件監聽,也就是實現了preference整個區域的點擊事件
view.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
showToast(section-all);
//此處調用自定義的監聽器A方法,該監聽器A接口應由使用GestureSwitchPreference的類來實現,從而實現
//preference整個區域的點擊事件.注:監聽器A的定義可以參考OnRadioButtonCheckedListener接口的定義
}
});

//switch開關的點擊事件
if (mSwitch != null) {
mSwitch.setOnCheckedChangeListener(new OnCheckedChangeListener() {

@Override
public void onCheckedChanged(CompoundButton button, boolean checked) {
mChecked = checked;
showToast(only-switch-section);
//此處調用自定義的監聽器B方法,該監聽器B接口應由使用GestureSwitchPreference的類來實現,從而實現
//preference的switch點擊事件.注:監聽器B的定義可以參考OnRadioButtonCheckedListener接口的定義
}
});
}
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(mContext, info, 5000);
}
mToast.setText(info);
mToast.show();
}
}


3. 引用GestureSwitchPreference:smart_quick_gesture_settings.xml



android:key=GestureSwitchPreference
android:summary=概要
android:title=標題 />



 

4. 主界面: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. 效果圖:
點擊preference整個區域
\

點擊switch:

\




上述實現方式不足之處是:
A 代碼量比較大
B 需要主動維護switch開關的狀態,否則退出再重新進入時switch開關狀態依舊是原來狀態

三 擴展:完全自定義Preference布局


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(mContext, 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.效果圖:

\


\

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved