91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android怎么實現自定義開關按鈕

發布時間:2022-05-05 16:18:45 來源:億速云 閱讀:218 作者:iii 欄目:開發技術

這篇文章主要講解了“Android怎么實現自定義開關按鈕”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Android怎么實現自定義開關按鈕”吧!

一、原理

我們在界面的某一個區域里放置一個背景圖A,這個圖片一邊為“開”,一邊為“關”,在這個圖片上放置一個圖片B,圖B大約為圖A的一半,恰好可以覆蓋掉圖A上的“開”或者“關”,當我們手指點擊圖片的時候,圖B在圖A上滑動,相應的覆蓋“開”或者“關”,這樣就實現了開關按鈕的效果。

二、實現

1、自定義View類MyToggle

這個類繼承自View類同時實現了OnTouchListener接口,這個類實現的功能比較多,我們分解來看這個類。

1)屬性字段

這個類中定義了不少的屬性字段,每個屬性字段的具體含義詳見代碼注釋

具體實現代碼如下:

//開關開啟的背景圖片  
private Bitmap bkgSwitchOn;  
//開關關閉的背景圖片  
private Bitmap bkgSwitchOff;  
//開關的滾動圖片  
private Bitmap btnSlip;  
//當前開關是否為開啟狀態  
private boolean toggleStateOn;  
//開關狀態的監聽事件  
private OnToggleStateListener toggleStateListener;  
//記錄開關·當前的狀態  
private boolean isToggleStateListenerOn;  
//手指按下屏幕時的x坐標  
private float proX;  
//手指滑動過程中當前x坐標  
private float currentX;  
//是否處于滑動狀態  
private boolean isSlipping;  
//記錄上一次開關的狀態  
private boolean proToggleState \= true;  
//開關開啟時的矩形  
private Rect rect\_on;  
//開關關閉時的矩形  
private Rect rect\_off;
2)覆寫View類的構造方法

我們在構造方法里完成的操作就是調用我們自己創建的init()方法

具體實現代碼如下:

public MyToggle(Context context) {  
  super(context);  
  init(context);  
}  
  
public MyToggle(Context context, AttributeSet attrs) {  
  super(context, attrs);  
  init(context);  
}
3)創建init方法

這個方法中實現的操作就是設置觸摸事件。

具體實現代碼如下:

//初始化方法  
private void init(Context context) {  
  setOnTouchListener(this);  
  
}
4)手指觸摸事件回調方法onTouch

這個方法是當手指操作手機屏幕時,Android自動回調的方法,我們在這個方法中,監聽手指的按下、移動和抬起事件,記錄手指當前的X坐標來判斷圖片B的移動方向,從而實現圖片B在圖片A上的移動來達到按鈕開和關的效果。

具體實現代碼如下:

@Override  
public boolean onTouch(View v, MotionEvent event) {  
  switch (event.getAction()) {  
  case MotionEvent.ACTION\_DOWN:  
    //記錄手指按下時的x坐標  
    proX \= event.getX();   
    currentX \= proX;  
    //將滑動標識設置為true  
    isSlipping \= true;  
    break;  
  
  case MotionEvent.ACTION\_MOVE:  
    //記錄手指滑動過程中當前x坐標  
    currentX \= event.getX();  
    break;  
  
  case MotionEvent.ACTION\_UP:  
    //手指抬起時將是否滑動的標識設置為false  
    isSlipping \= false;  
    //處于關閉狀態  
    if(currentX < bkgSwitchOn.getWidth() / 2 ){  
      toggleStateOn \= false;  
    } else { // 處于開啟狀態  
      toggleStateOn \= true;  
    }  
      
    // 如果使用了開關監聽器,同時開關的狀態發生了改變,這時使用該代碼  
    if(isToggleStateListenerOn && toggleStateOn != proToggleState){  
      proToggleState \= toggleStateOn;  
      toggleStateListener.onToggleState(toggleStateOn);  
    }  
    break;  
  }  
  invalidate();//重繪  
  return true;  
}
5)界面重繪方法onDraw

