網站首頁 編程語言 正文
本文實例為大家分享了Android自定義控件實現簡單滑動開關的具體代碼,供大家參考,具體內容如下
ToggleButton 滑動開關
項目概述
滑動開關是一個純粹的自定義控件,上面的按鈕會隨著我們的左右滑動而滑動,并且在狀態改變時通知用戶,效果如下圖1-9 所示,這也是應用中設置某些狀態信息時最常見的控件,因此,我們有必要學習關于如何
自定義一個這樣的滑動開關。
滑動開關UI
布局文件為activity_main.xml,代碼如下:res/layout/activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" ? ? ? ? ? ? ? ? xmlns:itheima="http://schemas.android.com/apk/res/com.itheima.togglebuttondemo" ? ? ? ? ? ? ? ? xmlns:tools="http://schemas.android.com/tools" ? ? ? ? ? ? ? ? android:layout_width="match_parent" ? ? ? ? ? ? ? ? android:layout_height="match_parent"> ? ? <com.itheima.togglebuttondemo.view.ToggleButton ? ? ? ? android:id="@+id/togglebutton" ? ? ? ? android:layout_width="wrap_content" ? ? ? ? android:layout_centerInParent="true" ? ? ? ? itheima:SwitchBtnBackgroud="@drawable/switch_background" ? ? ? ? itheima:SlidBtnBackgroud="@drawable/slide_button_background" ? ? ? ? itheima:CurrentState="false" ? ? ? ? android:layout_height="wrap_content"/> </RelativeLayout>
在activity_main.xml 布局中引入如下命名空間:
xmlns:itheima=”http://schemas.android.com/apk/res/com.itheima.togglebuttondemo”,com.itheima.togglebuttondemo 是包名,itheima 是自定義的命名控件名,可以任取名字,也可以使用類名。
上面的布局主要是引入com.itheima.togglebuttondemo.view.ToggleButton 類和自定義屬性的使用。添加自定義屬性,在values 目錄下創建attrs.xml 文件,具體代碼如文件所示:
res/values/attrs.xml
<?xml version="1.0" encoding="utf-8"?> <resources> ? ? <declare-styleable name="ToggleButton"> ? ? ? ? <!-- 滑動開關背景圖片屬性--> ? ? ? ? <attr ? ? ? ? ? ? name="SwitchBtnBackgroud" ? ? ? ? ? ? format="reference"/> ? ? ? ? <!-- 滑動塊背景圖片屬性--> ? ? ? ? <attr ? ? ? ? ? ? name="SlidBtnBackgroud" ? ? ? ? ? ? format="reference"/> ? ? ? ? <!-- 滑動開關的狀態--> ? ? ? ? <attr ? ? ? ? ? ? name="CurrentState" ? ? ? ? ? ? format="boolean"/> ? ? </declare-styleable> </resources>
attrs.xml 文件目錄結構如下圖所示:
滑動開關業務邏輯實現
下拉選擇框activity 界面,MainActivity.java 代碼如下:com/itheima/MySwitch/MainActivity
public class MainActivity extends Activity { ? ? @Override ? ? protected void onCreate(Bundle savedInstanceState) { ? ? ? ? super.onCreate(savedInstanceState); ? ? ? ? setContentView(R.layout.activity_main); ? ? ? ? ToggleButton togglebutton = (ToggleButton) findViewById(R.id.togglebutton); ? ? ? ? //設置滑動開關的背景圖片 ? ? ? ? // togglebutton.setSwitchBtnBackgroudResource(R.drawable.switch_background); ? ? ? ? //設置滑動塊的背景圖片 ? ? ? ? // togglebutton.setSlidBtnBackgroudResource(R.drawable.slide_button_background); ? ? ? ? //設置滑動開關的默認狀態 ? ? ? ? // togglebutton.setCurrentState(true); ? ? ? ? //設置滑動開關狀態改變監聽 ? ? ? ? Togglebutton.setToggleBtnStateChangeListener(new ToggleBtnStateChangeListener() { ? ? ? ? ? ? @Override ? ? ? ? ? ? public void onToggleBtnStateChange(boolean currentState) { ? ? ? ? ? ? ? ? if (currentState) { ? ? ? ? ? ? ? ? ? ? Toast.makeText(getApplicationContext(), "開關打開", 0).show(); ? ? ? ? ? ? ? ? }else{ ? ? ? ? ? ? ? ? ? ? Toast.makeText(getApplicationContext(), "開關關閉", 0).show(); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? }); ? ? } }
自定義的滑動開關ToggleButton 類的實現,具體代碼如文件所示:com/itheima/MySwitch/MainActivity
public class ToggleButton extends View { ? ? private Bitmap ?switchBitmap;//滑動開關的背景圖片 ? ? private Bitmap ?slidBitmap;//滑動塊的背景圖片 ? ? private boolean currentState; ? ? private int ? ? currentX;//手指觸摸點的X 值 ? ? private boolean isTouching = false; ? ? private ToggleBtnStateChangeListener mToggleBtnStateChangeListener;//狀態改變監聽器 ? ? //在xml 中引用該控件時,調用該方法 ? ? public ToggleButton(Context context, AttributeSet attrs) { ? ? ? ? super(context, attrs); ? ? ? ? String namespace = "http://schemas.android.com/apk/res/com.itheima.togglebuttondemo"; ? ? ? ? currentState = attrs.getAttributeBooleanValue(namespace, "CurrentState", false); ? ? ? ? int switchBtnBackgroudId = ? ? ? ? ? ? ? ? attrs.getAttributeResourceValue(namespace, "SwitchBtnBackgroud", -1); ? ? ? ? int slidBtnBackgroudId = ? ? ? ? ? ? ? ? attrs.getAttributeResourceValue(namespace, "SlidBtnBackgroud", -1); ? ? ? ? setSwitchBtnBackgroudResource(switchBtnBackgroudId); ? ? ? ? setSlidBtnBackgroudResource(slidBtnBackgroudId); ? ? } ? ? //在代碼中創建該控件時,調用該構造方法 ? ? public ToggleButton(Context context) { ? ? ? ? super(context); ? ? } ? ? //設置滑動開關的背景圖片 ? ? public void setSwitchBtnBackgroudResource(int switchBackground) { ? ? ? ? switchBitmap = BitmapFactory.decodeResource(getResources(), switchBackground); ? ? } ? ? // 為了可以高度自定義和增強可擴展性,我們可以給其創建一個自定義控件底部背景了一個方法 ? ? // 設置滑動塊的背景圖片 ? ? public void setSlidBtnBackgroudResource(int slideButtonBackground) { ? ? ? ? slidBitmap = BitmapFactory.decodeResource(getResources(), slideButtonBackground); ? ? } ? ? //設置滑動開關的默認狀態 ? ? public void setCurrentState(boolean b) { ? ? ? ? currentState = b; ? ? } ? ? // 1、測量滑動開關的寬高 ? ? // 測量控件的寬高 ? ? @Override ? ? protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { ? ? ? ? super.onMeasure(widthMeasureSpec, heightMeasureSpec); ? ? ? ? setMeasuredDimension(switchBitmap.getWidth(), switchBitmap.getHeight()); ? ? } ? ? // 2、繪制,畫出我們的滑動開關 ? ? //canvas:畫布,將圖形繪制在canvas,才能顯示到屏幕上 ? ? @Override ? ? protected void onDraw(Canvas canvas) { ? ? ? ? //繪制滑動開關的背景圖片 ? ? ? ? canvas.drawBitmap(switchBitmap, 0, 0, null); ? ? ? ? //繪制滑動塊的背景圖片 ? ? ? ? if(isTouching){//手指觸摸的時候,根據currentx 的值來繪制滑動塊 ? ? ? ? ? ? //根據手指的X 值,來繪制滑動塊圖片 ? ? ? ? ? ? int left = currentX - slidBitmap.getWidth()/2; ? ? ? ? ? ? if(left < 0){//設置左邊界 ? ? ? ? ? ? ? ? left = 0; ? ? ? ? ? ? }else if(left > (switchBitmap.getWidth() - slidBitmap.getWidth())){//設置右邊界 ? ? ? ? ? ? ? ? left = switchBitmap.getWidth() - slidBitmap.getWidth(); ? ? ? ? ? ? } ? ? ? ? ? ? canvas.drawBitmap(slidBitmap, left, 0, null); ? ? ? ? }else{ // 手指離開控件的時候,根據狀態來繪制滑動塊 ? ? ? ? ? ? // 根據狀態值,來繪制滑動塊 ? ? ? ? ? ? if(currentState){ //當前為true,開關打開,滑動塊顯示在最右邊 ? ? ? ? ? ? ? ? canvas.drawBitmap(slidBitmap,switchBitmap.getWidth() - slidBitmap.getWidth(), ? ? ? ? ? ? ? ? ? ? ? ? 0, null); ? ? ? ? ? ? }else{//當前為false,開關關閉,滑動塊顯示在最左邊 ? ? ? ? ? ? ? ? canvas.drawBitmap(slidBitmap, 0, 0, null); ? ? ? ? ? ? } ? ? ? ? } ? ? } ? ? //當控件被觸摸后,會調用該方法 ? ? @Override ? ? public boolean onTouchEvent(MotionEvent event) { ? ? ? ? switch (event.getAction()) { ? ? ? ? ? ? case MotionEvent.ACTION_DOWN://手指按下 ? ? ? ? ? ? ? ? isTouching = true; ? ? ? ? ? ? ? ? currentX = (int) event.getX(); ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? case MotionEvent.ACTION_MOVE://手指滑動 ? ? ? ? ? ? ? ? isTouching= true; ? ? ? ? ? ? ? ? currentX = (int) event.getX(); ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? case MotionEvent.ACTION_UP://手指抬起 ? ? ? ? ? ? ? ? isTouching = false; ? ? ? ? ? ? ? ? currentX = (int) event.getX(); ? ? ? ? ? ? ? ? int center = switchBitmap.getWidth()/2; ? ? ? ? ? ? ? ? //當滑動塊中心點大于滑動開關背景圖片的中心線時,顯示到右邊,當前狀態為true ? ? ? ? ? ? ? ? boolean state = currentState; ? ? ? ? ? ? ? ? currentState = currentX > center; ? ? ? ? ? ? ? ? if(mToggleBtnStateChangeListener !=null&&state != currentState ){ ? ? ? ? ? ? ? ? ? ? mToggleBtnStateChangeListener.onToggleBtnStateChange(currentState); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? default: ? ? ? ? ? ? ? ? break; ? ? ? ? } ? ? ? ? invalidate(); //強制讓控件重新繪制,ondraw; ? ? ? ? return true; //自己處理觸摸事件 ? ? } ? ? public void setToggleBtnStateChangeListener(ToggleBtnStateChangeListenerlistener){ ? ? ? ? this.mToggleBtnStateChangeListener = listener; ? ? } ? ? // 定義滑動開關狀態改變的回調接口 ? ? public interface ToggleBtnStateChangeListener{ ? ? ? ? void onToggleBtnStateChange(boolean currentState); ? ? } }
運行程序,效果圖如圖1-11 所示。
知識點總結
1.通過setMeasuredDimension 方法,來設置自定義控件的寬高,見ToggleButton 類第42 行
2.View 可以通過invalidate()方法強制讓自己重新繪制,見ToggleButton 類第96 行
3.View 通過實現onTouchEvent 方法來處理手指觸摸事件,見ToggleButton 類第72 行
自定義控件之自定義屬性
當我們使用自定義屬性來自定義控件時,一般分為以下幾個步驟進行設置:
1、在res 文件的values 里面創建attrs.xml,見文件【1-10】attrs.xml
2、在attrs.xml,里面定義我們需要的屬性,見文件【1-10】attrs.xml 代碼
3、在布局文件中使用自定義的屬性,注意要添加命名空間,見文件【1-9】activity_main.xml 第2 行
4、在構造方法中來獲取設置的屬性數據,見文件【1-9】見ToggleButton 類第8~19 行
原文鏈接:https://blog.csdn.net/axi295309066/article/details/55669319
- 上一篇:C語言中的柔性數組你真的了解嗎_C 語言
- 下一篇:C語言中結構體實例解析_C 語言
相關推薦
- 2022-06-14 jquery實現樓層滾動特效_jquery
- 2021-11-22 C++?STL中五個常用算法使用教程及實例講解_C 語言
- 2023-01-08 Android?IntentFilter的匹配規則示例詳解_Android
- 2022-03-30 jupyter?notebook使用argparse傳入list參數_python
- 2022-10-27 React事件處理和表單的綁定詳解_React
- 2022-07-12 Docker-swarm快速搭建redis集群的方法步驟_docker
- 2022-12-05 C++?Boost?MultiArray簡化使用多維數組庫_C 語言
- 2022-05-02 C語言遞歸實現歸并排序詳解_C 語言
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支