---恢复内容开始---
滑动开关--------
自定义控件步骤:
测量:onMeasure 设置自己显示在屏幕上的宽高
布局:onLayout 设置自己显示在屏幕上的位置(只有在自定义ViewGroup中才用到)
绘制:onDraw 控制显示在屏幕上的样子(自定义viewgroup时不需要这个)
View和ViewGroup的区别
1.他们都需要进行测量操作
2.ViewGroup主要是控制子view如何摆放,所以必须实现onLayout
View没有子view,所以不需要onLayout方法,但是必须实现onDraw
然后要想你设计这个控件能够有哪些功能?
1.设置滑动开关的背景图片,
2.设置滑动开关的滑块图片,
3.设置滑动开关的状态,
然后有了这些功能需求就可以进行代码的编写,
这次我们要自定义一个view,所以要继承view,实现它的构造方法,然后要实现设置图片的两个方法,和设置开关状态的方法,这里开关状态用了枚举类型。
因为绘制的时候只能绘制bitmap类型,所以要进行转化
/** * 选择框的背景 * * @param icLauncher */ public void setSwitchBackgroundResource(int icLauncher) { switchBg = BitmapFactory.decodeResource(getResources(), icLauncher); } /** * 滑动按钮背景 * * @param icLauncher */ public void setSlideBackgroundResouce(int icLauncher) { slideBg = BitmapFactory.decodeResource(getResources(), icLauncher); } /** * 设置开关的初始状态 * * @param state */ public void setSlideStare(ToggleState state) { togglestate = state; }
然后要重写测量方法,就是背景图片的宽高
/** * 设置当前控件显示在屏幕上的宽高 */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // TODO Auto-generated method stub super.onMeasure(widthMeasureSpec, heightMeasureSpec); setMeasuredDimension(switchBg.getWidth(), switchBg.getHeight()); }
测量之后要进行绘制
首先绘制分为两种,
一种是滑动中绘制,
还有一种是不滑动根据设置的状态进行绘制
滑动中绘制:这个主要就是通过Touch事件来改变滑块距离左侧的值来进行绘制
@Override public boolean onTouchEvent(MotionEvent event) { //改变的值
currentX = (int) event.getX(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: break; // 松开的时候看当前X的值在哪里 case MotionEvent.ACTION_UP: break; case MotionEvent.ACTION_MOVE: break; } // 由它来调用ondraw方法 invalidate(); return true; }
绘制方法
/* * 设置在正中间 */ int left = currentX - slideBg.getWidth() / 2; if (left < 0) { left = 0; } else if (left >= (switchBg.getWidth() - slideBg.getWidth())) { left = switchBg.getWidth() - slideBg.getWidth(); }
另外一种就是不滑动根据状态绘制。首先要规定出状态,状态布尔值默认是false,然后当down变成true,当up时候重新变成false
// 绘制滑块 // 判断滑块的状态 // 打开 if (togglestate == ToggleState.Open) { canvas.drawBitmap(slideBg, switchBg.getWidth() - slideBg.getWidth(), 0, null); // 关闭 } else { canvas.drawBitmap(slideBg, 0, 0, null); }
完整代码
package com.example.tbtn.view; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; public class ToggleButton extends View { // 设置的状态 private ToggleState togglestate = ToggleState.Open; // 选择背景 private Bitmap switchBg; // 滑动按钮背景 private Bitmap slideBg; // 点击的X值 private int currentX = 0; // 是否滑动 private boolean isSliding = false; // 枚举类型 public enum ToggleState { Open, Close } /** * 布局文件引用调用 * * @param context * @param attrs */ public ToggleButton(Context context, AttributeSet attrs) { super(context, attrs); } /** * 代码使用调用 * * @param context */ public ToggleButton(Context context) { super(context); } /** * 选择框的背景 * * @param icLauncher */ public void setSwitchBackgroundResource(int icLauncher) { switchBg = BitmapFactory.decodeResource(getResources(), icLauncher); } /** * 滑动按钮背景 * * @param icLauncher */ public void setSlideBackgroundResouce(int icLauncher) { slideBg = BitmapFactory.decodeResource(getResources(), icLauncher); } /** * 设置开关的初始状态 * * @param state */ public void setSlideStare(ToggleState state) { togglestate = state; } /** * 设置当前控件显示在屏幕上的宽高 */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // TODO Auto-generated method stub super.onMeasure(widthMeasureSpec, heightMeasureSpec); setMeasuredDimension(switchBg.getWidth(), switchBg.getHeight()); } /** * 绘制 */ @Override protected void onDraw(Canvas canvas) { // TODO Auto-generated method stub super.onDraw(canvas); // left 距图片左侧 top 距图片上部 canvas.drawBitmap(switchBg, 0, 0, null); if (isSliding) { /* * 设置按在正中间 */ int left = currentX - slideBg.getWidth() / 2; if (left < 0) { left = 0; } else if (left >= (switchBg.getWidth() - slideBg.getWidth())) { left = switchBg.getWidth() - slideBg.getWidth(); } canvas.drawBitmap(slideBg, left, 0, null); } else { // 绘制滑块 // 判断滑块的状态 // 打开 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; // 松开的时候看当前X的值在哪里 case MotionEvent.ACTION_UP: isSliding = false; // 图片中心点 int centerX = switchBg.getWidth() / 2; // 打开 if (currentX > centerX) { // 判断当前状态是否真的改变(就是滑动一半回去了) if (togglestate != ToggleState.Open) { togglestate = ToggleState.Open; // 设置回调借口 if (lisern != null) { lisern.onToggleChange(togglestate); } } // 关闭 } else { if (togglestate != ToggleState.Close) { togglestate = ToggleState.Close; // 设置回调借口 if (lisern != null) { lisern.onToggleChange(togglestate); } } } break; case MotionEvent.ACTION_MOVE: break; } // 由它来调用ondraw方法 invalidate(); return true; } private OnToggleChangeLisern lisern; public void setOnToggleChangeLisern(OnToggleChangeLisern lisern) { this.lisern = lisern; } // 回调接口 public interface OnToggleChangeLisern { void onToggleChange(ToggleState state); } }
Activity中使用
package com.example.tbtn; import com.example.tbtn.view.ToggleButton; import com.example.tbtn.view.ToggleButton.OnToggleChangeLisern; import com.example.tbtn.view.ToggleButton.ToggleState; import android.app.Activity; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.widget.Toast; public class MainActivity extends Activity { private ToggleButton tBtn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tBtn = (ToggleButton) findViewById(R.id.tbtn); tBtn.setSwitchBackgroundResource(R.drawable.togglebtn); tBtn.setSlideBackgroundResouce(R.drawable.ic_launcher); tBtn.setSlideStare(ToggleState.Open); tBtn.setOnToggleChangeLisern(new OnToggleChangeLisern() { @Override public void onToggleChange(ToggleState state) { if(state==ToggleState.Open){ Toast.makeText(MainActivity.this,"打开", 0).show(); }else{ Toast.makeText(MainActivity.this,"关闭", 0).show(); } } }); } }