這個方法主要實現的是界面的重繪操作。

只要的思路是:

畫背景圖A:

    當前手指滑動X坐標currentX大于圖A寬度的一般時,按鈕背景為開啟狀態;

    當前手指滑動X坐標currentX小于圖A寬度的一般時,按鈕背景為關閉狀態;

記錄滑塊B的X坐標:

B滑動時:

   當前手指滑動X坐標currentX大于背景圖A的寬度,則B坐標為圖A寬度減去圖B寬度

   當前手指滑動X坐標currentX小于背景圖A的寬度,則B坐標為當前X坐標currentX減去滑塊寬度的一半

B靜止:

   當按鈕處于“開”狀態,則B坐標為“開”狀態的最左邊X坐標

   當按鈕處于“關”狀態,則B坐標為“關”狀態的最左邊X坐標

具體實現代碼如下:

@Override  
protected void onDraw(Canvas canvas) {  
  super.onDraw(canvas);  
  //用來記錄我們滑動塊的位置  
  int left\_slip \= 0;   
  Matrix matrix \= new Matrix();  
  Paint paint \= new Paint();  
  if(currentX < bkgSwitchOn.getWidth() / 2){  
    //在畫布上繪制出開關狀態為關閉時的  背景圖片  
    canvas.drawBitmap(bkgSwitchOff, matrix, paint);  
  }else{  
    //在畫布上繪制出開關狀態為開啟時的  背景圖片  
    canvas.drawBitmap(bkgSwitchOn, matrix, paint);  
  }  
  if(isSlipping){//開關是否處于滑動狀態  
    // 滑動塊 是否超過了整個滑動按鈕的寬度   
    if(currentX \> bkgSwitchOn.getWidth()){  
      //指定滑動塊的位置  
      left\_slip \= bkgSwitchOn.getWidth() \- btnSlip.getWidth();  
    } else {  
      //設置當前滑動塊的位置  
      left\_slip \= (int) (currentX \- btnSlip.getWidth() /2);  
    }  
  } else {//開關是否處于   不滑動狀態   
    if(toggleStateOn){  
      left\_slip \= rect\_on.left;  
    } else {  
      left\_slip \= rect\_off.left;  
    }  
  }  
    
  if(left\_slip < 0){  
    left\_slip \= 0;  
  } else if( left\_slip \> bkgSwitchOn.getWidth() \- btnSlip.getWidth()){  
    left\_slip \= bkgSwitchOn.getWidth() \- btnSlip.getWidth();  
  }  
  //繪制圖像  
  canvas.drawBitmap(btnSlip, left\_slip, 0, paint);  
}
6)計算開關的寬高

這里我通過覆寫onMeasure來計算開關的寬度和高度

具體實現代碼如下:

//計算開關的寬高  
@Override  
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
  setMeasuredDimension(bkgSwitchOn.getWidth(), bkgSwitchOn.getHeight());  
}
7)設置圖片資源信息

這個方法主要是供外界調用,向本類提供圖片資源。

具體代碼實現如下:

/\*\*  
 \* 設置圖片資源信息  
 \* @param bkgSwitch\_on  
 \* @param bkgSwitch\_off  
 \* @param btn\_Slip  
 \*/  
public void setImageRes(int bkgSwitch\_on, int bkgSwitch\_off, int btn\_Slip) {  
  bkgSwitchOn \= BitmapFactory.decodeResource(getResources(), bkgSwitch\_on);  
  bkgSwitchOff \= BitmapFactory.decodeResource(getResources(),bkgSwitch\_off);  
  btnSlip \= BitmapFactory.decodeResource(getResources(), btn\_Slip);  
  rect\_on \= new Rect(bkgSwitchOn.getWidth() \- btnSlip.getWidth(), 0,bkgSwitchOn.getWidth(), btnSlip.getHeight());  
  rect\_off \= new Rect(0, 0, btnSlip.getWidth(), btnSlip.getHeight());  
}
8)設置開關按鈕的狀態

