滑动开关-----自定义
2015-07-22 09:01
357 查看
1. 自定义控件步骤:
测量:onMeasure 设置自己显示在屏幕上的宽高
布局:onLayout 设置自己显示在屏幕上的位置(只有在自定义ViewGroup中才用到)
绘制:onDraw 控制显示在屏幕上的样子(自定义viewgroup时不需要这个)
2. View和ViewGroup的区别
(1).他们都需要进行测量操作
(2).ViewGroup主要是控制子view如何摆放,所以必须实现onLayout
View没有子view,所以不需要onLayout方法,但是必须实现onDraw
3.根据需求定制控件,例如:控件需要判断开关状态,则有一个方法set
4.id转换成bitmap
5.两个坐标系:屏幕坐标系,view坐标系
6.布局使用 java的位置
7. 设计需求
8.根据需求设计代码
测量:onMeasure 设置自己显示在屏幕上的宽高
布局:onLayout 设置自己显示在屏幕上的位置(只有在自定义ViewGroup中才用到)
绘制:onDraw 控制显示在屏幕上的样子(自定义viewgroup时不需要这个)
2. View和ViewGroup的区别
(1).他们都需要进行测量操作
(2).ViewGroup主要是控制子view如何摆放,所以必须实现onLayout
View没有子view,所以不需要onLayout方法,但是必须实现onDraw
3.根据需求定制控件,例如:控件需要判断开关状态,则有一个方法set
4.id转换成bitmap
switchBg = BitmapFactory.decodeResource(getResources(), switchBackground);
5.两个坐标系:屏幕坐标系,view坐标系
6.布局使用 java的位置
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" > <com.heima52.togglebutton.view.ToggleButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:id="@+id/toggleButton"/> </RelativeLayout>
7. 设计需求
public class MainActivity extends Activity { private ToggleButton toggleButton; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); toggleButton = (ToggleButton) findViewById(R.id.toggleButton); toggleButton.setSlideBackgroudResource(R.drawable.slide_button_background); toggleButton.setSwitchBackgroudResource(R.drawable.switch_background); toggleButton.setToggleState(ToggleState.Open); toggleButton.setOnToggleStateChangeListener(new OnToggleStateChangeListner() { @Override public void onToggleStateChange(ToggleState state) { Toast.makeText(MainActivity.this, state==ToggleState.Open?"开启":"关闭", 0).show(); } }); } }
8.根据需求设计代码
public class ToggleButton extends View{ private ToggleState toggleState = ToggleState.Open;//开关的状态 private Bitmap slideBg; private Bitmap switchBg; private boolean isSliding = false; private int currentX;//当前触摸点x坐标 /** * 如果你的view只是在布局文件中使用,只需要重写这个构造方法 * @param context * @param attrs */ public ToggleButton(Context context, AttributeSet attrs) { super(context, attrs); } /** * 如果你的 view需要在java代码中动态new出来,走的是这个构造方法 * @param context */ public ToggleButton(Context context) { super(context); } public enum ToggleState{ Open,Close } /** * 设置滑动块的背景图片 * @param slideButtonBackground */ public void setSlideBackgroudResource(int slideButtonBackground) { slideBg = BitmapFactory.decodeResource(getResources(), slideButtonBackground); } /** * 设置滑动开关的背景图片 * @param switchBackground */ public void setSwitchBackgroudResource(int switchBackground) { switchBg = BitmapFactory.decodeResource(getResources(), switchBackground); } /** * 设置开关的状态 * @param open */ public void setToggleState(ToggleState state) { toggleState = state; } /** * 设置当前控件显示在屏幕上的宽高 */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); setMeasuredDimension(switchBg.getWidth(), switchBg.getHeight()); } /** * 绘制自己显示在屏幕时的样子 */ @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //1.绘制背景图片 //left: 图片的左边的x坐标 //top: 图片顶部的y坐标 canvas.drawBitmap(switchBg, 0, 0, null); //2.绘制滑动块的图片 if(isSliding){ int left = currentX - slideBg.getWidth()/2; if(left<0)left = 0; if(left>(switchBg.getWidth() - slideBg.getWidth())){ left = switchBg.getWidth() - slideBg.getWidth(); } canvas.drawBitmap(slideBg, left, 0, null); }else { //此时抬起,根据state去绘制滑动块的位置 if(toggleState==ToggleState.Open){ canvas.drawBitmap(slideBg, switchBg.getWidth()-slideBg.getWidth(), 0, null); }else { canvas.drawBitmap(slideBg, 0, 0, null); } } } /** *触摸状态 */ @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; int centerX = switchBg.getWidth()/2; if(currentX>centerX){ //open if(toggleState!=ToggleState.Open){ toggleState = ToggleState.Open; if(listner!=null){ listner.onToggleStateChange(toggleState); } } }else { //close if(toggleState!=ToggleState.Close){ toggleState = ToggleState.Close; if(listner!=null){ listner.onToggleStateChange(toggleState); } } } break; } invalidate();//刷新,调用ondraw()方法,重绘,不能直接调用ondraw() return true; } private OnToggleStateChangeListner listner; public void setOnToggleStateChangeListener(OnToggleStateChangeListner listner){ this.listner = listner; } //暴露数据给用户 public interface OnToggleStateChangeListner{ void onToggleStateChange(ToggleState state); } }
相关文章推荐
- FPGA 软件Quartus II 版本下载地址
- 命令模式
- VS2012 反汇编
- iOS开发多线程同步
- 【DP模型:LCS】uva1625 Color Length
- Java数组简单用法
- iOS开发 - CALayer图层
- 常用的 nosql 数据库
- [leetcode 189] Rotate Array
- 图片折叠效果:Layer的contentsRect属性和渐变层
- google ip 系列之一
- iOS接收null的处理方法
- G - Gargari and Bishops-贪心暴力
- iOS应用安全开发,你不知道的那些事
- visual studio 2015 下载地址
- 深入理解Java内存模型--转载
- 11个Visual Studio代码性能分析工具
- virtualbox_ubuntu和Windows共享文件夹
- 安卓中的JSON解析
- Linux中出现/usr/bin/ld: cannot find -lxxx报错该怎么办?