自定義控件的步驟:
測量:onMeasure 設定自己顯示在螢幕上的寬高
布局:onLayout 設定自己顯示在螢幕上的位置(隻有在自定義ViewGroup中才用到)
繪制:onDraw 控制顯示在螢幕上的樣子(自定義viewgroup時不需要這個)
以下是自定義的滑動開關:
使用時隻要設定滑動塊的背景圖檔setSlideBackgroundResource()和滑動開關的背景圖檔setSwitchBackgroundResource(R.drawable.switch_background)即可。
其中setToggleState()方法是設定滑動開關的狀态:ToggleState.Open 開啟狀态ToggleState.Close關閉狀态。
setOnToggleStateChangeListener()可以監聽滑動塊狀态的改變。
代碼如下:
MainActivity:
public class MainActivity extends Activity {
private ToggleButton toggleButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toggleButton = (ToggleButton) findViewById(R.id.toggleButton);
toggleButton.setSlideBackgroundResource(R.drawable.slide_button_background);
toggleButton.setSwitchBackgroundResource(R.drawable.switch_background);
toggleButton.setToggleState(ToggleState.Open);
toggleButton.setOnToggleStateChangeListener(new OnToggleStateChangeListener() {
@Override
public void onToggleStateChange(ToggleState state) {
Toast.makeText(MainActivity.this, state == ToggleState.Open ? "開啟" : "關閉", 0).show();
}
});
}
}
自定義ToggleButton的代碼:
public class ToggleButton extends View {
private ToggleState toggleState = ToggleState.Open;// 開關的狀态
private Bitmap slideBg;
private Bitmap switchBg;
private boolean isSliding = false;
private OnToggleStateChangeListener listener;
private int currentX;// 目前觸摸點的X坐标
/**
* 如果view隻是在布局檔案中使用,隻需要重寫這個構造方法
*
* @param context
* @param attrs
*/
public ToggleButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
/**
* 如果view需要在java代碼中動态new出來,使用的是這個構造方法
*
* @param context
*/
public ToggleButton(Context context) {
super(context);
}
/**
* 設定滑動塊的背景圖檔
*
* @param slideButtonBackground
* 圖檔的資源id
*/
public void setSlideBackgroundResource(int slideButtonBackground) {
slideBg = BitmapFactory.decodeResource(getResources(), slideButtonBackground);
}
/**
* 設定滑動開關的背景圖檔
*
* @param switchBackground
* 圖檔的資源id
*/
public void setSwitchBackgroundResource(int switchBackground) {
switchBg = BitmapFactory.decodeResource(getResources(), switchBackground);
}
/**
* 使用枚舉定義兩個滑動開關的狀态
*
* @author Administrator
*
*/
public enum ToggleState {
Open, Close
}
/**
* 設定開關的狀态
*
* @param open
*/
public void setToggleState(ToggleState state) {
toggleState = state;
}
/**
* 設定目前控件顯示在螢幕上的寬高
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(switchBg.getWidth(), switchBg.getHeight());
}
/**
* 繪制控件顯示在螢幕上的樣子
*/
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 1.繪制背景圖檔
// left:圖檔的左邊的X坐标
// top:圖檔頂部的Y坐标
canvas.drawBitmap(switchBg, 0, 0, null);
// 2.繪制滑動塊的圖檔
if (isSliding) {
int left = currentX - slideBg.getWidth() / 2;
if (left < 0) {
left = 0;
}
if (left > (switchBg.getWidth() - slideBg.getWidth())) {
left = switchBg.getWidth() - slideBg.getWidth();
}
canvas.drawBitmap(slideBg, left, 0, null);
} else {
// 此時擡起,根據state去繪制滑動塊的位置
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;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
isSliding = false;
int centerX = switchBg.getWidth() / 2;// 開關的中點
if (currentX > centerX) {
// open
if (toggleState != ToggleState.Open) {
toggleState = ToggleState.Open;
if (listener != null) {
listener.onToggleStateChange(toggleState);
}
}
} else {
// close
if (toggleState != ToggleState.Close) {
toggleState = ToggleState.Close;
if (listener != null) {
listener.onToggleStateChange(toggleState);
}
}
}
break;
}
invalidate();// 重繪
return true;
}
public void setOnToggleStateChangeListener(OnToggleStateChangeListener listener) {
this.listener = listener;
}
public interface OnToggleStateChangeListener {
void onToggleStateChange(ToggleState state);
}
}
布局檔案:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.example.view.ToggleButton
android:id="@+id/toggleButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true" />
</RelativeLayout>
Demo位址: 點選打開連結