自定義滑動開關 - 新聞資訊 - 雲南小程序開發|雲南軟件開發|雲南網站建設-昆明融晨信息技術有限公司

159-8711-8523

雲南網建設/小程序開發/軟件開發

知識

不(bù)管是(shì)網站,軟件還是(shì)小程序,都要(yào / yāo)直接或間接能爲(wéi / wèi)您産生價值,我們在(zài)追求其視覺表現的(de)同時(shí),更側重于(yú)功能的(de)便捷,營銷的(de)便利,運營的(de)高效,讓網站成爲(wéi / wèi)營銷工具,讓軟件能切實提升企業内部管理水平和(hé / huò)效率。優秀的(de)程序爲(wéi / wèi)後期升級提供便捷的(de)支持!

您當前位置>首頁 » 新聞資訊 » 技術分享 >

自定義滑動開關

發表時(shí)間:2021-1-10

發布人(rén):融晨科技

浏覽次數:41


轉載請注明出(chū)處:http://blog.csdn.net/forwardyzk/article/details/42526343
當開發的(de)時(shí)候,使用開關的(de)時(shí)候,效果不(bù)能不(bù)滿足我們的(de)需求,要(yào / yāo)表現出(chū)滑動的(de)效果。我們就(jiù)可以(yǐ)自定義開關。
思路:
1.把開關分爲(wéi / wèi)兩部分,一部分是(shì)開關的(de)背景,另一部分是(shì)滑動按鈕。
2.測量開關的(de)長和(hé / huò)寬,當然是(shì)在(zài)onMeasure中進行處理
3.在(zài)onTouchEvent()根據觸摸開關進行滑動位置進行監聽,在(zài)onDraw()中進行繪畫。
  當然也(yě)要(yào / yāo)繪畫兩部分:開關背景和(hé / huò)滑動按鈕
4.對觸摸位置和(hé / huò)滑動位置進行判斷
   1.觸摸位置要(yào / yāo)在(zài)開關背景的(de)範圍内。
   2.在(zài)繪畫的(de)時(shí)候,滑動按鈕不(bù)能超出(chū)開關背景的(de)範圍。


在(zài)onTouchEvent()方法中調用invalidate()方法,會根據位置的(de)變化不(bù)斷的(de)在(zài)onDraw()方法中繪畫按鈕。


設置開關的(de)背景和(hé / huò)滑動按鈕
onXPosition和(hé / huò)offXPosition爲(wéi / wèi)開關狀态的(de)變化之(zhī)間,滑動按鈕左側的(de)X坐标不(bù)能必須在(zài)兩者之(zhī)間。

public void setImageResource(int switchOnBg, int slipBtn) {
		Log.d(TAG, "setImageResource");
		switch_bg = BitmapFactory.decodeResource(getResources(), switchOnBg);
		slip_Btn = BitmapFactory.decodeResource(getResources(), slipBtn);
		onXPosition = switch_bg.getWidth() - slip_Btn.getWidth();
		offXPosition = 0;
	}

在(zài)OnTouchEvent()中監聽手勢滑動的(de)位置

public boolean onTouchEvent(MotionEvent event) {
		switch (event.getAction()) {
		// 按下,判斷按下的(de)位置在(zài)開關上(shàng),才可以(yǐ)做後面的(de)操作
		case MotionEvent.ACTION_DOWN:
			Log.d(TAG, "MotionEvent.ACTION_DOWN");
			if (event.getX() > switch_bg.getWidth()
					|| event.getY() > switch_bg.getHeight()) {
				return false;
			}

			isSlipping = true;
			currentX = event.getX();
			break;
		// 滑動,記錄當前的(de)按下的(de)位置
		case MotionEvent.ACTION_MOVE:
			Log.d(TAG, "MotionEvent.ACTION_MOVE");
			currentX = event.getX();
			break;
		// 松開,設置開關的(de)監聽器,設置開關的(de)狀态
		case MotionEvent.ACTION_UP:
			Log.d(TAG, "MotionEvent.ACTION_UP");
			isSlipping = false;
			// 松開前開關的(de)狀态
			boolean previousSwitchState = isSwitchOn;
			// 如果當前的(de)位置在(zài)開關背景中間位置的(de)右側,表示的(de)是(shì)開的(de)狀态,否則爲(wéi / wèi)關
			if (event.getX() >= (switch_bg.getWidth() / 2)) {
				isSwitchOn = true;
			} else {
				isSwitchOn = false;
			}

			// 如果設置了(le/liǎo)監聽器,則調用此方法
			if (onSwitchListener != null && (previousSwitchState != isSwitchOn)) {
				onSwitchListener.onSwitched(isSwitchOn);
			}
			break;

		default:
			break;
		}

		// 重新繪制控件
		invalidate();// 不(bù)要(yào / yāo)忘了(le/liǎo)重繪開關
		return true;
	}

