服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Android - Android自定义实现可滑动按钮

Android自定义实现可滑动按钮

2022-09-21 15:17常利兵 Android

这篇文章主要为大家详细介绍了Android自定义实现可滑动的按钮,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了Android自定义实现可滑动按钮的具体代码,供大家参考,具体内容如下

实现逻辑

1.创建一个类继承view类,实现里面的onMeasure() onDraw()方法

2.在 onMeasure() 中需要调用setMeasuredDimension(viewWidth,viewheight),用来绘制按钮的位置区域

3.需要加载按钮的背景和滑块资源 并且转化为bitmap对象

4.获取背景图片的宽和高作为自定义控件的宽和高

5.获取滑块的宽度,用来调整按钮的开和关

6.在onDraw()方法中绘制出背景图片和滑块,并展示在页面中

7.创建一个触摸事件,用来监听按钮所在的位置

8.创建drawSlide方法,用来限制滑块的运行区间,防止滑块划出指定的区域,并限制按钮只有两个结果,开和关

9.根据drawSlide方法得到开关的结果,设置开关的状态

10.根据开关的状态设置开关中滑块的位置

11设.置一个回调接口,用来监听按钮的状态是否发生改变

布局文件

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context="com.example.a3_.MainActivity">
 
<com.example.a3_.MyToggleButton
 android:id="@+id/myToggle"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content" />
 
<com.example.a3_.MyToggleButton
 android:id="@+id/myToggle2"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content" />
</LinearLayout>

核心代码

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package com.example.a3_;
 
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;
 
public class MainActivity extends AppCompatActivity {
 
private MyToggleButton toggleButton;
private MyToggleButton toggleButton2;
 
@Override
protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 
 //初始化控件
 toggleButton = (MyToggleButton) findViewById(R.id.myToggle);
 //设置按钮的状态
 toggleButton.setToggleStste(true);
 //创建一个监听
 MyListener myListener = new MyListener();
 //设置监听
 toggleButton.setOnToggleStateChangedListener(myListener);
 
 //初始化控件
 toggleButton2 = (MyToggleButton) findViewById(R.id.myToggle2);
 //设置按钮的状态
 toggleButton2.setToggleStste(true);
 //创建一个监听
 MyListener myListener2 = new MyListener();
 //设置监听
 toggleButton2.setOnToggleStateChangedListener(myListener2);
 
}
 
//创建一个监听
class MyListener implements MyToggleButton.onToggleStateChangedListener {
 
 @Override
 public void onToggleStateChange(MyToggleButton button, boolean isToggleOn) {
 
  //判定是哪个按钮触发了监听
  switch (button.getId()) {
   case R.id.myToggle:
    Toast.makeText(MainActivity.this, isToggleOn ? "开1" : "关1", Toast.LENGTH_SHORT).show();
    break;
   case R.id.myToggle2:
    Toast.makeText(MainActivity.this, isToggleOn ? "开2" : "关2", Toast.LENGTH_SHORT).show();
  }
 
 }
}
}

自定义控件代码

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package com.example.a3_;
 
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
 
/**
 * Created by Administrator on 2017.05.27.0027.
 */
 
public class MyToggleButton extends View {
 
private Bitmap bgBitmap;
private Bitmap slidebg;
private final int viewWidth;
private final int viewheight;
private float slidebgleft;
private final int slideWidth;
private final int slideMaxLeft;
//设置一个成员变量,用来判定开关的状态
private boolean toggleStste = false;
private boolean canChangeToggleState = false;
 
private onToggleStateChangedListener monToggleStateChangedListener = null;
 
//创建一个开关状态改变的监听,当状态改变时触发,否则不触发
public void setOnToggleStateChangedListener(onToggleStateChangedListener monToggleStateChangedListener) {
 this.monToggleStateChangedListener = monToggleStateChangedListener;
}
 
 
public MyToggleButton(Context context, AttributeSet attrs) {
 super(context, attrs);
 //设置按钮的背景和滑块资源
 setBackgroundAndSlideResource(R.mipmap.toogle_background, R.mipmap.toogle_slidebg);
 //获取背景的高度和宽度
 viewWidth = bgBitmap.getWidth();
 viewheight = bgBitmap.getHeight();
 //背景的宽和高就是这个自定义按钮的宽和高
 //获取滑块的宽度
 slideWidth = slidebg.getWidth();
 //计算滑块的右边最大值
 slideMaxLeft = viewWidth - slideWidth;
}
 
//定义一个方法,用来显示按钮是开还是关
public void setToggleStste(boolean toggleStste) {
 this.toggleStste = toggleStste;
 if (toggleStste) {
  slidebgleft = slideMaxLeft;
 } else {
  slidebgleft = 0;
 }
 //重新绘制
 invalidate();
}
 
//设置按钮的背景和滑块资源
private void setBackgroundAndSlideResource(int toogle_background, int toogle_slidebg) {
 bgBitmap = BitmapFactory.decodeResource(getResources(), toogle_background);
 slidebg = BitmapFactory.decodeResource(getResources(), toogle_slidebg);
}
 
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//  super.onMeasure(widthMeasureSpec, heightMeasureSpec);
 //调用setMeasuredDimension绘制按钮的区域
 setMeasuredDimension(viewWidth, viewheight);
}
 
@Override
protected void onDraw(Canvas canvas) {
 
 //重写drawBitmap,将控件的背景和滑块绘制到页面中
 canvas.drawBitmap(bgBitmap, 0, 0, null);
 drawSlide(canvas);
 
}
 
//通过控制slidebgleft,来控制滑块的位置
private void drawSlide(Canvas canvas) {
 //限制滑块的运行区间,防止滑块移动到界外
 if (slidebgleft < 0) {
  slidebgleft = 0;
 } else if (slidebgleft > slideMaxLeft) {
  slidebgleft = slideMaxLeft;
 }
 canvas.drawBitmap(slidebg, slidebgleft, 0, null);
 if (canChangeToggleState) {
  canChangeToggleState = false;
  //记录上一次开关的状态
  boolean lastToggleState = toggleStste;
  //根据当前滑块的位置更新开关的状态
  if (slidebgleft == 0) {
   toggleStste = false;
  } else {
   toggleStste = true;
  }
 
  //如果当前的状态与上一次状态不同时,才会触发监听事件
  if (lastToggleState != toggleStste && monToggleStateChangedListener != null) {
   monToggleStateChangedListener.onToggleStateChange(this, toggleStste);
  }
 }
}
 
//设置按钮的触摸事件
@Override
public boolean onTouchEvent(MotionEvent event) {
 switch (event.getAction()) {
  case MotionEvent.ACTION_DOWN:
   slidebgleft = event.getX() - slideWidth / 2;
   break;
  case MotionEvent.ACTION_MOVE:
   slidebgleft = event.getX() - slideWidth / 2;
   break;
  case MotionEvent.ACTION_UP:
   if (event.getX() > viewWidth / 2) {
    slidebgleft = slideMaxLeft;
   } else {
    slidebgleft = 0;
   }
   //只有当手机离开屏幕的是否才可以触发监听
   canChangeToggleState = true;
   break;
 }
 //重复不断地绘制
 invalidate();
 return true;
}
 
interface onToggleStateChangedListener {
 void onToggleStateChange(MyToggleButton button, boolean isToggleOn);
}
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/qq_32890771/article/details/72784073

延伸 · 阅读

精彩推荐