---恢复内容开始---
滑动开关--------
自定义控件步骤:
测量: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();
}
}
});
}
}