今天自己做了一个关于自定义控件的小Demo,下面是思路
自定义控件
* 怎么自定义?android每一个控件和布局都是继承自View,写一个类继承
* 构造函数 两个(java,布局文件中)+使用样式资源的时候调用,0
* 怎么用呢?全类名去引用
* 需要两张图片,复制进去,,,,findViewById
* 设置背景图片,设置滑动块图片,设置开关选中状态(注释),,,,三个方法创建出来
* 这三个都需要成员变量记录下来,,,三个成员变量记录bitmap和state,,,保留下来
* 跑起来,,,白板,,,那么就需要画出来自定义控件
#android中view绘制流程(讲一下android中自定义控件流程)
* measuer layout draw
* 对应着三个方法,测量宽高,布局(对自己的子控件进行排版布局操作,这里不需要),绘制
* 1.在--方法中测量并设置自己的宽和高
* 2.绘制出来
#步骤
* 当前控件需要测量时 触发的方法,,,其实跟背景图片宽和高一样setMeasuredDemien(宽,高)
* onDraw,,,点super为空---当前控件需要绘制时,调用,,,当前使用cavas画的都会显示
* 1.平铺背景图片
* cavas.drawBitmap(),,,讲为什么是0,0?
* 2.根据当前状态绘制滑动块位置(都是在看左边这条线,不要看右边)
* //当前开关打开状态,画在右边
* 画图讲解画的位置
* //关闭状态,左边
* 3.拖动操作 onTouchEvent(true,自己处理触摸事件)
* down move up 记录x值
* 滑动位置需要重绘,手动触发onDraw方法重绘,很简单 调invilate()
* 1,2之间,,,根据当前x值来动态修改滑块位置(把当前x值付给left,,,两个问题(移出去,不在中间))
* 先注释2.
* 中间:x-当前控件的一半
* 移出去:左边---left<0,=0;右边:还是看左边,left>蓝线,=蓝线
* 当松开时,处理当前的状态(触摸时根据位置,松开时根据状态),,,,isTouching记录(down为true,,,up为false)
* 1的.下面判断,,,剪切进去代码
* 还要在up中,进行判断偏向于哪一边(根据控件的中心线与按下的点的位置),,,去更改state
<com.togglebuttondemo.ToggleButtonCustom
android:id="@+id/togglebutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
/>
主Activity代码:
public class MainActivity extends AppCompatActivity {
private ToggleButtonCustom toggleButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//获得自定义控件控件
toggleButton = (ToggleButtonCustom) findViewById(R.id.togglebutton);
//设置背景图片
toggleButton.setBackgroundPic(R.drawable.switch_background);
//设置上边图片
toggleButton.setForePic(R.drawable.slide_button_background);
//记录状态
toggleButton.setState(false);
}
}
自定义控件类
public class ToggleButtonCustom extends View {
private Bitmap foreBitmap;
private boolean state=false;
private Bitmap backBitmap;
private boolean isTouching;
private int currentX;
//java代码中创建时使用此方法
public ToggleButtonCustom(Context context) {
super(context);
}
//xml布局文件中使用
public ToggleButtonCustom(Context context, AttributeSet attrs) {
super(context, attrs);
}
//有style布局文件中使用
public ToggleButtonCustom(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
//背景
public void setBackgroundPic(int switch_background) {
backBitmap = BitmapFactory.decodeResource(getResources(),switch_background);
}
//上面的图片
public void setForePic(int slide_button_background) {
foreBitmap = BitmapFactory.decodeResource(getResources(),slide_button_background);
}
//状态
public void setState(boolean b) {
state=b;
}//目前什么都没有,还没有绘制
//控件的大小
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//设置宽高
setMeasuredDimension(backBitmap.getWidth(), backBitmap.getHeight());
}
//绘制控件
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//平铺背景图片
canvas.drawBitmap(backBitmap,0,0,null);
//如果出现按钮移出去和不在中间,加上如下代码
// if(isTouching){
// //获得最左边位置
// int left=currentX-foreBitmap.getWidth()/2;
// if(left<0){
// left=0;
// }else if(left>backBitmap.getWidth()-foreBitmap.getWidth()){
// left=backBitmap.getWidth()-foreBitmap.getWidth();
// }
// canvas.drawBitmap(foreBitmap,0,0,null);
// }else{
// if(state){
// //右边
// canvas.drawBitmap(foreBitmap,backBitmap.getWidth()-foreBitmap.getWidth(),0,null);
// }else{
// //左边
// canvas.drawBitmap(foreBitmap,0,0,null);
// }
// }
if(state){
//右边
canvas.drawBitmap(foreBitmap,backBitmap.getWidth()-foreBitmap.getWidth(),0,null);
}else{
//左边
canvas.drawBitmap(foreBitmap,0,0,null);
}
}
//触摸控件时调用的方法
//三种状态
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
isTouching=true;
//当前触摸位置
currentX = (int) event.getX();
break;
case MotionEvent.ACTION_MOVE:
isTouching=true;
currentX = (int) event.getX();
break;
case MotionEvent.ACTION_UP:
isTouching=false;
currentX = (int) event.getX();
<span style="color:#ff6666;">//判断开关状态
state=currentX>backBitmap.getWidth()/2;//如果大于背景宽度的一半,说明是开的状态state=true</span>
break;
}
<span style="color:#ff6666;"> //重新绘制控件。自动调用onDraw();
invalidate();</span>
return true;
}
}
效果图