標籤:android
由於Android並未提供滑動開關之類的組件,所以我們需要自己去實現一個自訂的視圖組件來實現滑動開關效果。
這裡有一個範例程式碼,它包括三個類:開關組件視圖、狀態監聽介面、MainActivity
我們先來看看整個demo的:
我們先來看看視圖組件的完整代碼,代碼都已經注釋:
package com.bear.swtichbuttondemo;import java.util.ArrayList;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Matrix;import android.graphics.Paint;import android.graphics.Rect;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.view.View.OnTouchListener;/** * 自訂滑動開關 */public class MySwitchButton extends View implements OnTouchListener {private Bitmap switchOnBkg; // 開關開啟時的背景private Bitmap switchOffBkg; // 開關關閉時的背景private Bitmap slipSwitchButton; // 滑動開關的圖片private boolean isSlipping = false; // 是否正在滑動private boolean isSwitchOn = false; // 當前開關的狀態,true表示開啟,flase表示關閉private float previousX; // 手指按下時的水平座標xprivate float currentX; // 當前的水平座標Xprivate ArrayList<OnSwitchListener> onSwitchListenerList; // 開關監聽器列表public MySwitchButton(Context context, AttributeSet attrs) {super(context, attrs);init();}private void init() {this.setOnTouchListener(this); // 設定觸摸監聽器onSwitchListenerList = new ArrayList<OnSwitchListener>();}public void setImageResource(int switchBkg, int slipBtn) {switchOnBkg = BitmapFactory.decodeResource(this.getResources(),switchBkg);switchOffBkg = BitmapFactory.decodeResource(this.getResources(),switchBkg);slipSwitchButton = BitmapFactory.decodeResource(this.getResources(),slipBtn);}public void setSwitchState(boolean switchState) {this.isSwitchOn = switchState;this.invalidate();}public boolean getSwitchState() {return this.isSwitchOn;}public void setOnSwitchStateListener(OnSwitchListener listener){onSwitchListenerList.add(listener);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);Matrix matrix = new Matrix();Paint paint = new Paint();float leftSlipBtnX; // 滑動按鈕的左邊座標//畫開關的背景圖片canvas.drawBitmap(switchOnBkg, matrix, paint);if (isSlipping) {// 如果正在滑動if (currentX > switchOnBkg.getWidth()) {leftSlipBtnX = switchOnBkg.getWidth()- slipSwitchButton.getWidth();} else {leftSlipBtnX = currentX - slipSwitchButton.getWidth();}} else {//如果沒有滑動if (isSwitchOn) {leftSlipBtnX = switchOnBkg.getWidth()- slipSwitchButton.getWidth();} else {leftSlipBtnX = 0;}}//如果手指滑出了開關的範圍,應當這樣處理if (leftSlipBtnX < 0) {leftSlipBtnX = 0;} else if (leftSlipBtnX > switchOnBkg.getWidth()- slipSwitchButton.getWidth()) {leftSlipBtnX = switchOnBkg.getWidth() - slipSwitchButton.getWidth();}//在畫布上畫開關圖片canvas.drawBitmap(slipSwitchButton, leftSlipBtnX, 0, paint);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);setMeasuredDimension(switchOnBkg.getWidth(), switchOnBkg.getHeight());}@Overridepublic boolean onTouch(View v, MotionEvent event) {//擷取觸摸動作類型int action = event.getAction();switch (action) {case MotionEvent.ACTION_MOVE://如果現在處於手指一動狀態currentX = event.getX();break;case MotionEvent.ACTION_DOWN://如果現在手指剛剛按上螢幕狀態isSlipping = true;break;case MotionEvent.ACTION_UP://如果現在手指剛剛離開螢幕狀態isSlipping = false;boolean previousState = isSwitchOn;if (event.getX() > (switchOnBkg.getWidth() / 2)) {isSwitchOn = true;} else {isSwitchOn = false;}//調用介面回調方法,將開關狀態通知給監聽對象if(previousState != isSwitchOn){if(onSwitchListenerList.size() > 0){for(OnSwitchListener listener : onSwitchListenerList){listener.onSwitched(isSwitchOn);}}}break;default:break;}this.invalidate();return true;}}
我們再來看看開關狀態監聽介面代碼,如下:
package com.bear.swtichbuttondemo;public interface OnSwitchListener {public abstract void onSwitched(boolean isSwitchOn);}
最後是我們的Activity中的代碼,這裡需要傳兩張圖片給自訂群組件,當然你也可以傳兩張自己做好的圖片,代碼如下:
package com.bear.swtichbuttondemo;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.Toast;public class MainActivity extends Activity {private MySwitchButton mySwitchButton;private Button myBtn;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);setupViews();}private void setupViews() {mySwitchButton = (MySwitchButton) findViewById(R.id.my_switch_button);//傳圖片給自訂群組件mySwitchButton.setImageResource(R.drawable.switch_bkg_switch,R.drawable.switch_btn_slip);myBtn = (Button) findViewById(R.id.button);//設定開關狀態監聽mySwitchButton.setOnSwitchStateListener(new OnSwitchListener() {@Overridepublic void onSwitched(boolean isSwitchOn) {if (isSwitchOn) {Toast.makeText(MainActivity.this, "開關開啟",Toast.LENGTH_SHORT).show();} else {Toast.makeText(MainActivity.this, "開關關閉",Toast.LENGTH_SHORT).show();}}});myBtn.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {boolean isOn = mySwitchButton.getSwitchState();mySwitchButton.setSwitchState(!isOn);}});}}
最後附上代碼的:
Android之實現滑動開關組件
Android之實現滑動開關組件