Android之实现滑动开关组件
16lz
2021-01-24
由于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仿ios年龄、生日、性别滚轮效果
- Handler: Service中使用Toast
- Android(安卓)开发究竟是选择 Java 还是 Kotlin?Google 有话说
- android缩放动画的两种实现方法
- Android客户端与java服务端AES加解密
- Android(安卓)Studio JNI开发
- Android(安卓)游戏开发中横竖屏切换问题
- Android(安卓)TableLayout中的使用说明
- LoganSquare——快速解析和序列化JSON对象的Android类库