Android [Android5.X.X]解除SwitchPreference与Preference的绑定事件

需求描述

默认情况,Android的两个控件SwitchPreference和CheckBoxPreference的事件处理是和Preference整个区域的事件绑定在一起的,然而,有时需要将其事件分开处理,即点击Preference整个区域时,不会改变SwitchPreference状态,仅当点击SwitchPreference时才去处理SwitchPreference的开关状态,如点击Preference整个区域弹出一个对话框或跳转到某个界面,点击SwitchPreference时仅是改变开关状态,不弹出对话框或不跳转.这样的需求该如何实现呢?下面将会列举几个常用实现方法:

SwitchPreference和CheckBoxPreference都是继承自TwoStatePreference,下面仅以SwitchPreference介绍,CheckBoxPreference的实现方式是一样的.

【声明】欢迎转载,但请保留文章原始出处:http://blog.csdn.net/yelangjueqi/article/details/46754711

一 继承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

<?xml version="1.0" encoding="utf-8"?>

<Switch xmlns:android="http://schemas.android.com/apk/res/android"

android:id="@+id/prefrence_switch_id"

android:layout_width="fill_parent"

android:layout_height="fill_parent" >

</Switch>

上面布局中的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

<?xml version="1.0" encoding="utf-8"?>

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >

<com.wtk.gesture.modules.GestureSwitchPreference

android:key="GestureSwitchPreference"

android:summary="概要"

android:title="标题" />

</PreferenceScreen>

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

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

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" >

<RadioGroup

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" >

<RadioButton

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" />

<ImageView

android:layout_width="match_parent"

android:layout_height="match_parent"

android:contentDescription="@null"

android:scaleType="centerCrop"

android:src="@drawable/zzz_gesture_tab_space" />

<RadioButton

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" />

</RadioGroup>

<TextView

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" />

</LinearLayout>

3.效果图:

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-08 19:38:09

Android [Android5.X.X]解除SwitchPreference与Preference的绑定事件的相关文章

Android studio 百度地图开发(6)Marker绑定事件、计算两点距离

email:[email protected] 开发环境:win7 64位,Android Studio,请注意是Android Studio,使用的导航SDK版本:3.1.0. 百度地图应用(1):Android studio 百度地图开发(1)配置工程.显示地图 百度地图应用(2):Android studio 百度地图开发(2)地图定位 百度地图应用(3):Android studio 百度地图开发(3)地图导航 百度地图应用(4):Android studio 百度地图开发(4)触摸选点

Android自定义工具类获取按钮并绑定事件(利用暴力反射和注解)

Android中为按钮绑定事件的有几种常见方式,你可以在布局文件中为按钮设置id,然后在MainActivity中通过findViewById方法获取按钮对象实例,再通过setOnClickListener为按钮绑定事件,如下所示: //1.获取控件 btn = (Button)findViewById(R.id.button1); //2.绑定事件 btn.setOnClickListener(new OnClickListener() { @Override public void onCl

基础知识:设置Android按钮与绑定事件

在前面 向应用添加一个新的Activity,我们使用了按钮,点击按钮进入一个新的 Activity.这里简单总结一下按钮在 Android 的使用. 设计一个按钮很简单,在 IDE 里一般都有图形界面,你也可以自己在 xml 里自己编写,比如:澳门赌场玩法 view source print? 1 <Button 2     android:id="@+id/nowamagicbtn" 3     android:layout_width="wrap_content&q

android通知栏Notification点击,取消,清除响应事件

主要是检测android通知栏的三种状态的响应事件 这次在实现推送需求的时候,要用到android通知栏Notification点击后进入消息页面,因为要实现一个保存推送用户名字的功能,我在点击后处理了这个功能,但是测试发现我点击删除或者滑动清除后这个功能并没有执行,所以才意识到要处理删除和滑动清除的事件: 首先实现一个BroadcastReceiver public class NotificationBroadcastReceiver extends BroadcastReceiver {

Android自动化测试初探(五): 再述模拟键盘鼠标事件(adb shell 实现) .

http://blog.csdn.net/roger_ge/article/details/5552740 转自csdn,实现模拟鼠标键盘系列 上一篇博文中讲述了通过Socket编程从外部向Emulator发送键盘鼠标模拟事件,貌似实现细节有点复杂.其实Android还有一种更简单的模拟键盘鼠标事件的方法,那就是通过使用adb shell 命令. 1.     发送键盘事件: 命令格式1:adb shell input keyevent "value" 其中value以及对应的key

基于Android系统应用层与框架层剖析View点击事件

基于Android操作系统的框架层和应用层,介绍了View的绘制.触摸事件的传递流程,分析了View与用户交互时被回调的相关框架层代码和应用层代码,研究了Android应用中事件处理的相关重要机制.通过具体代码详细剖析了在Android系统下用户和View交互过程中折射出的回调机制,回调方法在系统框架的详细执行过程,以及基于回调机制的经典事件处理模型. 1 引言 Android是一种基于Linux的自由及开放源代码的操作系统,目前基于Android平台的应用日趋广泛.Android应用程序大多基

Android [Android5.X.X]关于Android L的Service启动问题

一 问题描述 Android L[Android5.X.X] 版本通过Intent隐式启动service时将会报出以下错误: AndroidRuntime(  792): java.lang.IllegalArgumentException: Service Intent must be explicit [声明]欢迎转载,但请保留文章原始出处:http://blog.csdn.net/yelangjueqi/article/details/46754581 详细信息: 01-02 07:52:

[Android]Android5.0实现静默接听电话功能

原因: android曾经能够通过AIDL进行静默接听.可是5.0以后就被谷歌给屏蔽了.这时候我们仅仅能通过其它方式实现了. 解决方式: try { Runtime.getRuntime().exec("input keyevent " + Integer.toString(KeyEvent.KEYCODE_HEADSETHOOK)); } catch (IOException e) { // Runtime.exec(String) had an I/O problem, try t

关于mac android studio 与svn 解除关联后 无法再次share (Subversion) 的解决办法

Android studio 把工程share 到 svn 上面,可是一不小心忘了 ignore files 的设置,结果没办法,把svn 上的删掉再重新share 一次,先接触本地代码与svn 的关联,两种方法,(1)android sutio 的设置按钮,找到version control 大类,用鼠标点击这一栏,旁变白色区域,有个project 最右边对应Subversion,白色区域左下角有个减号,点击也可以.(2)从android 切换到project目录,在.idea 文件夹下有个v