zoukankan      html  css  js  c++  java
  • 自定义控件:滑动开关按钮

     

     1 <RelativeLayout 
     2     xmlns:android="http://schemas.android.com/apk/res/android"
     3     xmlns:tools="http://schemas.android.com/tools"
     4     android:layout_width="match_parent"
     5     android:layout_height="match_parent" >
     6 
     7     <com.example.testdemo.MyToggleButton
     8         android:id="@+id/my_toggle_btn"
     9         android:layout_width="wrap_content"
    10         android:layout_height="wrap_content"
    11         android:layout_centerHorizontal="true"
    12         android:layout_centerVertical="true" />
    13 
    14 </RelativeLayout>
      1 package com.example.testdemo;
      2 
      3 import android.content.Context;
      4 import android.graphics.Bitmap;
      5 import android.graphics.BitmapFactory;
      6 import android.graphics.Canvas;
      7 import android.graphics.Paint;
      8 import android.util.AttributeSet;
      9 import android.view.MotionEvent;
     10 import android.view.View;
     11 import android.view.View.OnClickListener;
     12 
     13 public class MyToggleButton extends View implements OnClickListener {
     14 
     15     // 做为背景的图片
     16     private Bitmap backgroundBitmap;
     17     // 可以滑动的图片
     18     private Bitmap slideBtn;
     19     private Paint paint;
     20     // 滑动按钮的左边届
     21     private float slideBtn_left;
     22     // down 事件时的x值
     23     private int firstX;
     24     // touch 事件的上一个x值
     25     private int lastX;
     26     // 当前开关的状态 true 为开
     27     private boolean currState = false;
     28     // 判断是否发生拖动, 如果拖动了,就不再响应 onclick 事件
     29     private boolean isDrag = false;
     30 
     31     /**
     32      * 在代码里面创建对象的时候,使用此构造方法
     33      */
     34     public MyToggleButton(Context context) {
     35         super(context);
     36         // TODO Auto-generated constructor stub
     37     }
     38 
     39     /**
     40      * 在布局文件中声名的view,创建时由系统自动调用。
     41      * 
     42      * @param context
     43      *            上下文对象
     44      * @param attrs
     45      *            属性集
     46      */
     47     public MyToggleButton(Context context, AttributeSet attrs) {
     48         super(context, attrs);
     49 
     50         initView();
     51     }
     52 
     53     /**
     54      * 初始化
     55      */
     56     private void initView() {
     57 
     58         // 初始化图片
     59         backgroundBitmap = BitmapFactory.decodeResource(getResources(),
     60                 R.drawable.switch_background);
     61         slideBtn = BitmapFactory.decodeResource(getResources(),
     62                 R.drawable.slide_button);
     63 
     64         // 初始化 画笔
     65         paint = new Paint();
     66         paint.setAntiAlias(true); // 打开抗矩齿
     67 
     68         // 添加onclick事件监听
     69         setOnClickListener(this);
     70     }
     71 
     72     /*
     73      * view 对象显示的屏幕上,有几个重要步骤: 
     74      * 1、构造方法 创建 对象。 
     75      * 2、测量view的大小。 onMeasure(int,int);
     76      * 3、确定view的位置 ,view自身有一些建议权,决定权在 父view手中。 onLayout(); 
     77      * 4、绘制 view 的内容 。
     78      * onDraw(Canvas)
     79      */
     80 
     81     @Override
     82     /**
     83      * 测量尺寸时的回调方法 
     84      */
     85     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
     86         // super.onMeasure(widthMeasureSpec, heightMeasureSpec);
     87         // 设置当前view的大小 width :view的宽度 height :view的高度 (单位:像素)
     88         setMeasuredDimension(backgroundBitmap.getWidth(),
     89                 backgroundBitmap.getHeight());
     90     }
     91 
     92     // 确定位置的时候调用此方法
     93     // 自定义view的时候,作用不大
     94     // @Override
     95     // protected void onLayout(boolean changed, int left, int top, int right,
     96     // int bottom) {
     97     // super.onLayout(changed, left, top, right, bottom);
     98     // }
     99 
    100     @Override
    101     /**
    102      * 绘制当前view的内容
    103      */
    104     protected void onDraw(Canvas canvas) {
    105         // super.onDraw(canvas);
    106 
    107         // 绘制 背景
    108         /*
    109          * backgroundBitmap 要绘制的图片 left 图片的左边届 top 图片的上边届 paint 绘制图片要使用的画笔
    110          */
    111         canvas.drawBitmap(backgroundBitmap, 0, 0, paint);
    112 
    113         // 绘制 可滑动的按钮
    114         canvas.drawBitmap(slideBtn, slideBtn_left, 0, paint);
    115     }
    116 
    117 
    118     @Override
    119     /**
    120      * onclick 事件在View.onTouchEvent 中被解析。
    121      * 系统对onclick 事件的解析,过于简陋,只要有down 事件  up 事件,
    122      * 系统即认为 发生了click 事件
    123      */
    124     public void onClick(View v) {
    125         // 如果没有拖动,才执行改变状态的动作
    126         if (!isDrag) {
    127             currState = !currState;
    128             flushState();
    129         }
    130     }
    131 
    132     @Override
    133     public boolean onTouchEvent(MotionEvent event) {
    134         super.onTouchEvent(event);
    135 
    136         switch (event.getAction()) {
    137         case MotionEvent.ACTION_DOWN:
    138             firstX = lastX = (int) event.getX();
    139             isDrag = false;
    140 
    141             break;
    142         case MotionEvent.ACTION_MOVE:
    143 
    144             // 判断是否发生拖动
    145             if (Math.abs(event.getX() - firstX) > 5) {
    146                 isDrag = true;
    147             }
    148 
    149             // 计算 手指在屏幕上移动的距离
    150             int dis = (int) (event.getX() - lastX);
    151 
    152             // 将本次的位置 设置给lastX
    153             lastX = (int) event.getX();
    154 
    155             // 根据手指移动的距离,改变slideBtn_left 的值
    156             slideBtn_left = slideBtn_left + dis;
    157             break;
    158         case MotionEvent.ACTION_UP:
    160             // 在发生拖动的情况下,根据最后的位置,判断当前开关的状态
    161             if (isDrag) {
    162                 // alideBtn 左边界最大值
    163                 int maxLeft = backgroundBitmap.getWidth() - slideBtn.getWidth();
    165                 /*
    166                  * 根据 slideBtn_left 判断,当前应是什么状态
    167                  */
    168                 if (slideBtn_left > maxLeft / 2) { // 此时应为 打开的状态
    169                     currState = true;
    170                 } else {
    171                     currState = false;
    172                 }
    174                 flushState();
    175             }
    176             break;
    177         }
    179         flushView();
    181         return true;
    182     }
    183 
    184     /**
    185      * 刷新当前状态
    186      */
    187     private void flushState() {
    188         if (currState) {
    189             slideBtn_left = backgroundBitmap.getWidth() - slideBtn.getWidth();
    190         } else {
    191             slideBtn_left = 0;
    192         }
    194         flushView();
    195     }
    196 
    197     /**
    198      * 刷新当前视力
    199      */
    200     private void flushView() {
    201         /*
    202          * 对 slideBtn_left 的值进行判断 ,确保其在合理的位置 即 0<=slideBtn_left <= maxLeft
    203          */
    205         int maxLeft = backgroundBitmap.getWidth() - slideBtn.getWidth(); 207 
    208         // 确保 slideBtn_left >= 0
    209         slideBtn_left = (slideBtn_left > 0) ? slideBtn_left : 0;
    210 
    211         // 确保 slideBtn_left <=maxLeft
    212         slideBtn_left = (slideBtn_left < maxLeft) ? slideBtn_left : maxLeft;
    213 
    214         /*
    215          * 刷新当前视图 导致 执行onDraw执行
    216          */
    217         invalidate();
    218     }
    219 
    220 }

     DEMO下载地址:http://pan.baidu.com/s/1qWjXEhQ

  • 相关阅读:
    Orcale 之基本术语一
    robots 小记
    划分子网例题详解 转
    jsp中利用response.senddirect(str)重定向,传递参数新思路
    当有多个form表单请求时如何处理?
    Form表单中的action提交路径问题
    用mysql workbench导出mysql数据库关系图
    eclipse中html编辑环境的搭建
    两个jsp文件运行后弹出对话框 下载文件问题
    Eclipse tomcat配置 未在Eclipse中添加.jar包出错
  • 原文地址:https://www.cnblogs.com/androidsj/p/3995307.html
Copyright © 2011-2022 走看看