Android 自定义滑动开关ToggleButton
来源:互联网 发布:dash windows版 编辑:程序博客网 时间:2024/05/18 12:31
不得不说,在做自定义滑动开关过程中,学习到了很多东西。跟大家分享分享!
1、自定义控件步骤:
测量:onMeasure 设置自己显示在屏幕上的宽高布局:onLayout 设置自己显示在屏幕上的位置(只有在自定义ViewGroup中才用到,需要设置子view的位置)
绘制:onDraw 控制显示在屏幕上的样子(自定义viewgroup时不需要这个,绘制单个view的样子)
所以我们在自定义一个控件之前,要明白自定义的是一个view,还是一个viewgroup,如:本篇中自定义的ToggleButton
只是一个简单view,本人是这样理解的:view相当于button,textview之类的小控件,而viewgroup相当于RelativeLayout
之类的布局。大家可以提出个人的见解让他人可以更好的理解view与viewgroup的差别!
View和ViewGroup的区别
1.他们都需要进行测量操作
2.ViewGroup主要是控制子view如何摆放,所以必须实现onLayout
View没有子view,所以不需要onLayout方法,但是必须实现onDraw
3、废话有点多,先贴出ToggleButton效果图:
4、源码:xml中很简单:
<com.chenshi.mytogglebutton.ToggleButton android:id="@+id/toggleBtn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" />
最后一句是使view居于父控件居中!
5、MainActivity中:
toggleButton.setSildeBackgroundResource(R.drawable.slide_bg);toggleButton.setSwitchOnBackgroundResource(R.drawable.switch_on);toggleButton.setSwitchOffBackgroundResource(R.drawable.switch_off);//设置开关状态,默认为OPENtoggleButton.setToggleState(ToggleButton.ToggleState.CLOSE);toggleButton.setOnStateChangeListeren(new ToggleButton.OnToggleStateChangeListeren() { @Override public void onToggleStateChangeListeren(ToggleButton.ToggleState toggleState) { Toast.makeText(MainActivity.this, toggleState == ToggleButton.ToggleState.CLOSE ? "关" : "开",Toast.LENGTH_SHORT).show(); }});
为什么要先贴出MainActivity中源码呢,因为我们通过set知道我们自定中需要哪里方法,如:
toggleButton.setSildeBackgroundResource(R.drawable.slide_bg);对应于自定类ToggleButton中就要有/** * 设置滑块的背景图片 * * @param slide_bg */public void setSildeBackgroundResource(int slide_bg) { slideBg = BitmapFactory.decodeResource(getResources(), slide_bg);}此方法!这是一种思路!并不是盲目的自定义方法!
6、自定类源码:注释的挺详细的,大家耐心点看!
public class ToggleButton extends View { private Bitmap slideBg;//滑块的背景图 private Bitmap switchOn;//滑动开关开的背景图 private Bitmap switchOff;//滑动开关关的背景图 private ToggleState state = ToggleState.OPEN;//滑动开关的状态,默认为OPEN; //手指触摸在view上的坐标,这个是相对于view的坐标 private int currentX; //是否在滑动 private boolean isSliding = true; /** * 如果自定的控件需要在Java中实例化,重写该构造方法 * * @param context */ public ToggleButton(Context context) { super(context); } /** * 如果自定义控件需要在xml文件使用,重写该构造方法 * * @param context * @param attrs */ public ToggleButton(Context context, AttributeSet attrs) { super(context, attrs); } /** * 设置滑块的背景图片 * * @param slide_bg */ public void setSildeBackgroundResource(int slide_bg) { slideBg = BitmapFactory.decodeResource(getResources(), slide_bg); } /** * 设置滑动开关开的背景图 * * @param switch_on */ public void setSwitchOnBackgroundResource(int switch_on) { switchOn = BitmapFactory.decodeResource(getResources(), switch_on); } /** * 设置滑动开关关的背景图 * * @param switch_off */ public void setSwitchOffBackgroundResource(int switch_off) { switchOff = BitmapFactory.decodeResource(getResources(), switch_off); } public void setToggleState(ToggleState toggleState) { this.state = toggleState; } public enum ToggleState { OPEN, CLOSE } /** * 绘制view的宽与高,以滑动开关的宽高绘制 * * @param widthMeasureSpec * @param heightMeasureSpec */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); setMeasuredDimension(switchOn.getWidth(), switchOn.getHeight()); } /** * 画view * * @param canvas */ @Override protected void onDraw(Canvas canvas) { int left = currentX - slideBg.getWidth() / 2; // (left > (switchOn.getWidth() / 2)) ? ((state = ToggleState.OPEN)) : ((state = ToggleState.CLOSE)); //当触摸点超过整view的一半时,就切换开关背景; super.onDraw(canvas); /** * (@NonNull Bitmap bitmap, float left, float top, @Nullable Paint paint) * left:图片左边的x坐标 * top:图片顶部的y坐标 */ if (isSliding) { if (state == ToggleState.OPEN) { //绘制开关图片 canvas.drawBitmap(switchOn, 0, 0, null); //绘制滑块图片 if (left > (switchOn.getWidth() - slideBg.getWidth())) left = switchOn.getWidth() - slideBg.getWidth(); canvas.drawBitmap(slideBg, left, 0, null); } else { //绘制开关图片 canvas.drawBitmap(switchOff, 0, 0, null); //绘制滑块图片 if (left < 0) left = 0; canvas.drawBitmap(slideBg, left, 0, null); } } else { if (state == ToggleState.OPEN) { //绘制开关图片 canvas.drawBitmap(switchOn, 0, 0, null); canvas.drawBitmap(slideBg, switchOn.getWidth() - slideBg.getWidth(), 0, null); } else { //绘制开关图片 canvas.drawBitmap(switchOff, 0, 0, null); canvas.drawBitmap(slideBg, 0, 0, null); } } } /** * 定义滑动 * * @param event * @return */ @Override public boolean onTouchEvent(MotionEvent event) { currentX = (int) event.getX(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: isSliding = true; break; case MotionEvent.ACTION_MOVE: break; case MotionEvent.ACTION_UP: isSliding = false; break; } //在滑动的过程中状态改变也进行监听,触摸结束后也监听状态改变,未改变就无需其他动作 if (currentX > switchOn.getWidth() / 2) { if (state != ToggleState.OPEN) { state = ToggleState.OPEN; if (stateChangeListeren != null) { stateChangeListeren.onToggleStateChangeListeren(state); } } } else { //CLOSE if (state != ToggleState.CLOSE) { state = ToggleState.CLOSE; if (stateChangeListeren != null) { stateChangeListeren.onToggleStateChangeListeren(state); } } } //调用此方法,间接调用OnD invalidate(); return true; } /** * 开放状态改变接口 */ private OnToggleStateChangeListeren stateChangeListeren; public void setOnStateChangeListeren(OnToggleStateChangeListeren stateChangeListeren) { this.stateChangeListeren = stateChangeListeren; } public interface OnToggleStateChangeListeren { void onToggleStateChangeListeren(ToggleState state); }}
1 0
- Android 自定义滑动开关ToggleButton
- 自定义滑动开关(ToggleButton)
- Android 滑动开关(ToggleButton) 解析
- Android 开发 ToggleButton 滑动开关按钮
- android自定义滑动开关
- Android ToggleButton(自定义可滑动的ToggleButton控件)
- Android 开发之 ToggleButton App 滑动开关按钮
- Android自定义控件---滑动开关
- android自定义滑动选择开关
- Android 自定义SwitchView(滑动开关)
- Android开关控件ToggleButton
- Android-开关按钮ToggleButton
- Android ToggleButton 开关按钮
- Android ToggleButton(开关)
- android自定义滑动开关控件,自定义view
- Android:android自定义滑动开关控件
- Android ToggleButton Example--开关按钮
- Android---19---ToggleButton开关按钮
- Android Studio Jar、so、library项目依赖
- 工作前的准备
- Upgrade CentOS 7 kernel
- Lowest Common Ancestor of a Binary Search Tree
- Linux makefile 教程 非常详细,且易懂
- Android 自定义滑动开关ToggleButton
- 荷兰国旗问题
- HDU 1429 胜利大逃亡(续)
- mysql 修改 COMMENT
- TortoiseGit 使用详解
- 开通啦
- 如何解决Android 5.0中出现的警告:Service Intent must be explict
- Android Notification学习
- Codeforces 569B__Inventory