Android API中有自带的ToggleButton控件,然而这个控件看起来并不是那么美观,所以我们可以选择自定义我们的控件来实现该效果。

实现效果:


布局文件main.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="match_parent"    android:background="@drawable/blue_striped_bg"    android:orientation="vertical" >    <RelativeLayout        android:id="@+id/relativeLayout1"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_marginTop="15dip"        android:padding="5dip" >        <TextView             android:id="@+id/textView"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="自定义可滑动ToggleButton实例介绍"            android:layout_centerHorizontal="true"/>        <Button            android:id="@+id/ringagain"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_centerHorizontal="true"            android:background="@drawable/clock_list"            android:clickable="false"            android:gravity="center_vertical"            android:padding="10dip"            android:text="开"            android:textColor="@android:color/black"            android:textSize="18sp"             android:layout_below="@id/textView"            android:layout_marginTop="10dp"            />        <com.cn.slipbutton.SlipButton            android:id="@+id/splitbutton"            android:layout_width="100dip"            android:layout_height="40dip"            android:layout_alignRight="@id/ringagain"            android:layout_alignTop="@id/ringagain"            android:layout_marginTop="10dip" />    </RelativeLayout></LinearLayout>

SlipButtonActivity:

package com.cn.slipbutton;import android.app.Activity;import android.os.Bundle;import android.widget.Button;import com.cn.slipbutton.SlipButton.OnChangedListener;public class SlipButtonActivity extends Activity {private SlipButton sb = null;private Button btn = null;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);/** * 初始化控件 */sb = (SlipButton) findViewById(R.id.splitbutton);btn = (Button) findViewById(R.id.ringagain);sb.setCheck(true);/** * 设置监听 */sb.SetOnChangedListener(new OnChangedListener() {public void OnChanged(boolean CheckState) {btn.setText(CheckState ? "开" : "关");}});}}

自定义ToggleButton(取名为SlipButton):

package com.cn.slipbutton;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;public class SlipButton extends View implements OnTouchListener {private boolean NowChoose = false;// 记录当前按钮是否打开,true为打开,false为关闭private boolean isChecked;private boolean OnSlip = false;// 记录用户是否在滑动的变量private float DownX, NowX;// 按下时的x,当前的xprivate Rect Btn_On, Btn_Off;// 打开和关闭状态下,游标的Rect .private boolean isChgLsnOn = false;private OnChangedListener ChgLsn;private Bitmap bg_on, bg_off, slip_btn;public SlipButton(Context context) {super(context);init();}public SlipButton(Context context, AttributeSet attrs) {super(context, attrs);init();}public SlipButton(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);init();}private void init() {// 初始化bg_on = BitmapFactory.decodeResource(getResources(),R.drawable.split_left_1);bg_off = BitmapFactory.decodeResource(getResources(),R.drawable.split_right_1);slip_btn = BitmapFactory.decodeResource(getResources(),R.drawable.split_1);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}@Overrideprotected void onDraw(Canvas canvas) {// 绘图函数super.onDraw(canvas);Matrix matrix = new Matrix();Paint paint = new Paint();float x;if (NowX < (bg_on.getWidth() / 2))// 滑动到前半段与后半段的背景不同,在此做判断{x = NowX - slip_btn.getWidth() / 2;canvas.drawBitmap(bg_off, matrix, paint);// 画出关闭时的背景}else {x = bg_on.getWidth() - slip_btn.getWidth() / 2;canvas.drawBitmap(bg_on, matrix, paint);// 画出打开时的背景}if (OnSlip)// 是否是在滑动状态,{if (NowX >= bg_on.getWidth())// 是否划出指定范围,不能让游标跑到外头,必须做这个判断x = bg_on.getWidth() - slip_btn.getWidth() / 2;// 减去游标1/2的长度...else if (NowX < 0) {x = 0;} else {x = NowX - slip_btn.getWidth() / 2;}} else {// 非滑动状态if (NowChoose)// 根据现在的开关状态设置画游标的位置{x = Btn_Off.left;canvas.drawBitmap(bg_on, matrix, paint);// 初始状态为true时应该画出打开状态图片} elsex = Btn_On.left;}if (isChecked) {canvas.drawBitmap(bg_on, matrix, paint);x = Btn_Off.left;isChecked = !isChecked;}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) {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_CANCEL: // 移到控件外部OnSlip = false;boolean choose = NowChoose;if (NowX >= (bg_on.getWidth() / 2)) {NowX = bg_on.getWidth() - slip_btn.getWidth() / 2;NowChoose = true;} else {NowX = NowX - slip_btn.getWidth() / 2;NowChoose = false;}if (isChgLsnOn && (choose != NowChoose)) // 如果设置了监听器,就调用其方法..ChgLsn.OnChanged(NowChoose);break;case MotionEvent.ACTION_UP:// 松开OnSlip = false;boolean LastChoose = NowChoose;if (event.getX() >= (bg_on.getWidth() / 2)) {NowX = bg_on.getWidth() - slip_btn.getWidth() / 2;NowChoose = true;}else {NowX = NowX - slip_btn.getWidth() / 2;NowChoose = false;}if (isChgLsnOn && (LastChoose != NowChoose)) // 如果设置了监听器,就调用其方法..ChgLsn.OnChanged(NowChoose);break;default:}invalidate();// 重画控件return true;}public void SetOnChangedListener(OnChangedListener l) {// 设置监听器,当状态修改的时候isChgLsnOn = true;ChgLsn = l;}public interface OnChangedListener {abstract void OnChanged(boolean CheckState);}public void setCheck(boolean isChecked) {this.isChecked = isChecked;NowChoose = isChecked;}}



点击下载源码



更多相关文章

  1. 奇葩属性:layout_weight 的解释及使用
  2. Android网络状态实时监听器
  3. Android(安卓)Touch 事件的分发和消费机制
  4. Android开发 常用控件罕见特殊属性集锦
  5. android 让ImageView的图片全屏填充
  6. Android(安卓)调用相册 拍照 实现系统控件缩放 切割图片
  7. Android使用控件ImageView加载图片的方法
  8. 实现ScrollView的嵌套
  9. Spinner的详解

随机推荐

  1. Android体系结构——为什么选择MVVM而不
  2. android获取自定义控件位置坐标,屏幕尺寸,
  3. Android使用正则表达式验证手机号
  4. (4.2.32.2)android热修复之ClassLoader方式
  5. Android实现双击TitleBar回顶部的功能示
  6. CheckBox in ListView
  7. Dialogplus——简单的Android(安卓)dialo
  8. Android添加(创建)、删除及判断是否存在
  9. 详解Android使GridView横向水平滚动的实
  10. emoji表情在web html上显示