Android 自定义ToggleButton
2016-08-10 13:34
232 查看
Android自定义ToggleButton
1.需求
在项目需求中,可能需要自定义开关按钮,于是本人就根据网上的教程写了个符合自己需求的按钮首先看一下要实现的效果:有4中图片的切换效果,点击切换开关状态,还要求支持滑动切换。
2.解决思路
写个MyToggleButton类,继承自View,重写onDraw,onClick,onMeasure,onTouchEvent等事件,来实现想要的效果。最后图片的添加放到xml中,这需要在attrs中添加自定义属性。3.代码
MyToggleBtn .javapackage com.sanmiao.mytest.myview; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Paint; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import com.sanmiao.mytest.R; /** * @作者 : 丁建强 * @创建时间:2016/8/9 0009 17:36 * @类说明 :自定义切换按钮 */ public class MyToggleBtn extends View implements View.OnClickListener { private Bitmap currBtnBitmap, currBackBitmap; private Bitmap toggle_bg_on; private Bitmap toggle_bg_off; private Bitmap toggle_btn_on; private Bitmap toggle_btn_off; private Paint paint; private float slide_left = 0; private boolean currState = false;//当前开关状态,true 为开 public MyToggleBtn(Context context) { this(context, null); } public MyToggleBtn(Context context, AttributeSet attrs) { this(context, attrs, 0); } public MyToggleBtn(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); //初始化自定义属性 TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.MyToggleBtn); currState = ta.getBoolean(R.styleable.MyToggleBtn_isChecked, false); int backOnId = ta.getResourceId(R.styleable.MyToggleBtn_backImageOn, 0); int backOffId = ta.getResourceId(R.styleable.MyToggleBtn_backImageOff, 0); int slideOnId = ta.getResourceId(R.styleable.MyToggleBtn_slideImageOn, 0); int slideOffId = ta.getResourceId(R.styleable.MyToggleBtn_slideImageOff, 0); toggle_bg_on = BitmapFactory.decodeResource(getResources(), backOnId); toggle_btn_on = BitmapFactory.decodeResource(getResources(), slideOnId); if (backOffId == 0) { toggle_bg_off = toggle_bg_on; } else { toggle_bg_off = BitmapFactory.decodeResource(getResources(), backOffId); } if (slideOffId == 0) { toggle_btn_off = toggle_btn_on; } else { toggle_btn_off = BitmapFactory.decodeResource(getResources(), slideOffId); } ta.recycle(); initView(); } private void initView() { currBtnBitmap = toggle_btn_off; currBackBitmap = toggle_btn_off; paint = new Paint(); paint.setAntiAlias(true);//设置抗锯齿 setOnClickListener(this); flushState(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { //super.onMeasure(widthMeasureSpec, heightMeasureSpec); //设置当前view 大小 setMeasuredDimension(toggle_bg_on.getWidth(), toggle_btn_on.getHeight()); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //背景图片 canvas.drawBitmap(currBackBitmap, 0, getHeight() / 2 - toggle_bg_on.getHeight() / 2, paint); //滑动按钮图片 canvas.drawBitmap(currBtnBitmap, slide_left, 0, paint); } @Override public void onClick(View v) { currState = !currState; if (!isDrag) { flushState(); } } /** * 刷新当前状态 */ private void flushState() { if (currState) {//开 slide_left = toggle_bg_on.getWidth() - toggle_btn_off.getWidth(); currBackBitmap = toggle_bg_on; currBtnBitmap = toggle_btn_on; } else {//关 slide_left = 0; currBackBitmap = toggle_bg_off; currBtnBitmap = toggle_btn_off; } invalidate(); } private int firstX, lastX; boolean isDrag = false;//是否拖动 @Override public boolean onTouchEvent(MotionEvent event) { int maxLeft = getWidth() - currBtnBitmap.getWidth();//左边界做大值 super.onTouchEvent(event); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: firstX = lastX = (int) event.getX(); isDrag = false; break; case MotionEvent.ACTION_MOVE: if (Math.abs(event.getX() - firstX) > 5) { isDrag = true; } //计算手指在屏幕上移动的距离 int dis = (int) (event.getX() - firstX); //将本次的位置设置给 lastX lastX = (int) event.getX(); //根据手指移动的距离,改变slide_left的值 slide_left = slide_left + dis; if (slide_left > maxLeft / 2) { currBackBitmap = toggle_bg_on; currBtnBitmap = toggle_btn_on; } else { currBackBitmap = toggle_bg_off; currBtnBitmap = toggle_btn_off; } break; case MotionEvent.ACTION_UP: if (isDrag) { if (slide_left > maxLeft / 2) { currState = true; } else { currState = false; } flushState(); } break; } flushView(); return true; } /** * 刷新视图 */ private void flushView() { //对slide_left进行判断 0<= slide_left <= maxLeft int maxLeft = getWidth() - currBtnBitmap.getWidth();//左边界做大值 slide_left = slide_left > 0 ? slide_left : 0; slide_left = slide_left < maxLeft ? slide_left : maxLeft; invalidate(); } /** * 是否打开 * * @return */ public boolean isChecked() { return currState; } }
attrs.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="MyToggleBtn"> <attr name="isChecked" format="boolean" /> <attr name="backImageOff" format="reference" /> <attr name="backImageOn" format="reference" /> <attr name="slideImageOn" format="reference" /> <attr name="slideImageOff" format="reference" /> </declare-styleable> </resources>
activity_test.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="center"> <com.sanmiao.mytest.myview.MyToggleBtn android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="10dp" app:backImageOff="@mipmap/img_toggle_bg_off" app:slideImageOn="@mipmap/img_toggle_btn_on" app:slideImageOff="@mipmap/img_toggle_btn_off" app:backImageOn="@mipmap/img_toggle_bg_on" app:isChecked="true" /> <com.sanmiao.mytest.myview.MyToggleBtn android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="10dp" app:slideImageOn="@mipmap/slide_button" app:backImageOn="@mipmap/switch_background" app:isChecked="true" /> </LinearLayout>
4.运行效果
5.说明
若按钮只有2张图片(背景和滑动图片)只需要在xml中添加 slideImageOn 和backImageOn这两个属性就可以了;若有4张需要添加backImageOff、slideImageOn、slideImageOff、backImageOn这4个属性
相关文章推荐
- Android 自定义滑动开关ToggleButton
- Android:自定义ToggleButton
- 自定义Button模拟ToggleButton功能,android
- Android 自定义toggleButton
- android-----自定义ToggleButton
- Android自定义View仿IOS选择控件Togglebutton实现
- Android 自定义View---ToggleButton
- Android 自定义ToggleButton
- android_94_自定义ToggleButton
- Android 自定义 LinearLayout
- Android Ringtone 自定义铃声介绍
- Android高手进阶教程(三)之----Android 中自定义View的应用.
- Android中使用自定义Adapter(一)
- 新书内容连载(1):自定义Android组件之带图像的TextView
- 【转】Android自定义控件中自定义属性的处理方式
- Android中使用自定义Adapter(二)
- android构建自定义的视图组件
- android自定义列表的实现
- 新书内容连载(1):自定义Android组件之带图像的TextView
- Android自定义View设定到FrameLayout布局中实现多组件显示