继承View类方式(自定义开关效果案例)

—————————————————-简单的效果图————————————————————————–

activity_main.xml

<RelativeLayout xmlns:android=""xmlns:tools=""android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity" ><com.atguigu.mytogglebutton.MyToggleViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"/></RelativeLayout>MainActivity.java

package com.atguigu.mytogglebutton;import android.os.Bundle;import android.app.Activity;import android.view.Menu;public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}}MyToggleView.java

package com.atguigu.mytogglebutton;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;/** * 设置滑动效果 * 1、 手指按下记录坐标 * 2、来到新坐标记录下 * 3、计算偏移量 * 4、依据偏移量移动按钮 * 5、屏蔽非法值 * 6、重新初始化初始值 */public class MyToggleView extends View implements View.OnClickListener {// true:开的状态 false:关闭状态(默认关闭状态)private boolean isOpened = false;// 画笔-辅助工具private Paint paint;// 背景图片private Bitmap backgroudbitmap;private Bitmap slidingbitmap;// 滑动按钮距离左边的距离private float sledingLeft;// 滑动按钮距离左边的最大距离private float maxLeft;/** * 自定义控件的构造方法–带样式 */public MyToggleView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);initView();}/** * 系统规定,,在布局文件使用View,实例化的时候只用带有两个参数的构造方法 */public MyToggleView(Context context, AttributeSet attrs) {super(context, attrs);initView();}/** * 通常在代码中实例化的时候使用 */public MyToggleView(Context context) {super(context);initView();}/** * 初始化View */private void initView() {// 创建画笔paint = new Paint();// 设置抗锯齿paint.setAntiAlias(true);// 创建背景图片backgroudbitmap = BitmapFactory.decodeResource(getResources(),R.drawable.switch_background);slidingbitmap = BitmapFactory.decodeResource(getResources(),R.drawable.slide_button);// 滑动按钮距离左边的最大距离maxLeft = backgroudbitmap.getWidth() – slidingbitmap.getWidth();// 设置点击事件MyToggleView.this.setOnClickListener(this);}/** * 执行的主要方法: * 1.构造 * 2.测量-onMeasure();一般是View的时候测量 * 3.指定view的大小和位置:onLayout(); * 一般View用不到,但是如果当前View继承的是ViewGroup,一定要实现,有义务指定孩子的位置和大小。 * 4.绘制-onDraw(); * 5、onTouchEvent() *//** * 1.View本身大小多少,这由onMeasure()决定; * 2.View在ViewGroup中的位置如何,这由onLayout()决定 * 3.绘制View,onDraw()定义了如何绘制这个View */@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {// 指定大小setMeasuredDimension(backgroudbitmap.getWidth(),backgroudbitmap.getHeight());}/** * 绘制 */@Overrideprotected void onDraw(Canvas canvas) {// canvas.drawBitmap(bitmap, left, top, paint)左上坐标(从左上顶点开始画)canvas.drawBitmap(backgroudbitmap, 0, 0, paint);canvas.drawBitmap(slidingbitmap, sledingLeft, 0, paint);}// 起始的X轴的坐标private float startX;// 历史的X轴的坐标private float lastX;/** * true:点击事件生效触摸事件不生效 false:点击事件不生效,触摸事件生效 */private boolean isClickEnbale = false;/** * 触摸事件 */@Overridepublic boolean onTouchEvent(MotionEvent event) {super.onTouchEvent(event);switch (event.getAction()) {case MotionEvent.ACTION_DOWN:// 按下// 1.手指按下的坐标lastX = startX = event.getX();// 手指按下时,设置状态为点击事件生效,触摸事件不生效isClickEnbale = true;break;case MotionEvent.ACTION_MOVE:// 滑动// 2.来到新的坐标float newX = event.getX();// 3.计算偏移量float distanceX = newX – startX;// 从开始到现在滑动的距离if (Math.abs(newX – lastX) > 5) {// 如果偏移量大于5,设状态为点击事件失效,触摸事件生效isClickEnbale = false;}// 重新绘制界面flunshView(distanceX);// 5.重新记录初始值startX = event.getX();break;case MotionEvent.ACTION_UP:// 离开// 如果触摸事件生效,点击事件失效if (!isClickEnbale) {// 如果滑动按钮距离左边的距离大于滑动按钮距离左边最大距离的一半,就设置状态为开if (sledingLeft > maxLeft / 2) {isOpened = true;} else if (sledingLeft <= maxLeft / 2) {// 如果滑动按钮距离左边的距离小于滑动按钮距离左边最大距离的一半,就设置状态为关isOpened = false;}// 重新绘制界面flushViewState();}break;default:break;}return true;}/** * 屏蔽非法值和根据位置重新绘制 */private void flunshView(float distanceX) {sledingLeft += distanceX;if (sledingLeft < 0) {sledingLeft = 0;}if (sledingLeft > maxLeft) {sledingLeft = maxLeft;}// 4.根据最新的位置绘制invalidate();}/** * 点击事件 */@Overridepublic void onClick(View v) {// 如果是点击状态生效,触摸事件失效if (isClickEnbale) {flushViewState();// 点击后,如果是状态时开的话就设置为关,如果是关的状态就设置为开isOpened = !isOpened;}}private void flushViewState() {// 开的状态if (isOpened) {// 开的状态sledingLeft = maxLeft;} else {// 关的状态sledingLeft = 0;}invalidate();// 在主线程中执行 导致onDraw执行}}

穷则思变,差则思勤!没有比人更高的山没有比脚更长的路。

继承View类方式(自定义开关效果案例)

相关文章:

你感兴趣的文章:

标签云: