zoukankan      html  css  js  c++  java
  • SlideSwitch

    //SlideSwitch.java

    [java] view plaincopy
     
    1. package com.example.hellojni;  
    2.   
    3. import android.content.Context;  
    4. import android.content.res.Resources;  
    5. import android.graphics.Bitmap;  
    6. import android.graphics.BitmapFactory;  
    7. import android.graphics.Canvas;  
    8. import android.graphics.Color;  
    9. import android.graphics.Paint;  
    10. import android.graphics.Rect;  
    11. import android.graphics.Typeface;  
    12. import android.util.AttributeSet;  
    13. import android.util.Log;  
    14. import android.view.MotionEvent;  
    15. import android.view.View;  
    16. import android.view.ViewGroup.LayoutParams;  
    17.   
    18. /** 
    19.  * SlideSwitch 仿iphone滑动开关组件,仿百度魔图滑动开关组件 
    20.  * 组件分为三种状态:打开、关闭、正在滑动<br/> 
    21.  * 使用方法:         
    22.  * <pre>SlideSwitch slideSwitch = new SlideSwitch(this); 
    23.  *slideSwitch.setOnSwitchChangedListener(onSwitchChangedListener); 
    24.  *linearLayout.addView(slideSwitch); 
    25. </pre> 
    26. 注:也可以加载在xml里面使用 
    27.  * @author scott 
    28.  * 
    29.  */  
    30. public class SlideSwitch extends View  
    31. {  
    32.     public static final String TAG = "SlideSwitch";  
    33.     public static final int SWITCH_OFF = 0;//关闭状态  
    34.     public static final int SWITCH_ON = 1;//打开状态  
    35.     public static final int SWITCH_SCROLING = 2;//滚动状态  
    36.       
    37.     //用于显示的文本  
    38.     private String mOnText = "打开";  
    39.     private String mOffText = "关闭";  
    40.   
    41.     private int mSwitchStatus = SWITCH_OFF;  
    42.   
    43.     private boolean mHasScrolled = false;//表示是否发生过滚动  
    44.   
    45.     private int mSrcX = 0, mDstX = 0;  
    46.       
    47.     private int mBmpWidth = 0;  
    48.     private int mBmpHeight = 0;  
    49.     private int mThumbWidth = 0;  
    50.   
    51.     private     Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);  
    52.       
    53.     private OnSwitchChangedListener mOnSwitchChangedListener = null;  
    54.   
    55.     //开关状态图  
    56.     Bitmap mSwitch_off, mSwitch_on, mSwitch_thumb;  
    57.   
    58.     public SlideSwitch(Context context)   
    59.     {  
    60.         this(context, null);  
    61.     }  
    62.   
    63.     public SlideSwitch(Context context, AttributeSet attrs)   
    64.     {  
    65.         super(context, attrs);  
    66.         init();  
    67.     }  
    68.   
    69.     public SlideSwitch(Context context, AttributeSet attrs, int defStyle)  
    70.     {  
    71.         super(context, attrs, defStyle);  
    72.         init();  
    73.     }  
    74.   
    75.     //初始化三幅图片  
    76.     private void init()  
    77.     {  
    78.         Resources res = getResources();  
    79.         mSwitch_off = BitmapFactory.decodeResource(res, R.drawable.bg_switch_off);  
    80.         mSwitch_on = BitmapFactory.decodeResource(res, R.drawable.bg_switch_on);  
    81.         mSwitch_thumb = BitmapFactory.decodeResource(res, R.drawable.switch_thumb);  
    82.         mBmpWidth = mSwitch_on.getWidth();  
    83.         mBmpHeight = mSwitch_on.getHeight();  
    84.         mThumbWidth = mSwitch_thumb.getWidth();  
    85.     }  
    86.   
    87.     @Override  
    88.     public void setLayoutParams(LayoutParams params)   
    89.     {  
    90.         params.width = mBmpWidth;  
    91.         params.height = mBmpHeight;  
    92.         super.setLayoutParams(params);  
    93.     }  
    94.       
    95.     /** 
    96.      * 为开关控件设置状态改变监听函数 
    97.      * @param onSwitchChangedListener 参见 {@link OnSwitchChangedListener} 
    98.      */  
    99.     public void setOnSwitchChangedListener(OnSwitchChangedListener onSwitchChangedListener)  
    100.     {  
    101.         mOnSwitchChangedListener = onSwitchChangedListener;  
    102.     }  
    103.       
    104.     /** 
    105.      * 设置开关上面的文本 
    106.      * @param onText  控件打开时要显示的文本 
    107.      * @param offText  控件关闭时要显示的文本 
    108.      */  
    109.     public void setText(final String onText, final String offText)  
    110.     {  
    111.         mOnText = onText;  
    112.         mOffText =offText;  
    113.         invalidate();  
    114.     }  
    115.       
    116.     /** 
    117.      * 设置开关的状态 
    118.      * @param on 是否打开开关 打开为true 关闭为false 
    119.      */  
    120.     public void setStatus(boolean on)  
    121.     {  
    122.         mSwitchStatus = ( on ? SWITCH_ON : SWITCH_OFF);  
    123.     }  
    124.       
    125.     @Override  
    126.     public boolean onTouchEvent(MotionEvent event)  
    127.     {  
    128.         int action = event.getAction();  
    129.         Log.d(TAG, "onTouchEvent  x="  + event.getX());  
    130.         switch (action) {  
    131.         case MotionEvent.ACTION_DOWN:  
    132.             mSrcX = (int) event.getX();  
    133.             break;  
    134.         case MotionEvent.ACTION_MOVE:  
    135.             mDstX = Math.max( (int) event.getX(), 10);  
    136.             mDstX = Math.min( mDstX, 62);  
    137.             if(mSrcX == mDstX)  
    138.                 return true;  
    139.             mHasScrolled = true;  
    140.             AnimationTransRunnable aTransRunnable = new AnimationTransRunnable(mSrcX, mDstX, 0);  
    141.             new Thread(aTransRunnable).start();  
    142.             mSrcX = mDstX;  
    143.             break;  
    144.         case MotionEvent.ACTION_UP:  
    145.             if(mHasScrolled == false)//如果没有发生过滑动,就意味着这是一次单击过程  
    146.             {  
    147.                 mSwitchStatus = Math.abs(mSwitchStatus-1);  
    148.                 int xFrom = 10, xTo = 62;  
    149.                 if(mSwitchStatus == SWITCH_OFF)  
    150.                 {  
    151.                     xFrom = 62;  
    152.                     xTo = 10;  
    153.                 }  
    154.                 AnimationTransRunnable runnable = new AnimationTransRunnable(xFrom, xTo, 1);  
    155.                 new Thread(runnable).start();  
    156.             }  
    157.             else  
    158.             {  
    159.                 invalidate();  
    160.                 mHasScrolled = false;  
    161.             }  
    162.             //状态改变的时候 回调事件函数  
    163.             if(mOnSwitchChangedListener != null)  
    164.             {  
    165.                 mOnSwitchChangedListener.onSwitchChanged(this, mSwitchStatus);  
    166.             }  
    167.             break;  
    168.   
    169.         default:  
    170.             break;  
    171.         }  
    172.         return true;  
    173.     }  
    174.   
    175.     @Override  
    176.     protected void onSizeChanged(int w, int h, int oldw, int oldh)  
    177.     {  
    178.         super.onSizeChanged(w, h, oldw, oldh);  
    179.     }  
    180.   
    181.     @Override  
    182.     protected void onDraw(Canvas canvas)  
    183.     {  
    184.         super.onDraw(canvas);  
    185.         //绘图的时候 内部用到了一些数值的硬编码,其实不太好,  
    186.         //主要是考虑到图片的原因,图片周围有透明边界,所以要有一定的偏移  
    187.         //硬编码的数值只要看懂了代码,其实可以理解其含义,可以做相应改进。  
    188.         mPaint.setTextSize(14);  
    189.         mPaint.setTypeface(Typeface.DEFAULT_BOLD);  
    190.           
    191.         if(mSwitchStatus == SWITCH_OFF)  
    192.         {  
    193.             drawBitmap(canvas, null, null, mSwitch_off);  
    194.             drawBitmap(canvas, null, null, mSwitch_thumb);  
    195.             mPaint.setColor(Color.rgb(105, 105, 105));  
    196.             canvas.translate(mSwitch_thumb.getWidth(), 0);  
    197.             canvas.drawText(mOffText, 0, 20, mPaint);  
    198.         }  
    199.         else if(mSwitchStatus == SWITCH_ON)  
    200.         {  
    201.             drawBitmap(canvas, null, null, mSwitch_on);  
    202.             int count = canvas.save();  
    203.             canvas.translate(mSwitch_on.getWidth() - mSwitch_thumb.getWidth(), 0);  
    204.             drawBitmap(canvas, null, null, mSwitch_thumb);  
    205.             mPaint.setColor(Color.WHITE);  
    206.             canvas.restoreToCount(count);  
    207.             canvas.drawText(mOnText, 17, 20, mPaint);  
    208.         }  
    209.         else //SWITCH_SCROLING  
    210.         {  
    211.             mSwitchStatus = mDstX > 35 ? SWITCH_ON : SWITCH_OFF;  
    212.             drawBitmap(canvas, new Rect(0, 0, mDstX, mBmpHeight), new Rect(0, 0, (int)mDstX, mBmpHeight), mSwitch_on);  
    213.             mPaint.setColor(Color.WHITE);  
    214.             canvas.drawText(mOnText, 17, 20, mPaint);  
    215.   
    216.             int count = canvas.save();  
    217.             canvas.translate(mDstX, 0);  
    218.             drawBitmap(canvas, new Rect(mDstX, 0, mBmpWidth, mBmpHeight),  
    219.                           new Rect(0, 0, mBmpWidth - mDstX, mBmpHeight), mSwitch_off);  
    220.             canvas.restoreToCount(count);  
    221.   
    222.             count = canvas.save();  
    223.             canvas.clipRect(mDstX, 0, mBmpWidth, mBmpHeight);  
    224.             canvas.translate(mThumbWidth, 0);  
    225.             mPaint.setColor(Color.rgb(105, 105, 105));  
    226.             canvas.drawText(mOffText, 0, 20, mPaint);  
    227.             canvas.restoreToCount(count);  
    228.   
    229.             count = canvas.save();  
    230.             canvas.translate(mDstX - mThumbWidth / 2, 0);  
    231.             drawBitmap(canvas, null, null, mSwitch_thumb);  
    232.             canvas.restoreToCount(count);  
    233.         }  
    234.   
    235.     }  
    236.   
    237.     public void drawBitmap(Canvas canvas, Rect src, Rect dst, Bitmap bitmap)  
    238.     {  
    239.         dst = (dst == null ? new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()) : dst);  
    240.         Paint paint = new Paint();  
    241.         canvas.drawBitmap(bitmap, src, dst, paint);  
    242.     }  
    243.   
    244.     /** 
    245.      * AnimationTransRunnable 做滑动动画所使用的线程 
    246.      */  
    247.     private class AnimationTransRunnable implements Runnable  
    248.     {  
    249.         private int srcX, dstX;  
    250.         private int duration;  
    251.   
    252.         /** 
    253.          * 滑动动画 
    254.          * @param srcX 滑动起始点 
    255.          * @param dstX 滑动终止点 
    256.          * @param duration 是否采用动画,1采用,0不采用 
    257.          */  
    258.         public AnimationTransRunnable(float srcX, float dstX, final int duration)  
    259.         {  
    260.             this.srcX = (int)srcX;  
    261.             this.dstX = (int)dstX;  
    262.             this.duration = duration;  
    263.         }  
    264.   
    265.         @Override  
    266.         public void run()   
    267.         {  
    268.             final int patch = (dstX > srcX ? 5 : -5);  
    269.             if(duration == 0)  
    270.             {  
    271.                 SlideSwitch.this.mSwitchStatus = SWITCH_SCROLING;  
    272.                 SlideSwitch.this.postInvalidate();  
    273.             }  
    274.             else  
    275.             {  
    276.                 Log.d(TAG, "start Animation: [ " + srcX + " , " + dstX + " ]");  
    277.                 int x = srcX + patch;  
    278.                 while (Math.abs(x-dstX) > 5)   
    279.                 {  
    280.                     mDstX = x;  
    281.                     SlideSwitch.this.mSwitchStatus = SWITCH_SCROLING;  
    282.                     SlideSwitch.this.postInvalidate();  
    283.                     x += patch;  
    284.                     try   
    285.                     {  
    286.                         Thread.sleep(10);  
    287.                     }   
    288.                     catch (InterruptedException e)  
    289.                     {  
    290.                         e.printStackTrace();  
    291.                     }  
    292.                 }  
    293.                 mDstX = dstX;  
    294.                 SlideSwitch.this.mSwitchStatus = mDstX > 35 ? SWITCH_ON : SWITCH_OFF;  
    295.                 SlideSwitch.this.postInvalidate();  
    296.             }  
    297.         }  
    298.   
    299.     }  
    300.   
    301.     public static interface OnSwitchChangedListener  
    302.     {  
    303.         /** 
    304.          * 状态改变 回调函数 
    305.          * @param status  SWITCH_ON表示打开 SWITCH_OFF表示关闭 
    306.          */  
    307.         public abstract void onSwitchChanged(SlideSwitch obj, int status);  
    308.     }  
    309.   
    310. }  
     
    // layout xml
    [html] view plaincopy
     
    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    3.     android:layout_width="fill_parent"  
    4.     android:layout_height="fill_parent"  
    5.     android:background="#fdfdfd"  
    6.     android:orientation="vertical"  
    7.     android:paddingLeft="10dip"  
    8.     android:paddingRight="10dip" >  
    9.   
    10.     <ImageView  
    11.         android:id="@+id/imageView1"  
    12.         android:layout_width="fill_parent"  
    13.         android:layout_height="wrap_content"  
    14.         android:src="@drawable/top" />  
    15.   
    16.     <RelativeLayout  
    17.         android:layout_width="fill_parent"  
    18.         android:layout_height="wrap_content" >  
    19.   
    20.         <TextView  
    21.             android:id="@+id/textView1"  
    22.             android:layout_width="wrap_content"  
    23.             android:layout_height="wrap_content"  
    24.             android:layout_alignParentLeft="true"  
    25.             android:layout_centerVertical="true"  
    26.             android:text="网络构图"  
    27.             android:textSize="15sp" />  
    28.   
    29.         <com.example.hellojni.SlideSwitch  
    30.             android:id="@+id/slideSwitch1"  
    31.             android:layout_width="116dip"  
    32.             android:layout_height="46dip"  
    33.             android:layout_alignParentRight="true"  
    34.             android:layout_centerVertical="true" />  
    35.     </RelativeLayout>  
    36.   
    37.     <RelativeLayout  
    38.         android:layout_width="fill_parent"  
    39.         android:layout_height="wrap_content" >  
    40.   
    41.         <TextView  
    42.             android:id="@+id/textView2"  
    43.             android:layout_width="wrap_content"  
    44.             android:layout_height="wrap_content"  
    45.             android:layout_alignParentLeft="true"  
    46.             android:layout_centerVertical="true"  
    47.             android:text="保留原图"  
    48.             android:textSize="15sp" />  
    49.   
    50.         <com.example.hellojni.SlideSwitch  
    51.             android:id="@+id/slideSwitch2"  
    52.             android:layout_width="116dip"  
    53.             android:layout_height="46dip"  
    54.             android:layout_alignParentRight="true"  
    55.             android:layout_centerVertical="true" />  
    56.     </RelativeLayout>  
    57.   
    58.     <RelativeLayout  
    59.         android:layout_width="fill_parent"  
    60.         android:layout_height="wrap_content" >  
    61.   
    62.         <TextView  
    63.             android:id="@+id/textView3"  
    64.             android:layout_width="wrap_content"  
    65.             android:layout_height="wrap_content"  
    66.             android:layout_alignParentLeft="true"  
    67.             android:layout_centerVertical="true"  
    68.             android:text="拍照声音"  
    69.             android:textSize="15sp" />  
    70.   
    71.         <com.example.hellojni.SlideSwitch  
    72.             android:id="@+id/slideSwitch3"  
    73.             android:layout_width="116px"  
    74.             android:layout_height="46px"  
    75.             android:layout_alignParentRight="true"  
    76.             android:layout_centerVertical="true" />  
    77.     </RelativeLayout>  
    78.   
    79.     <TextView  
    80.         android:id="@+id/textViewTip"  
    81.         android:layout_width="fill_parent"  
    82.         android:layout_height="wrap_content"  
    83.         android:gravity="center"  
    84.         android:text="TextView" />  
    85.   
    86. </LinearLayout>  
  • 相关阅读:
    01视频传输,监控,直播方案摄像头如何采集的图像,MCU如何读取的图像数据
    203ESP32_SDK开发softAP+station共存模式
    2视频传输,监控,直播方案搭建视频流服务器,推送视频流,拉取视频流观看(RTMP,m3u8)
    F# (Part one)
    测试驱动开发(一)我们要的不仅仅是“质量”
    软件开发中的破窗效应
    结对编程神奇的力量
    《高性能网站建设指南》笔记
    【线程呓语】Thread
    【线程呓语】与线程相关的一些概念
  • 原文地址:https://www.cnblogs.com/qianyukun/p/4892423.html
Copyright © 2011-2022 走看看