自定义滑动开关按钮-SwitchButton-进阶

来源:互联网 发布:mac silverlight下载 编辑:程序博客网 时间:2024/05/18 13:25
之前写过这样一个简单的控件,详情可见:[ 自定义滑动开关按钮-SwitchButton](http://blog.csdn.net/u012424449/article/details/51678311)发现还是有点不方便,存在一些问题:    1.字体没有居中显示    2.图片和字都是固定的,不灵活于是在这基础上进行了改良,效果如下,和上次效果几乎一样。本来是有点击事件的,但是这录屏软件好像屏蔽了,录制的时候不会出现,录制完了就会出现屏蔽掉的Toast。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

这里写图片描述

1.首先在values目录里添加xml文件:attrs,自定义属性,具体如下: 
attrs.xml

<resources>    <declare-styleable name="AutoButton">        <attr name="textOn" format="string"/>        <attr name="textOff" format="string"/>        <attr name="textSize_ab" format="dimension"/>        <attr name="bg_bitmap" format="reference"/>        <attr name="btn_bitmap" format="reference"/>    </declare-styleable></resources>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
2.新建一个类继承系统View,在创建的时候获取xml中的属性,具体代码如下:
  • 1
  • 2
 TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AutoButton);        Drawable bg_Drawable = a.getDrawable(R.styleable.AutoButton_bg_bitmap);        Drawable btn_Drawable = a.getDrawable(R.styleable.AutoButton_btn_bitmap);        textOn = a.getString(R.styleable.AutoButton_textOn);        textOff = a.getString(R.styleable.AutoButton_textOff);        textSize = a.getDimension(R.styleable.AutoButton_textSize_ab, 35);        //注意此操作        a.recycle();        bgBitmap = ((BitmapDrawable) bg_Drawable).getBitmap();        btnBitmap = ((BitmapDrawable) btn_Drawable).getBitmap();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

在上面代码我标注了注意的操作,因为TypeArray是一个单例模式,这个 array 是从一个 array pool的池中获取的。具体可以参考这篇文章:http://blog.csdn.net/Monicabg/article/details/45014327

主要也就是这两个步骤,其他的我就直接上源码了:

AuttoButton.java

