• 自定义控件,开关左右滑动


    自定义控件一般的思路都是根据图片,自己绘制相应的控件

    布局文件

     1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     2     xmlns:tools="http://schemas.android.com/tools"
     3     android:layout_width="match_parent"
     4     android:layout_height="match_parent"
     5     android:paddingBottom="@dimen/activity_vertical_margin"
     6     android:paddingLeft="@dimen/activity_horizontal_margin"
     7     android:paddingRight="@dimen/activity_horizontal_margin"
     8     android:paddingTop="@dimen/activity_vertical_margin"
     9     tools:context=".MainActivity" >
    10 
    11     <com.itheima27.slidebutton.view.SlideButton
    12         android:id="@+id/slidebutton"
    13         android:layout_width="wrap_content"
    14         android:layout_height="wrap_content"
    15         android:layout_centerInParent="true" />
    16 
    17 </RelativeLayout>
      1 import com.itheima27.slidebutton.R;
      2 import com.itheima27.slidebutton.interf.OnToggleStateChangedListener;
      3 
      4 import android.content.Context;
      5 import android.graphics.Bitmap;
      6 import android.graphics.BitmapFactory;
      7 import android.graphics.Canvas;
      8 import android.util.AttributeSet;
      9 import android.view.MotionEvent;
     10 import android.view.View;
     11 
     12 public class SlideButton extends View {
     13 
     14     private Bitmap switchBG;    // 滑动开关的背景
     15     private Bitmap slideButtonBG; // 滑动块的背景
     16     private boolean currentState = false;    // 开关当前的状态, 默认为: 关闭
     17     private int currentX;    // x轴的偏移量
     18     private boolean isSliding = false;        // 是否正在滑动中
     19     private OnToggleStateChangedListener mListener;
     20 
     21     public SlideButton(Context context, AttributeSet attrs) {
     22         super(context, attrs);
     23         
     24         initBitmap();
     25     }
     26 
     27     /**
     28      * 当测量当前控件的宽高时回调
     29      */
     30     @Override
     31     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
     32         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
     33         
     34         // 设置开关的宽和高
     35         setMeasuredDimension(switchBG.getWidth(), switchBG.getHeight());
     36     }
     37 
     38     /**
     39      * 绘制当前控件的方法
     40      */
     41     @Override
     42     protected void onDraw(Canvas canvas) {
     43         
     44         // 1. 把滑动开关的背景画到画布上
     45         canvas.drawBitmap(switchBG, 0, 0, null);        // 把背景平铺到控件上
     46         
     47         // 2. 绘制滑动块显示的位置, 开或者关
     48         
     49         if(isSliding) {
     50             int left = currentX - (slideButtonBG.getWidth() / 2);
     51             if(left < 0) {
     52                 left = 0;
     53             } else if(left > switchBG.getWidth() - slideButtonBG.getWidth()) {
     54                 left = switchBG.getWidth() - slideButtonBG.getWidth();
     55             }
     56             
     57             canvas.drawBitmap(slideButtonBG, left, 0, null);
     58         } else {
     59             if(currentState) {    // 绘制开关为开的状态
     60                 canvas.drawBitmap(slideButtonBG, switchBG.getWidth() - slideButtonBG.getWidth(), 0, null);
     61             } else {    // 绘制开关为关的状态
     62                 canvas.drawBitmap(slideButtonBG, 0, 0, null);
     63             }
     64         }
     65         super.onDraw(canvas);
     66     }
     67 
     68     /**
     69      * 当产生触摸时间时回调此方法
     70      */
     71     @Override
     72     public boolean onTouchEvent(MotionEvent event) {
     73         switch (event.getAction()) {
     74         case MotionEvent.ACTION_DOWN: // 按下
     75             currentX = (int) event.getX();
     76             isSliding  = true;
     77             break;
     78         case MotionEvent.ACTION_MOVE: // 移动
     79             currentX = (int) event.getX();
     80             break;
     81         case MotionEvent.ACTION_UP: // 抬起
     82             isSliding = false;
     83             
     84             // 判断当前滑动块, 偏向于哪一边, 如果滑动块的中心点小于背景的中心点, 设置为关闭状态
     85             
     86             int bgCenter = switchBG.getWidth() / 2;
     87             
     88             boolean state = currentX > bgCenter;        // 改变后的状态
     89             
     90             // 调用用户的监听事件
     91             if(state != currentState && mListener != null) {
     92                 mListener.onToggleStateChanged(state);
     93             }
     94 
     95             currentState = state;
     96             break;
     97         default:
     98             break;
     99         }
    100 
    101         invalidate();        // 刷新当前控件, 会引起onDraw方法的调用
    102         return true;
    103     }
    104 
    105     /**
    106      * 初始化图片
    107      */
    108     private void initBitmap() {
    109         slideButtonBG = BitmapFactory.decodeResource(getResources(), R.drawable.slide_button_background);
    110         switchBG = BitmapFactory.decodeResource(getResources(), R.drawable.switch_background);
    111     }
    112 
    113     /**
    114      * 设置开关的状态
    115      * @param b
    116      */
    117     public void setToggleState(boolean b) {
    118         currentState = b;
    119     }
    120 
    121     /**
    122      * 设置开关状态改变的监听事件
    123      * @param listener
    124      */
    125     public void setOnToggleStateChangedListener(OnToggleStateChangedListener listener) {
    126         this.mListener = listener;
    127     }
    128 }
  • 相关阅读:
    浅谈.NET和JAVA的跨平台
    ADO.NET获取TIPTOP存储过程的返回值
    Hide DataGrid Columns via HeaderText
    笑话一则:开车的最高境界
    [推薦]面试时最常问的15问题
    美国小学生守则 VS 中国小学生守则
    Embedded UserControls: Revisited
    SOA认识存误区 详解SOA企业部署的六大关键要素
    Java、.NET,为什么不合二为一?
    [轉]informix语句祥解
  • 原文地址:https://www.cnblogs.com/friends-wf/p/4539132.html
Copyright © 2020-2023  润新知