Android学习(43) -- 自定义控件(7) 滑动开关
来源:互联网 发布:南京软件行业优惠政策 编辑:程序博客网 时间:2024/06/10 15:58
简介
自定义控件步骤:
1. 写类继承View
2. 重写onDraw, 进行绘制
3. 重新onMeasure,修改尺寸 要使用 setMeasuredDimension设置当前自定义View的大小
4. 在xml布局文件中配置
可能需要重写的方法:
测量:onMeasure 设置自己显示在屏幕上的宽高 在重写这个方法时,必须调用setMeasuredDimension(int, int)来存储测量得到的宽度和高度值
布局:onLayout 设置自己显示在屏幕上的位置(只有在自定义ViewGroup中才用到) 需要调用各自的layout(int, int, int, int)方法绘制:onDraw 控制显示在屏幕上的样子(自定义viewgroup时不需要这个)
View和ViewGroup的区别
1.他们都需要进行测量操作
2.ViewGroup主要是控制子view如何摆放,所以必须实现onLayout
View没有子view,所以不需要onLayout方法,但是必须实现onDraw
自定义控件实际操作:
1、创建类继承View
2、重写两个构造器
3、重写
onMeasure并调用setMeasuredDimension方法设置控件的宽和高
onDraw 绘制自己显示在屏幕上的样子
4、定义操作控件的方法
a、设置开关块的图片
b、设置开关背景的图片
c、设置更改开关状态的方法
5、定义onTouchEvent事件
6、定义接口对外开关状态
效果
定义View
1、创建类继承View
2、重写两个构造器
3、重写
onMeasure并调用setMeasuredDimension方法设置控件的宽和高
onDraw 绘制自己显示在屏幕上的样子
4、定义操作控件的方法
a、设置开关块的图片
b、设置开关背景的图片
c、设置更改开关状态的方法
public class MySwitch extends View {private SwitchState sState; // 开关状态private Bitmap slideBitmap;private Bitmap switchBitmap;/** * 如果自定义的View只是在布局文件中使用,只需要重写这个构造方法 * * @param context * @param attrs */public MySwitch(Context context, AttributeSet attrs) {super(context, attrs);}/** * 如果自定义的View是在Java代码中动态的new出来,需要重写这个构造方法 * * @param context */public MySwitch(Context context) {super(context);}/** * 设置活动块的图片 */public void setSlideBackgroudResource(int slideBackground) {// 将资源文件转换为BitmapslideBitmap = BitmapFactory.decodeResource(getResources(),slideBackground);}/** * 设置switch的图片 * * @param switchBackground */public void setSwitchBackgroundResource(int switchBackground) {// 将资源文件转换为BitmapswitchBitmap = BitmapFactory.decodeResource(getResources(),switchBackground);}/** * Switch开关状态的枚举 * * @author Denny * @date 2016-4-25 */public enum SwitchState {OPEN, CLOSE}/** * 设置Switch开关状态 * * @param open */public void setSwitchState(SwitchState open) {sState = open;}/** * 设置当前控件在屏幕上的宽和高 */@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);// 设置当前View的大小 这个方法决定了当前View的大小setMeasuredDimension(switchBitmap.getWidth(), switchBitmap.getHeight());}/** * 绘制自己显示在屏幕上的样子 */@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);// 1.在某一个位置 绘制背景图片// left:图片的左边的x坐标// top:图片的顶部的y坐标canvas.drawBitmap(switchBitmap, 0, 0, null);// 2.绘制滑动块图片//当抬起的时候 绘制滑动块的位置// 根据SwitchState 确定滑动块的位置// 如果滑动块在左边的话 left:0 top:0// 如果滑动块在右边:left : 背景的宽 - 滑动块的宽 top:0if (sState == SwitchState.OPEN) {canvas.drawBitmap(slideBitmap, switchBitmap.getWidth()- slideBitmap.getWidth(), 0, null);} else if (sState == SwitchState.CLOSE) {canvas.drawBitmap(slideBitmap, 0, 0, null);}}}
5、定义onTouchEvent事件
1、Android中有两套坐标:
2、开关要有两种操作
2.1定义成员
定义一个变量用于判断是根据滑动还是 根据状态进行 操作
private boolean isSliding = false;
2.2当onTouchEvent事件中处理 滑动块滑动 操作
@Overridepublic boolean onTouchEvent(MotionEvent event) {// 获取当前的x点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 centernX = switchBitmap.getWidth() / 2;//判断当前x值和中间线的大小 更改SwitchStateif( currentX >= centernX){//openif(sState != SwitchState.OPEN){sState = SwitchState.OPEN;}}else{//closeif(sState != SwitchState.CLOSE){sState = SwitchState.CLOSE;}}break;}// 调用invalidate()方法,请求重新draw()invalidate();return true;}
protected void onDraw(Canvas canvas) {super.onDraw(canvas);// 1.在某一个位置 绘制背景图片// left:图片的左边的x坐标// top:图片的顶部的y坐标canvas.drawBitmap(switchBitmap, 0, 0, null);// 2.绘制滑动块图片//如果是滑动的话 则根据currentX来进行操作if(isSliding ){//当鼠标移动到slideBitmap一半的时候才会有响应int left = currentX - slideBitmap.getWidth() / 2;//如果leftif (left < 0) {left = 0;}int maxX = switchBitmap.getWidth() - slideBitmap.getWidth();if (left > (maxX)) {left = maxX;}canvas.drawBitmap(slideBitmap, left, 0, null);}else{//当抬起的时候 绘制滑动块的位置// 根据SwitchState 确定滑动块的位置// 如果滑动块在左边的话 left:0 top:0// 如果滑动块在右边:left : 背景的宽 - 滑动块的宽 top:0if (sState == SwitchState.OPEN) {canvas.drawBitmap(slideBitmap, switchBitmap.getWidth()- slideBitmap.getWidth(), 0, null);} else if (sState == SwitchState.CLOSE) {canvas.drawBitmap(slideBitmap, 0, 0, null);}}}
6、定义接口对外开关状态
a、定义接口对外开关状态的方法b、定义根据接口来更改状态的方法
public interface OnSwitchStateChangedListern{void onSwitchStateChenged(SwitchState state);}private OnSwitchStateChangedListern listern;public void setOnSwitchStateChangedListern(OnSwitchStateChangedListern listern) {this.listern = listern;}
public boolean onTouchEvent(MotionEvent event) {// 获取当前的x点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 centernX = switchBitmap.getWidth() / 2;//判断当前x值和中间线的大小 更改SwitchStateif( currentX >= centernX){//openif(sState != SwitchState.OPEN){sState = SwitchState.OPEN;if(listern != null){listern.onSwitchStateChenged(sState);}}}else{//closeif(sState != SwitchState.CLOSE){sState = SwitchState.CLOSE;if(listern != null){listern.onSwitchStateChenged(sState);}}}break;}// 调用invalidate()方法,请求重新draw()invalidate();return true;}
使用
布局文件
<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.example.togbutton.view.MySwitch android:id="@+id/ms_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" /></RelativeLayout>
Java代码
public class MainActivity extends Activity {private MySwitch mySwitch;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mySwitch = (MySwitch) findViewById(R.id.ms_btn);// 设置滑动块的背景图片mySwitch.setSlideBackgroudResource(R.drawable.slide_button);// 设置Switch背景图片mySwitch.setSwitchBackgroundResource(R.drawable.switch_background);// 设置更改Switch的开关状态mySwitch.setSwitchState(SwitchState.OPEN);// 设置Switch的开关状态监听器mySwitch.setOnSwitchStateChangedListern(new OnSwitchStateChangedListern() {@Overridepublic void onSwitchStateChenged(SwitchState state) {Toast.makeText(MainActivity.this,state == SwitchState.OPEN ? "开启" : "关闭", 0).show();}});}}
- Android学习(43) -- 自定义控件(7) 滑动开关
- 由浅入深学习自定义控件(4)-滑动开关slidemenu
- Android自定义控件之旅(一)滑动开关
- 【Android】自定义控件实现可滑动的开关(switch)
- Android自定义控件---滑动开关
- android自定义滑动开关控件,自定义view
- Android:android自定义滑动开关控件
- android自定义控件滑动开关详解
- Android自定义控件—滑动开关
- Android自定义控件(二) 滑动开关
- android 纯粹自定义控件 滑动开关
- Android自定义控件之滑动开关
- Android进阶自定义控件之滑动开关
- 自定义控件:滑动开关
- Android复习笔记(14)-自定义控件(1)-滑动开关
- 自定义view(滑动开关)
- Android滑动开关控件
- android自定义滑动开关
- 如何捕获系统应用程序的界面&&调用系统的下载管理(Downloads)界面
- 帧率、码流与分辨率相关知识
- matlab通过两点画线问题&&plot,line的用法和区别。
- nodejs在windows下的安装配置(使用NVM的方式)
- aa4.0
- Android学习(43) -- 自定义控件(7) 滑动开关
- diy作品——3D扫描+打印
- C#利用POST实现杭电oj的AC自动机器人,AC率高达50%~~
- 深入理解JVM(六)——JVM性能调优实战
- 加速Android Studio/Gradle构建
- Quartus II 中调用ModelSim-Altera 报错问题
- JVM基础(三) JVM内存管理
- 免费科研资料下载网站记录
- 对象的引用及传递