Android自定義控制元件模仿iOS滑塊SwitchButton
SwitchButton可以點選的時候切換狀態,類似CheckBox
在拖動的時候,也可以根據拖動的距離判斷是否切換狀態,類似ToggleButton
因此要區別出單擊事件和拖動事件
實現效果如圖所示:
自定義的SwitchButton如下:
public class SwitchButton extends View implements View.OnTouchListener {
private Bitmap bg_on, bg_off, slipper_btn;
/**
* 按下時的x和當前的x
*/
private float downX, nowX;
/**
* 記錄使用者是否在滑動
*/
private boolean onSlip = false;
/**
* 當前的狀態
*/
private boolean nowStatus = false;
/**
* 監聽介面
*/
private OnChangedListener listener;
/*
* 一個滑動的距離臨界值,判斷是滑動還是點選
* getScaledTouchSlop():
* Distance in pixels a touch can wander before we think the user is scrolling
* */
private int mTouchSlop=new ViewConfiguration().getScaledTouchSlop();
public SwitchButton(Context context) {
super(context);
init();
}
public SwitchButton(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public void init(){
//載入圖片資源
bg_on = BitmapFactory.decodeResource(getResources(), R.mipmap.switch_on_on);
bg_off = BitmapFactory.decodeResource(getResources(), R.mipmap.switch_off_off);
slipper_btn = BitmapFactory.decodeResource(getResources(), R.mipmap.switch_ball_ball);
setOnTouchListener(this);
}
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Matrix matrix = new Matrix();
Paint paint = new Paint();
float x = 0;
//根據nowX設定背景,開或者關狀態
if (nowX < (bg_on.getWidth()/2)){
canvas.drawBitmap(bg_off, matrix, paint);//畫出關閉時的背景
}else{
canvas.drawBitmap(bg_on, matrix, paint);//畫出開啟時的背景
}
if (onSlip) {//是否是在滑動狀態,
if(nowX >= bg_on.getWidth())//是否劃出指定範圍,不能讓滑塊跑到外頭,必須做這個判斷
x = bg_on.getWidth() - slipper_btn.getWidth()/2;//減去滑塊1/2的長度
else
x = nowX - slipper_btn.getWidth()/2;
}else {
if(nowStatus){//根據當前的狀態設定滑塊的x值
x = bg_on.getWidth() - slipper_btn.getWidth();
}else{
x = 0;
}
}
//對滑塊滑動進行異常處理,不能讓滑塊出界
if (x < 0 ){
x = 0;
}
else if(x > bg_on.getWidth() - slipper_btn.getWidth()){
x = bg_on.getWidth() - slipper_btn.getWidth();
}
//畫出滑塊
canvas.drawBitmap(slipper_btn, x, 0, paint);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:{
if (event.getX() > bg_off.getWidth() || event.getY() > bg_off.getHeight()){
return false;
}else{
onSlip = true;
downX = event.getX();
nowX = downX;
}
break;
}
case MotionEvent.ACTION_MOVE:{
nowX = event.getX();
break;
}
case MotionEvent.ACTION_UP:{
DebugLog.e("mTouchSlop:"+mTouchSlop);
onSlip = false;
nowX = event.getX();
float float_distance=nowX - downX;
int int_disatnce=(int)float_distance;
DebugLog.e("int_disatnce:"+int_disatnce);
/*滑動距離太短,認定是點選事件*/
if(Math.abs(int_disatnce)<mTouchSlop){
if(this.isChecked()){
this.setChecked(false);
nowX = 0;
}else{
this.setChecked(true);
nowX = bg_on.getWidth() - slipper_btn.getWidth();
}
}else{
/*滑動距離足夠,認為是滑動事件*/
if(event.getX() >= (bg_on.getWidth()/2)){
nowStatus = true;
nowX = bg_on.getWidth() - slipper_btn.getWidth();
}else{
nowStatus = false;
nowX = 0;
}
}
if(listener != null){
listener.OnChanged(SwitchButton.this, nowStatus);
}
break;
}
}
//重新整理介面
invalidate();
return true;
}
/**
* 為WiperSwitch設定一個監聽,供外部呼叫的方法
* @param listener
*/
public void setOnChangedListener(OnChangedListener listener){
this.listener = listener;
}
/**
* 設定滑動開關的初始狀態,供外部呼叫
* @param checked
*/
public void setChecked(boolean checked){
if(checked){
nowX = bg_off.getWidth();
}else{
nowX = 0;
}
nowStatus = checked;
}
public boolean isChecked() {
return nowStatus;
}
/**
* 回撥介面
*
*/
public interface OnChangedListener {
public void OnChanged(SwitchButton wiperSwitch, boolean checkState);
}
}
佈局檔案中使用:
<com.uestcneon.chuji.changjianglife.share.SwitchButton android:id="@+id/user_privacy_state" android:layout_width="wrap_content" android:layout_height="20dp" android:layout_marginLeft="30dp" />
控制元件用到的3個資源圖片:
相關文章
- iOS 自定義雙向滑塊SlideriOSIDE
- WPF滑塊控制元件(Slider)的自定義樣式控制元件IDE
- Android中實現類似iOS的SwitchButton控制元件AndroidiOS控制元件
- iOS自定義控制元件 AlertViewiOS控制元件View
- iOS自定義控制元件 SegmentiOS控制元件
- Android自定義控制元件——自定義屬性Android控制元件
- Android自定義控制元件之自定義組合控制元件Android控制元件
- Android右滑關閉Activity介面功能-自定義控制元件實現Android控制元件
- Android自定義控制元件之自定義屬性Android控制元件
- iOS自定義控制元件 SlideriOS控制元件IDE
- Android自定義滑動刻度尺Android
- Android 自定義View 滑動解鎖AndroidView
- android:建立自定義控制元件Android控制元件
- (Android自定義控制元件)Android自定義狀態提示圖表Android控制元件
- iOS自定義控制元件:簡易下拉控制元件iOS控制元件
- Android自定義組合控制元件之自定義屬性Android控制元件
- Android自定義View(四)側滑佈局AndroidView
- 【Android】自定義樹形控制元件Android控制元件
- android 自定義控制元件 自定義屬性詳細介紹Android控制元件
- iOS 自定義拖拽式控制元件:QiDragViewiOS控制元件View
- iOS 自定義卡片式控制元件:QiCardViewiOS控制元件View
- 【朝花夕拾】Android自定義View篇之(十一)View的滑動,彈性滑動與自定義PagerViewAndroidView
- Android開發自定義View之滑動按鈕與自定義屬性AndroidView
- android 滑動刪除的listview(自定義view)AndroidView
- [C#] (原創)一步一步教你自定義控制元件——03,SwitchButton(開關按鈕)C#控制元件
- iOS自定義控制元件:自定義TableView、CollectionView空資料佔點陣圖iOS控制元件View
- [譯] 教你如何用 Flutter 的 GestureDetector 構建自定義滑塊Flutter
- iOS 自定義的卡片流互動控制元件iOS控制元件
- iOS 自定義日曆(日期選擇)控制元件iOS控制元件
- iOS開發自定義View佈局子控制元件iOSView控制元件
- Android自定義控制元件之自定義ViewGroup實現標籤雲Android控制元件View
- Android 自定義輪播圖片控制元件Android控制元件
- Android自定義下拉重新整理控制元件Android控制元件
- Android圓形圖片--自定義控制元件Android控制元件
- android自定義開關控制元件-SlideSwitchAndroid控制元件IDE
- Android 控制元件架構與自定義控制元件詳解Android控制元件架構
- iOS自定義控制元件:精簡的底部彈框iOS控制元件
- 自定義ViewGroup,實現Android的側滑選單ViewAndroid