在(zài)最後不(bù)要(yào / yāo)忘了(le/liǎo)調用invalidate(),否則不(bù)會進行繪畫開關。
判斷了(le/liǎo)觸摸的(de)範圍必須在(zài)開關上(shàng)


在(zài)onDraw()繪畫開關

protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		super.onDraw(canvas);
		Log.d(TAG, "onDraw");
		Matrix matrix = new Matrix();
		Paint paint = new Paint();
		// 滑動按鈕的(de)X方向左側坐标
		float left_SlipBtn;
		// 把開關的(de)背景畫出(chū)來(lái)
		canvas.drawBitmap(switch_bg, matrix, paint);
		// 判斷當前是(shì)否正在(zài)滑動
		if (isSlipping) {
			if (currentX > switch_bg.getWidth()) {
				left_SlipBtn = switch_bg.getWidth() - slip_Btn.getWidth();
			} else {
				// 保持滑動的(de)位置是(shì)滑動按鈕的(de)中間位置
				left_SlipBtn = currentX - slip_Btn.getWidth() / 2;
			}
		} else {
			// 根據當前的(de)開關狀态設置滑動按鈕的(de)位置
			if (isSwitchOn) {
				left_SlipBtn = onXPosition;
			} else {
				left_SlipBtn = offXPosition;
			}
		}

		// 對滑動按鈕左側和(hé / huò)右側進行判斷,不(bù)能超過背景的(de)範圍
		if (left_SlipBtn < 0) {
			left_SlipBtn = 0;
		} else if (left_SlipBtn > switch_bg.getWidth() - slip_Btn.getWidth()) {
			left_SlipBtn = switch_bg.getWidth() - slip_Btn.getWidth();
		}
		// 繪制滑動開關
		canvas.drawBitmap(slip_Btn, left_SlipBtn, 0, paint);
	}

canvas.drawBitmap(switch_bg, matrix, paint)繪畫開關背景
canvas.drawBitmap(slip_Btn, left_SlipBtn, 0, paint)繪畫滑動按鈕

滑動按鈕滑動的(de)時(shí),保持不(bù)能超過開關背景的(de)範圍,保持點擊的(de)位置在(zài)滑動按鈕的(de)中間位置。
使用步驟:
activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/main_button_switch"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_centerVertical="true"
        android:layout_marginLeft="15dp"
        android:paddingBottom="3dp"
        android:paddingLeft="25dp"
        android:paddingRight="25dp"
        android:paddingTop="3dp"
        android:text="切換狀态"
        android:textSize="15sp" />

    <com.example.view.MySlipSwitch
        android:id="@+id/main_myslipswitch"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:layout_marginRight="20dp" />

</RelativeLayout>

在(zài)MainActivity.java中使用
public class MainActivity extends Activity {

	private Button switch_Btn;
	private MySlipSwitch slipswitch_MSL;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		initView();
		setListener();
	}

	public void initView() {
		slipswitch_MSL = (MySlipSwitch) findViewById(R.id.main_myslipswitch);
		slipswitch_MSL.setImageResource(R.drawable.switch_bkg_switch,
				R.drawable.switch_btn_slip);
		slipswitch_MSL.setSwitchState(true);
		switch_Btn = (Button) findViewById(R.id.main_button_switch);
	}

	public void setListener() {
		//設置開關狀态變化監聽器
		slipswitch_MSL.setOnSwitchListener(new OnSwitchListener() {

			@Override
			public void onSwitched(boolean isSwitchOn) {
				// TODO Auto-generated method stub
				if (isSwitchOn) {
					Toast.makeText(getApplicationContext(), "開關已經開啓", 0).show();
				} else {
					Toast.makeText(getApplicationContext(), "開關已經關閉", 0).show();
				}
			}
		});

		switch_Btn.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				slipswitch_MSL.setSwitchState(!slipswitch_MSL.getSwitchState());
				if (slipswitch_MSL.getSwitchState()) {
					Toast.makeText(getApplicationContext(), "開關已經開啓", 0).show();
				} else {
					Toast.makeText(getApplicationContext(), "開關已經關閉", 0).show();
				}
			}
		});

	}
}

點擊切換按鈕,獲取開關的(de)狀态
設置滑動開關狀态的(de)的(de)監聽器,滑動的(de)位置影響到(dào)了(le/liǎo)開關的(de)狀态,有響應的(de)監聽。
源碼下載: http://download.csdn.net/detail/forwardyzk/8341363
效果圖:
[img]http://img.blog.csdn.net/20150108165542997?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZm9yd2FyZHl6aw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center






相關案例查看更多