您好,登錄后才能下訂單哦!
怎么在Android中通過自定義view實現滑動解鎖效果?針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
自定義view如下
@SuppressLint("ClickableViewAccessibility") class SlideSwitchButton : ViewGroup { constructor(context: Context?) : this(context, null) constructor(context: Context?, attrs: AttributeSet?) : this(context, attrs, 0) constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : this( context, attrs, defStyleAttr, 0 ) constructor( context: Context?, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int ) : super(context, attrs, defStyleAttr, defStyleRes) var duration = 300 var isOpen = false var scrollView: ScrollView? = null var onSwitchListener: ((isOpen: Boolean) -> Unit)? = null private var itemHeight = 0 private var itemPadding = 0 private var parentWidth = 0 private val stopImgView: ImageView by lazy { ImageView(context).apply { setImageResource(R.drawable.f1_svg_btn_stop) } } private val startImgView: ImageView by lazy { ImageView(context).apply { setImageResource(R.drawable.f1_svg_btn_start) } } private val hintView: TextView by lazy { TextView(context).apply { setTextSize(TypedValue.COMPLEX_UNIT_PX, resources.getDimension(R.dimen.dp_14)) compoundDrawablePadding = resources.getDimension(R.dimen.dp_5).toInt() setTextColor(Color.parseColor("#727b9f")) } } init { setBackgroundResource(R.drawable.f1_sel_bg_slide_btn) addView(hintView) updateHint() addView(stopImgView) addView(startImgView) var x = 0 startImgView.setOnTouchListener { v, event -> when (event.action) { MotionEvent.ACTION_DOWN -> { scrollView?.requestDisallowInterceptTouchEvent(true) x = event.x.toInt() } MotionEvent.ACTION_UP -> { if (startImgView.x < (parentWidth - startImgView.width) / 2) { play(false) } else { play(true) } scrollView?.requestDisallowInterceptTouchEvent(false) } MotionEvent.ACTION_MOVE -> { val lastX = event.x - x if (startImgView.x + lastX > parentWidth - itemPadding - startImgView.width) { return@setOnTouchListener true } if (startImgView.x + lastX < itemPadding) { return@setOnTouchListener true } startImgView.x += lastX } } return@setOnTouchListener true } } override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { super.onMeasure(widthMeasureSpec, heightMeasureSpec) setMeasuredDimension(widthMeasureSpec, resources.getDimension(R.dimen.dp_90).toInt()) itemPadding = resources.getDimension(R.dimen.dp_5).toInt() itemHeight = resources.getDimension(R.dimen.dp_80).toInt() parentWidth = MeasureSpec.getSize(widthMeasureSpec) } override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) { stopImgView.layout( itemPadding, itemPadding, itemPadding + itemHeight, itemPadding + itemHeight ) startImgView.layout( itemPadding, itemPadding, itemPadding + itemHeight, itemPadding + itemHeight ) val len = hintView.paint.measureText(hintView.text.toString()) + resources.getDimension(R.dimen.dp_24) val let = (r - len) / 2 hintView.layout( let.toInt(), resources.getDimension(R.dimen.dp_35).toInt(), (let + len).toInt(), resources.getDimension(R.dimen.dp_55).toInt() ) } /** * flag tue為開始 false為停止 */ private fun play(flag: Boolean) { val mStart = startImgView.x val mEnd = if (flag) { parentWidth - itemPadding * 2 - startImgView.width.toFloat() } else { stopImgView.x - itemPadding } val animatorOBJ = ObjectAnimator.ofFloat(startImgView, "translationX", mStart, mEnd) animatorOBJ.duration = duration.toLong() animatorOBJ.addListener(object : Animator.AnimatorListener { override fun onAnimationRepeat(animation: Animator?) { } override fun onAnimationEnd(animation: Animator?) { updateHint(flag) if (flag != isOpen) { isOpen = flag onSwitchListener?.invoke(flag) } } override fun onAnimationCancel(animation: Animator?) { } override fun onAnimationStart(animation: Animator?) { } }) animatorOBJ.start() } private fun updateHint(lock: Boolean = false) { val icon = if (lock) { hintView.text = "滑動停止" ResourcesCompat.getDrawable(resources, R.drawable.f1_svg_left_arrow, null) } else { hintView.text = "滑動開始" ResourcesCompat.getDrawable(resources, R.drawable.f1_svg_right_arrow, null) } icon?.setBounds( 0, 0, resources.getDimension(R.dimen.dp_14).toInt(), resources.getDimension(R.dimen.dp_12).toInt() ) if (lock) { hintView.setCompoundDrawables(icon, null, null, null) } else { hintView.setCompoundDrawables(null, null, icon, null) } } fun stop() { play(false) } fun start() { play(true) } }
這里需要注意一點:頁面過長時,ScrollView和SlideSwitchButton滑動事件會沖突,所以需要吧scrollView傳進來
class SlideSwitchButtonActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.f1_act_main) btn_start.scrollView = scrollView btn_start.onSwitchListener = { if (it) { Toast.makeText(this,"開始操作",Toast.LENGTH_LONG).show() btn_start.start() } else { Toast.makeText(this,"停止操作",Toast.LENGTH_LONG).show() btn_start.stop() } } } }
關于怎么在Android中通過自定義view實現滑動解鎖效果問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。