在很多时候我们看到在iphone手机应用中都有滑动开启和关闭这个功能,在android40以下的版本中且没有这个功能,但是android手机在使用的多是4.0以下的系统,所以为了满足需求,我们自己设计自定的滑动开启和关闭按钮。
第一步:创建一个打开关闭的状态接口函数OnChangedListener主要创建一个打开关闭状态的抽象方法OnChanged(boolean CheckState),本接口主要是用于空间跟activity之间的状态回调,代码如下:
- public interface OnChangedListener {
- abstract void OnChanged(boolean CheckState);
- }
第二步:创建SlipButton类继承View类(基本上android的空间都是继承这个类的,所以如果我们想自己设计出好看或者有特别用途的空间都可以继承这个类然后根据需求设计和实现重写相关方法)实现OnTouchListener接口实现手势触控和滑动的控制,本类的实现在代码中有详细的描述,代码如下:
- import android.content.Context;
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import android.graphics.Canvas;
- import android.graphics.Matrix;
- import android.graphics.Paint;
- import android.graphics.Rect;
- import android.util.AttributeSet;
- import android.view.MotionEvent;
- import android.view.View;
- import android.view.View.OnTouchListener;
- import com.example.slidebutton.R;
- public class SlipButton extends View implements OnTouchListener {
- private boolean NowChoose = false;// 记录当前按钮是否打开,true为打,flase为关
- private boolean OnSlip = false;// 记录用户是否在滑动的变量
- private float DownX, NowX;// 按下时的x,当前的x,
- private Rect Btn_On, Btn_Off;// 打开和关闭状态下,游标的Rect
- private boolean isChgLsnOn = false;
- private OnChangedListener ChgLsn;
- private Bitmap bg_on, bg_off, slip_btn;
- //此构造函数在直接new控件时调用
- public SlipButton(Context context) {
- super(context);
- // TODO Auto-generated constructor stub
- init();
- }
- public boolean isChecked(){
- return NowChoose;
- }
- public void setChecked(boolean check){
- NowChoose = check;
- invalidate();
- }
- //此构造函数在xml中使用控件时调用
- public SlipButton(Context context, AttributeSet attrs) {
- super(context, attrs);
- // TODO Auto-generated constructor stub
- init();
- }
- private void init() {// 初始资源
- // 载入图片资源
- bg_on = BitmapFactory.decodeResource(getResources(),
- R.drawable.images_on);
- bg_off = BitmapFactory.decodeResource(getResources(),
- R.drawable.images_off);
- slip_btn = BitmapFactory.decodeResource(getResources(),
- R.drawable.split_button);
- // 获得�?��的Rect数据
- Btn_On = new Rect(0, 0, slip_btn.getWidth(), slip_btn.getHeight());
- Btn_Off = new Rect(bg_off.getWidth() - slip_btn.getWidth(), 0,
- bg_off.getWidth(), slip_btn.getHeight());
- setOnTouchListener(this);// 设置触控监听,也可以直接复写OnTouchEvent
- }
- protected void onDraw(Canvas canvas) {// 绘图函数
- // TODO Auto-generated method stub
- super.onDraw(canvas);
- Matrix matrix = new Matrix();
- Paint paint = new Paint();
- float x;
- {
- if ((NowX < (bg_on.getWidth() / 2))&&!NowChoose)// 滑动到前半段与后半段的背景时在此做判是否关闭或打开
- {
- canvas.drawBitmap(bg_off, matrix, paint);// 画出关闭时的背景
- }
- else{
- canvas.drawBitmap(bg_on, matrix, paint);// 画出打开时的背景
- }
- if (OnSlip)// 是否是在滑动状
- {
- if (NowX >= bg_on.getWidth())// 是否划出指定范围,不能让游标跑到绘制控件范围外?必须做这个判?
- x = bg_on.getWidth() - slip_btn.getWidth() / 2;// 减去游标1/2的长度
- else
- x = NowX - slip_btn.getWidth() / 2;
- } else {// 非滑动状
- if (NowChoose)// 根据现在的开关状态设置画游标的位
- x = Btn_Off.left;
- else
- x = Btn_On.left;
- }
- if (x < 0)// 对游标位置进行异常判
- x = 0;
- else if (x > bg_on.getWidth() - slip_btn.getWidth())
- x = bg_on.getWidth() - slip_btn.getWidth();
- canvas.drawBitmap(slip_btn, x, 0, paint);// 画出游标.
- }
- }
- public boolean onTouch(View v, MotionEvent event) {
- // TODO Auto-generated method stub
- switch (event.getAction())// 根据动作来执行代
- {
- case MotionEvent.ACTION_MOVE:// 滑动
- NowX = event.getX();
- break;
- case MotionEvent.ACTION_DOWN:// 按下
- if (event.getX() > bg_on.getWidth()
- || event.getY() > bg_on.getHeight())
- return false;
- OnSlip = true;
- DownX = event.getX();
- NowX = DownX;
- break;
- case MotionEvent.ACTION_UP:// 松开
- OnSlip = false;
- boolean LastChoose = NowChoose;
- if (event.getX() >= (bg_on.getWidth() / 2))
- NowChoose = true;
- else
- NowChoose = false;
- if (isChgLsnOn && (LastChoose != NowChoose))// 如果设置了监听器,就调用其方法..
- ChgLsn.OnChanged(NowChoose);
- break;
- default:
- }
- invalidate();// 重画控件
- return true;
- }
- public void SetOnChangedListener(OnChangedListener l) {// 设置监听?当状态修改的时?
- isChgLsnOn = true;
- ChgLsn = l;
- }
第三步:设计xml文件(控件的使用也可以直接在activity中直接实例化的如:SlipButton mSlipButton=new SlipButton(this)),在xml中使用如下:
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent" >
- <RelativeLayout
- android:id="@+id/setlayout"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:background="@drawable/ic_preference_one_normal"
- android:gravity="center" >
- <TextView
- android:id="@+id/d_name"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentLeft="true"
- android:gravity="center_vertical"
- android:paddingBottom="10dip"
- android:paddingTop="10dip"
- android:singleLine="true"
- android:text="免打扰"
- android:textColor="#000000"
- />
- <!--使用SlipButton的方法这里必须是类的包名加.类名 -->
- <com.example.widget.SlipButton
- android:id="@+id/on"
- android:layout_width="60dip"
- android:layout_height="25dip"
- android:layout_alignParentRight="true"
- android:layout_marginBottom="8dip"
- android:layout_marginTop="8dip"
- />
- </RelativeLayout>
- </RelativeLayout>
第四步:编写MainActivity实现OnChangedListener接口,以便于监听打开和关闭时需要处理的事情。代码如下:
- import android.app.Activity;
- import android.os.Bundle;
- import android.widget.Toast;
- import com.example.widget.OnChangedListener;
- import com.example.widget.SlipButton;
- public class MainActivity extends Activity implements OnChangedListener {
- private SlipButton mSlipButton;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- mSlipButton = (SlipButton) this.findViewById(R.id.on);
- mSlipButton.SetOnChangedListener(this);//设置事件监听
- }
- //这里为开或者关时自己所需要做的动作或实现的内容处理
- public void OnChanged(boolean CheckState) {
- if (CheckState) {
- Toast.makeText(this, "打开了", Toast.LENGTH_LONG).show();
- } else {
- Toast.makeText(this, "关闭了", Toast.LENGTH_LONG).show();
- }
- }
- }