通過傳遞一個boolean類型的狀態,我們在這個方法中將這個狀態標識記錄下來。

具體實現代碼如下:

/\*\*  
 \* 設置開關按鈕的狀態  
 \* @param state  
 \*/  
public void setToggleState(boolean state) {  
  toggleStateOn \= state;  
}
9)自定義開關狀態監聽器

我在這個類中定義了一個開關狀態監聽器接口OnToggleStateListener,里面有一個onToggleState方法來執行按鈕的狀態變化監聽操作。

具體代碼實現如下:

/\*\*  
 \* 自定義開關狀態監聽器  
 \* @author liuyazhuang  
 \*  
 \*/  
interface OnToggleStateListener {  
  abstract void onToggleState(boolean state);  
}
10)設置開關監聽器

創建setOnToggleStateListener方法,傳遞一個OnToggleStateListener監聽器對象,通過外界創建OnToggleStateListener對象,并將OnToggleStateListener對象傳遞進來,我們只需要將外界傳遞過來的OnToggleStateListener對象記錄下來,同時當我們調用OnToggleStateListener接口中的onToggleState方法時,便實現了回調外界OnToggleStateListener實現類中的onToggleState方法。

具體代碼實現如下:

//設置開關監聽器并將是否設置了開關監聽器設置為true  
public void setOnToggleStateListener(OnToggleStateListener listener) {  
  toggleStateListener \= listener;  
  isToggleStateListenerOn \= true;  
}
11)MyToggle完整代碼如下:
package com.lyz.slip.toggle;  
  
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;  
  
/\*\*  
 \* 自定義開關類  
 \* @author liuyazhuang  
 \*  
 \*/  
public class MyToggle extends View implements OnTouchListener {  
  //開關開啟的背景圖片  
  private Bitmap bkgSwitchOn;  
  //開關關閉的背景圖片  
  private Bitmap bkgSwitchOff;  
  //開關的滾動圖片  
  private Bitmap btnSlip;  
  //當前開關是否為開啟狀態  
  private boolean toggleStateOn;  
  //開關狀態的監聽事件  
  private OnToggleStateListener toggleStateListener;  
  //記錄開關·當前的狀態  
  private boolean isToggleStateListenerOn;  
  //手指按下屏幕時的x坐標  
  private float proX;  
  //手指滑動過程中當前x坐標  
  private float currentX;  
  //是否處于滑動狀態  
  private boolean isSlipping;  
  //記錄上一次開關的狀態  
  private boolean proToggleState \= true;  
  //開關開啟時的矩形  
  private Rect rect\_on;  
  //開關關閉時的矩形  
  private Rect rect\_off;  
  
  public MyToggle(Context context) {  
    super(context);  
    init(context);  
  }  
    
  public MyToggle(Context context, AttributeSet attrs) {  
    super(context, attrs);  
    init(context);  
  }  
    
  //初始化方法  
  private void init(Context context) {  
    setOnTouchListener(this);  
  
  }  
  
  @Override  
  public boolean onTouch(View v, MotionEvent event) {  
    switch (event.getAction()) {  
    case MotionEvent.ACTION\_DOWN:  
      //記錄手指按下時的x坐標  
      proX \= event.getX();   
      currentX \= proX;  
      //將滑動標識設置為true  
      isSlipping \= true;  
      break;  
  
    case MotionEvent.ACTION\_MOVE:  
      //記錄手指滑動過程中當前x坐標  
      currentX \= event.getX();  
      break;  
  
    case MotionEvent.ACTION\_UP:  
      //手指抬起時將是否滑動的標識設置為false  
      isSlipping \= false;  
      //處于關閉狀態  
      if(currentX < bkgSwitchOn.getWidth() / 2 ){  
        toggleStateOn \= false;  
      } else { // 處于開啟狀態  
        toggleStateOn \= true;  
      }  
        
      // 如果使用了開關監聽器,同時開關的狀態發生了改變,這時使用該代碼  
      if(isToggleStateListenerOn && toggleStateOn != proToggleState){  
        proToggleState \= toggleStateOn;  
        toggleStateListener.onToggleState(toggleStateOn);  
      }  
      break;  
    }  
      
    invalidate();//重繪  
    return true;  
  }  
  
