思路:
自定义View,重写和封装好方法,外部直接调用
- 三个构造方法
- onMeasure -> onLayout -> onDraw 重写这些方法, 实现自定义控件(测量、在这个方法里指定自己的宽高;布局、摆放;绘制内容)
- 触摸事件onTouchEvent(MotionEvent event)
封装自定义方法 - 状态更新监听,内部接口OnSwitchStateUpdateListener,对外提供按钮状态数据,并定义方法方便外部调用setOnSwitchStateUpdateListener
自定义属性,更方便书写
activity
package com.maker_huige.activity;
import android.app.Activity;
import android.os.Bundle;
import android.widget.Toast;
import com.maker_huige.textapplication.R;
import com.maker_huige.ui.ToggleView;
/**
* Created by maker_huige on 2016/12/26.
*/
public class ToggleActivity extends Activity {
ToggleView toggleView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_toggle);
initUI();
toggleView.setOnSwitchStateUpdateListener(new ToggleView.OnSwitchStateUpdateListener() {
@Override
public void onStateUpdate(boolean state) {
Toast.makeText(getApplicationContext(),"state:" + state,Toast.LENGTH_SHORT).show();
}
});
}
private void initUI() {
toggleView = (ToggleView) findViewById(R.id.toggleview);
//用自定义属替代了
/*toggleView.setSwitchBackgroundResource(R.mipmap.switch_background);
toggleView.setSlideButtonResource(R.mipmap.slide_button);*/
}
}
自定义View
package com.maker_huige.ui;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
/**
* Created by maker_huige on 2016/12/26.
*/
public class ToggleView extends View {
boolean isTouchMode = false;
Bitmap bitmap_switch_background;
Bitmap bitmap_slide_button;
boolean mSwitchState = true;
float currentX;
private OnSwitchStateUpdateListener onSwitchStateUpdateListener;
public ToggleView(Context context) {
super(context);
init(null);
}
public ToggleView(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs);
}
public ToggleView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(attrs);
}
private void init(AttributeSet attrs) {
String namespace = "http://schemas.android.com/apk/res-auto";
int switch_background = attrs.getAttributeResourceValue(namespace, "switch_background", -1);
//通过自定义属性数组attrs,获取指定命名空间、指定属性名的参数id,需要提供默认值
int slide_button = attrs.getAttributeResourceValue(namespace, "slide_button", -1);
mSwitchState =attrs.getAttributeBooleanValue(namespace,"switch_state",false);
setSwitchBackgroundResource(switch_background);
setSlideButtonResource(slide_button);
}
/**
* 自定义组件的三个方法,执行onResum后执行
* onMeasure测量
* onLayout布局
* onDrow绘图
* view需要两个
* viewGrowp需要三个
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(bitmap_switch_background.getWidth(),bitmap_switch_background.getHeight());
}
@Override
protected void onDraw(Canvas canvas) {
Paint paint = new Paint();
canvas.drawBitmap(bitmap_switch_background,0,0,paint);
if(isTouchMode){
//当用户触摸到位置画滑块
float newLeft = currentX;
newLeft = currentX -bitmap_slide_button.getWidth() / 2.0f;
float maxLeft = bitmap_switch_background.getWidth()-bitmap_slide_button.getWidth();
if(newLeft < 0){
newLeft = 0;
}else {
newLeft = maxLeft;
}
canvas.drawBitmap(bitmap_slide_button,newLeft,0,paint);
}else {
if(mSwitchState){
canvas.drawBitmap(bitmap_slide_button,
bitmap_switch_background.getWidth()-bitmap_slide_button.getWidth(),
0,paint);
}else{
canvas.drawBitmap(bitmap_slide_button,0,0,paint);
}
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_MOVE:
currentX = event.getX();
break;
case MotionEvent.ACTION_DOWN:
isTouchMode = true;
currentX = event.getX();
break;
case MotionEvent.ACTION_UP:
currentX = event.getX();
isTouchMode = false;
boolean state = currentX > bitmap_switch_background.getWidth() / 2.0f;
if(state != mSwitchState && onSwitchStateUpdateListener !=null){
onSwitchStateUpdateListener.onStateUpdate(state);
}
mSwitchState = state;
break;
}
invalidate();
return true;
}
// 声明接口对象
public interface OnSwitchStateUpdateListener{
void onStateUpdate(boolean state);
}
// 添加设置接口对象的方法,外部进行调用
public void setOnSwitchStateUpdateListener(OnSwitchStateUpdateListener onSwitchStateUpdateListener) {
this.onSwitchStateUpdateListener = onSwitchStateUpdateListener;
}
//自定义方法,通过BitmapFactory用id获取到bitmap对象
public void setSwitchBackgroundResource(int switch_background) {
bitmap_switch_background = BitmapFactory.decodeResource(getResources(), switch_background);
}
public void setSlideButtonResource(int slide_button) {
bitmap_slide_button = BitmapFactory.decodeResource(getResources(), slide_button);
}
}
activity_toggle.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:itheima="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<com.maker_huige.ui.ToggleView
itheima:switch_background="@mipmap/switch_background"
itheima:slide_button="@mipmap/slide_button"
itheima:switch_state="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:id="@+id/toggleview"
/>
</RelativeLayout>
attrs.xml自定义属性
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="ToggleView">
<attr name="switch_background" format="reference"/>
<attr name="slide_button" format="reference"/>
<attr name="switch_state" format="boolean"/>
</declare-styleable>
</resources>