import android.content.Context;import android.content.res.TypedArray;import android.graphics.Bitmap;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.drawable.BitmapDrawable;import android.graphics.drawable.Drawable;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;/** * Created by admin on 2016/6/13. * author: myc * CopyRight: * email:myc1101255053@163.com * description: */public class AutoButton extends View implements View.OnTouchListener {    //背景图片    private Bitmap bgBitmap;    //按钮图片    private Bitmap btnBitmap;    private Paint paint;    private int leftDis = 0;    //标记最大滑动    private int slidingMax;    //标记按钮开关状态    private boolean mCurrent;    //标记是否点击事件    private boolean isClickable;    //标记是否移动    private boolean isMove;    //"开"事件监听器    private SoftFloorListener softFloorListener;    //"关"事件监听器    private HydropowerListener hydropowerListener;    //标记开关文本的宽度    float width1, width2;    //记录文本中心点 cx1:绘制文本1的x坐标  cx2:绘制文本2的x坐标    //cy记录绘制文本的高度    float cx1, cy, cx2;    //定义"开"文本    String textOn;    //定义"关"文本    String textOff;    //定义文本大小    float textSize;    public AutoButton(Context context) {        this(context, null);    }    public AutoButton(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public AutoButton(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        initData(context, attrs);        initView();    }    private void initData(Context context, AttributeSet attrs) {        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AutoButton);        Drawable bg_Drawable = a.getDrawable(R.styleable.AutoButton_bg_bitmap);        Drawable btn_Drawable = a.getDrawable(R.styleable.AutoButton_btn_bitmap);        textOn = a.getString(R.styleable.AutoButton_textOn);        textOff = a.getString(R.styleable.AutoButton_textOff);        textSize = a.getDimension(R.styleable.AutoButton_textSize_ab, 35);        a.recycle();        bgBitmap = ((BitmapDrawable) bg_Drawable).getBitmap();        btnBitmap = ((BitmapDrawable) btn_Drawable).getBitmap();    }    private void initView() {        paint = new Paint();        slidingMax = bgBitmap.getWidth() - btnBitmap.getWidth();        paint.setTextSize(textSize);        width1 = paint.measureText(textOn);        cx1 = btnBitmap.getWidth() / 2 - width1 / 2;        //测量绘制文本高度        Paint.FontMetrics fontMetrics=paint.getFontMetrics();        float fontHeight=fontMetrics.bottom-fontMetrics.top;        cy = btnBitmap.getHeight() -(btnBitmap.getHeight()-fontHeight)/2-fontMetrics.bottom;        width2 = paint.measureText(textOff);        cx2 = (bgBitmap.getWidth() * 2 - btnBitmap.getWidth()) / 2 - width2 / 2;        paint.setAntiAlias(true);        setOnTouchListener(this);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        setMeasuredDimension(bgBitmap.getWidth(), bgBitmap.getHeight());    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        canvas.drawBitmap(bgBitmap, 0, 0, paint);        canvas.drawBitmap(btnBitmap, leftDis, 0, paint);        if (mCurrent) {            paint.setColor(Color.WHITE);            canvas.drawText(textOff, cx2, cy, paint);            paint.setColor(Color.BLACK);            canvas.drawText(textOn, cx1, cy, paint);        } else {            paint.setColor(Color.WHITE);            canvas.drawText(textOn, cx1, cy, paint);            paint.setColor(Color.BLACK);            canvas.drawText(textOff, cx2, cy, paint);        }    }    //刷新视图    private void flushView() {        mCurrent = !mCurrent;        if (mCurrent) {            leftDis = slidingMax;            if (hydropowerListener != null) {                hydropowerListener.hydropower();            }        } else {            leftDis = 0;            if (softFloorListener != null) {                softFloorListener.softFloor();            }        }//        System.out.println("mCurrent:="+mCurrent);        invalidate();    }    //startX 标记按下的X坐标,  lastX标记移动后的X坐标 ,disX移动的距离    float startX, lastX, disX;    @Override    public boolean onTouch(View v, MotionEvent event) {        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:                isClickable = true;                startX = event.getX();                isMove = false;                break;            case MotionEvent.ACTION_MOVE:                lastX = event.getX();                disX = lastX - startX;                if (Math.abs(disX) < 5) break;                isMove = true;                isClickable = false;                moveBtn();                startX = event.getX();                break;            case MotionEvent.ACTION_UP:                if (isClickable) {                    flushView();                }                if (isMove) {                    if (leftDis > slidingMax / 2) {                        mCurrent = false;                    } else {                        mCurrent = true;                    }                    flushView();                }                break;        }        return true;    }    //移动后判断位置    private void moveBtn() {        leftDis += disX;        if (leftDis > slidingMax) {            leftDis = slidingMax;        } else if (leftDis < 0) {            leftDis = 0;        }        invalidate();    }    //设置左边按钮点击事件监听器    public void setSoftFloorListener(SoftFloorListener softFloorListener) {        this.softFloorListener = softFloorListener;    }    //设置右边按钮点击事件监听器    public void setHydropowerListener(HydropowerListener hydropowerListener) {        this.hydropowerListener = hydropowerListener;    }    //开点击事件    public interface SoftFloorListener {        void softFloor();    }    //关点击事件    public interface HydropowerListener {        void hydropower();    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211

然后就是在xml布局里调用,具体如下:

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    <!--注意此步骤-->    xmlns:myc="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin">  <com.yigong.admin.autobutton.AutoButton      android:id="@+id/btn_switchbutton"      android:layout_width="wrap_content"      android:layout_height="wrap_content"      myc:bg_bitmap="@drawable/bg"      myc:btn_bitmap="@drawable/btn"      myc:textSize_ab="15sp"      myc:textOn="开"      myc:textOff="关"      android:padding="10dp"      android:layout_centerHorizontal="true"/></RelativeLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

在上面我标注了注意步骤,因为需要使用自定义的控件属性,所以需要设置xml命名空间 
xmlns:myc=”http://schemas.android.com/apk/res-auto”,简单点可以这么设置,规范是 
xmlns:myc=”http://schemas.android.com/apk/<这里是包名>”

MainActivity.java

public class MainActivity extends Activity {    private AutoButton btn_switchbutton;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);       initView();    }    private void initView() {        btn_switchbutton= (AutoButton) findViewById(R.id.btn_switchbutton);        btn_switchbutton.setHydropowerListener(hydropowerListener);        btn_switchbutton.setSoftFloorListener(softFloorListener);    }    AutoButton.HydropowerListener hydropowerListener=new AutoButton.HydropowerListener() {        @Override        public void hydropower() {            Toast.makeText(MainActivity.this,"关",Toast.LENGTH_SHORT).show();        }    };    AutoButton.SoftFloorListener softFloorListener=new AutoButton.SoftFloorListener() {        @Override        public void softFloor() {      Toast.makeText(MainActivity.this,"开",Toast.LENGTH_SHORT).show();        }    };}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

完整代码可前往GitHub:https://github.com/yangmyc/SwitchButton 
我这里设置了点击事件,因为录屏软件问题,所以没有显示,关了录屏软件后,之前的Toast就全出来了。有问题可以私聊,或者你有更好的方法,请多多指教

阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 彩条布尺寸 彩条布批发市场 彩条布的价格 彩条布执行标准 彩胶布 塑料彩条布价格 彩条布批发 彩条布生产厂家 彩条布报价 彩条布多少钱一米 彩条布价格多少一平方 彩带蝴蝶结 彩带简笔画 彩带图片 彩带舞 彩带之舞 彩带怎么画 彩带风铃 彩带素材 彩带图 彩带怎么用 彩带怎么叠 彩带花 彩带的价格 彩带手工 彩带拉花 拉花彩带 驱鸟彩带 塑料彩带 礼盒彩带 儿童彩带舞 彩带幼儿园 彩带矢量图 ps彩带素材 彩带折花大全图解 一条彩带拉花大全图解 彩带编织手链 彩带装饰房间图片 塑料彩带折花大全图解 彩带折星星的教程一步一步教 彩带蝴蝶结的折法