  @Override  
  protected void onDraw(Canvas canvas) {  
    super.onDraw(canvas);  
    //用來記錄我們滑動塊的位置  
    int left\_slip \= 0;   
    Matrix matrix \= new Matrix();  
    Paint paint \= new Paint();  
    if(currentX < bkgSwitchOn.getWidth() / 2){  
      //在畫布上繪制出開關狀態為關閉時的  背景圖片  
      canvas.drawBitmap(bkgSwitchOff, matrix, paint);  
    }else{  
      //在畫布上繪制出開關狀態為開啟時的  背景圖片  
      canvas.drawBitmap(bkgSwitchOn, matrix, paint);  
    }  
    if(isSlipping){//開關是否處于滑動狀態  
      // 滑動塊 是否超過了整個滑動按鈕的寬度   
      if(currentX \> bkgSwitchOn.getWidth()){  
        //指定滑動塊的位置  
        left\_slip \= bkgSwitchOn.getWidth() \- btnSlip.getWidth();  
      } else {  
        //設置當前滑動塊的位置  
        left\_slip \= (int) (currentX \- btnSlip.getWidth() /2);  
      }  
    } else {//開關是否處于   不滑動狀態   
      if(toggleStateOn){  
        left\_slip \= rect\_on.left;  
      } else {  
        left\_slip \= rect\_off.left;  
      }  
    }  
      
    if(left\_slip < 0){  
      left\_slip \= 0;  
    } else if( left\_slip \> bkgSwitchOn.getWidth() \- btnSlip.getWidth()){  
      left\_slip \= bkgSwitchOn.getWidth() \- btnSlip.getWidth();  
    }  
    //繪制圖像  
    canvas.drawBitmap(btnSlip, left\_slip, 0, paint);  
  }  
  //計算開關的寬高  
  @Override  
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
    setMeasuredDimension(bkgSwitchOn.getWidth(), bkgSwitchOn.getHeight());  
  }  
    
  /\*\*  
   \* 設置圖片資源信息  
   \* @param bkgSwitch\_on  
   \* @param bkgSwitch\_off  
   \* @param btn\_Slip  
   \*/  
  public void setImageRes(int bkgSwitch\_on, int bkgSwitch\_off, int btn\_Slip) {  
    bkgSwitchOn \= BitmapFactory.decodeResource(getResources(), bkgSwitch\_on);  
    bkgSwitchOff \= BitmapFactory.decodeResource(getResources(),bkgSwitch\_off);  
    btnSlip \= BitmapFactory.decodeResource(getResources(), btn\_Slip);  
    rect\_on \= new Rect(bkgSwitchOn.getWidth() \- btnSlip.getWidth(), 0,bkgSwitchOn.getWidth(), btnSlip.getHeight());  
    rect\_off \= new Rect(0, 0, btnSlip.getWidth(), btnSlip.getHeight());  
  }  
  
  /\*\*  
   \* 設置開關按鈕的狀態  
   \* @param state  
   \*/  
  public void setToggleState(boolean state) {  
    toggleStateOn \= state;  
  }  
  
  /\*\*  
   \* 自定義開關狀態監聽器  
   \* @author liuyazhuang  
   \*  
   \*/  
  interface OnToggleStateListener {  
    abstract void onToggleState(boolean state);  
  }  
  //設置開關監聽器并將是否設置了開關監聽器設置為true  
  public void setOnToggleStateListener(OnToggleStateListener listener) {  
    toggleStateListener \= listener;  
    isToggleStateListenerOn \= true;  
  }  
}

