| | |
| | | package com.xw.common.custom |
| | | |
| | | import android.content.Context |
| | | import android.graphics.* |
| | | import android.graphics.Canvas |
| | | import android.graphics.Color |
| | | import android.graphics.Paint |
| | | import android.graphics.RectF |
| | | import android.util.AttributeSet |
| | | import android.view.MotionEvent |
| | | import android.view.View |
| | | import android.view.animation.DecelerateInterpolator |
| | | import android.widget.Scroller |
| | | import androidx.core.content.withStyledAttributes |
| | | import kotlin.math.abs |
| | | import com.xw.common.R |
| | | import kotlin.math.abs |
| | | |
| | | /** |
| | | * 自定义滑动开关 View |
| | |
| | | interface OnStateChangeListener { |
| | | fun onStateChanged(isChecked: Boolean) |
| | | } |
| | | |
| | | //是否能手动点击 |
| | | var switchEnable = true |
| | | set(value) { |
| | | field = value |
| | | invalidate() |
| | | } |
| | | |
| | | // 尺寸配置 |
| | | private var switchWidth = 0f |
| | |
| | | |
| | | init { |
| | | context.withStyledAttributes(attrs, R.styleable.SlideSwitchView, defStyleAttr, 0) { |
| | | switchEnable = getBoolean(R.styleable.SlideSwitchView_switchEnable, switchEnable) |
| | | // 背景颜色 |
| | | backgroundColorUnchecked = getColor( |
| | | R.styleable.SlideSwitchView_switchBackgroundColorUnchecked, |
| | |
| | | ) |
| | | |
| | | // 文字内容 |
| | | textUnchecked = getString(R.styleable.SlideSwitchView_switchTextUnchecked) ?: textUnchecked |
| | | textUnchecked = |
| | | getString(R.styleable.SlideSwitchView_switchTextUnchecked) ?: textUnchecked |
| | | textChecked = getString(R.styleable.SlideSwitchView_switchTextChecked) ?: textChecked |
| | | |
| | | // 文字大小 |
| | |
| | | |
| | | // 圆角 |
| | | cornerRadius = getDimension(R.styleable.SlideSwitchView_switchCornerRadius, 0f) |
| | | thumbCornerRadius = getDimension(R.styleable.SlideSwitchView_switchThumbCornerRadius, 0f) |
| | | thumbCornerRadius = |
| | | getDimension(R.styleable.SlideSwitchView_switchThumbCornerRadius, 0f) |
| | | |
| | | // 滑块间距(新增) |
| | | thumbMargin = getDimension(R.styleable.SlideSwitchView_switchThumbMargin, 0f) |
| | |
| | | } |
| | | |
| | | override fun onTouchEvent(event: MotionEvent): Boolean { |
| | | when (event.action) { |
| | | MotionEvent.ACTION_DOWN -> { |
| | | lastX = event.x |
| | | isDragging = false |
| | | parent?.requestDisallowInterceptTouchEvent(true) |
| | | return true |
| | | } |
| | | |
| | | MotionEvent.ACTION_MOVE -> { |
| | | val deltaX = event.x - lastX |
| | | if (!isDragging && abs(deltaX) > touchSlop) { |
| | | isDragging = true |
| | | if (switchEnable) { |
| | | when (event.action) { |
| | | MotionEvent.ACTION_DOWN -> { |
| | | lastX = event.x |
| | | isDragging = false |
| | | parent?.requestDisallowInterceptTouchEvent(true) |
| | | return true |
| | | } |
| | | |
| | | if (isDragging) { |
| | | thumbPosition += deltaX |
| | | // 限制滑动范围 |
| | | thumbPosition = thumbPosition.coerceIn(0f, maxThumbPosition) |
| | | invalidate() |
| | | } |
| | | lastX = event.x |
| | | return true |
| | | } |
| | | MotionEvent.ACTION_MOVE -> { |
| | | val deltaX = event.x - lastX |
| | | if (!isDragging && abs(deltaX) > touchSlop) { |
| | | isDragging = true |
| | | } |
| | | |
| | | MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> { |
| | | parent?.requestDisallowInterceptTouchEvent(false) |
| | | |
| | | if (!isDragging) { |
| | | // 点击切换 |
| | | toggle() |
| | | } else { |
| | | // 滑动释放,根据位置决定状态 |
| | | val threshold = maxThumbPosition / 2 |
| | | val targetChecked = thumbPosition > threshold |
| | | animateToState(targetChecked) |
| | | if (isDragging) { |
| | | thumbPosition += deltaX |
| | | // 限制滑动范围 |
| | | thumbPosition = thumbPosition.coerceIn(0f, maxThumbPosition) |
| | | invalidate() |
| | | } |
| | | lastX = event.x |
| | | return true |
| | | } |
| | | isDragging = false |
| | | return true |
| | | |
| | | MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> { |
| | | parent?.requestDisallowInterceptTouchEvent(false) |
| | | |
| | | if (!isDragging) { |
| | | // 点击切换 |
| | | toggle() |
| | | } else { |
| | | // 滑动释放,根据位置决定状态 |
| | | val threshold = maxThumbPosition / 2 |
| | | val targetChecked = thumbPosition > threshold |
| | | animateToState(targetChecked) |
| | | } |
| | | isDragging = false |
| | | return true |
| | | } |
| | | } |
| | | } |
| | | return super.onTouchEvent(event) |