2、MainActivity

這個類實現很簡單,主要的功能就是加載界面布局,初始化界面控件,調用MyToggle類中的方法實現按鈕的開關效果

具體代碼實現如下:

package com.lyz.slip.toggle;  
  
import android.app.Activity;  
import android.os.Bundle;  
import android.widget.Toast;  
  
import com.lyz.slip.toggle.MyToggle.OnToggleStateListener;  
  
/\*\*  
 \* 程序主入口  
 \* @author liuyazhuang  
 \*  
 \*/  
public class MainActivity extends Activity {  
    //自定義開關對象  
    private MyToggle toggle;  
    @Override  
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity\_main);  
        toggle \= (MyToggle) findViewById(R.id.toggle);  
        //設置開關顯示所用的圖片  
        toggle.setImageRes(R.drawable.bkg\_switch, R.drawable.bkg\_switch, R.drawable.btn\_slip);  
        //設置開關的默認狀態    true開啟狀態  
        toggle.setToggleState(true);  
        //設置開關的監聽  
        toggle.setOnToggleStateListener(new OnToggleStateListener() {  
            @Override  
            public void onToggleState(boolean state) {  
                // TODO Auto-generated method stub  
                if(state){  
                    Toast.makeText(getApplicationContext(), "開關開啟", 0).show();  
                } else {  
                    Toast.makeText(getApplicationContext(), "開關關閉", 0).show();  
                }  
            }  
        });  
    }  
}

3、布局文件activity_main.xml

這里我引用了自己定義的View類MyToggle。

具體代碼實現如下:

<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.lyz.slip.toggle.MyToggle  
        android:id\="@+id/toggle"  
        android:layout\_width\="wrap\_content"  
        android:layout\_height\="wrap\_content"  
        android:layout\_centerInParent\="true"/>  
</RelativeLayout\>

4、AndroidManifest.xml

具體代碼如下:

<?xml version="1.0" encoding="utf-8"?>  
<manifest xmlns:android\="http://schemas.android.com/apk/res/android"  
    package\="com.lyz.slip.toggle"  
    android:versionCode\="1"  
    android:versionName\="1.0" \>  
  
    <uses-sdk  
        android:minSdkVersion\="10"  
        android:targetSdkVersion\="18" />  
  
    <application  
        android:allowBackup\="true"  
        android:icon\="@drawable/ic\_launcher"  
        android:label\="@string/app\_name"  
        android:theme\="@style/AppTheme" \>  
        <activity  
            android:name\="com.lyz.slip.toggle.MainActivity"  
            android:label\="@string/app\_name" \>  
            <intent-filter\>  
                <action android:name\="android.intent.action.MAIN" />  
  
                <category android:name\="android.intent.category.LAUNCHER" />  
            </intent-filter\>  
        </activity\>  
    </application\>  
</manifest\>

三、運行效果

Android怎么實現自定義開關按鈕

Android怎么實現自定義開關按鈕

感謝各位的閱讀,以上就是“Android怎么實現自定義開關按鈕”的內容了,經過本文的學習后,相信大家對Android怎么實現自定義開關按鈕這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

综艺| 长乐市| 尤溪县| 越西县| 南投县| 卓尼县| 蒙自县| 光泽县| 宕昌县| 饶河县| 万山特区| 庆元县| 彝良县| 射阳县| 永善县| 高平市| 仁怀市| 平遥县| 秦皇岛市| 蓝山县| 河池市| 萨迦县| 文山县| 东乌| 偏关县| 阿勒泰市| 绥化市| 彰武县| 兴城市| 静宁县| 渭源县| 新邵县| 安乡县| 灯塔市| 麻栗坡县| 湘潭县| 鹤壁市| 繁峙县| 麻江县| 浙江省| 荔波县|