您好,登錄后才能下訂單哦!
怎么在Android中通過(guò)自定義view實(shí)現(xiàn)滑動(dòng)解鎖效果?針對(duì)這個(gè)問(wèn)題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問(wèn)題的小伙伴找到更簡(jiǎn)單易行的方法。
自定義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為開(kāi)始 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 = "滑動(dòng)停止" ResourcesCompat.getDrawable(resources, R.drawable.f1_svg_left_arrow, null) } else { hintView.text = "滑動(dòng)開(kāi)始" 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) } }
這里需要注意一點(diǎn):頁(yè)面過(guò)長(zhǎng)時(shí),ScrollView和SlideSwitchButton滑動(dòng)事件會(huì)沖突,所以需要吧scrollView傳進(jìn)來(lái)
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,"開(kāi)始操作",Toast.LENGTH_LONG).show() btn_start.start() } else { Toast.makeText(this,"停止操作",Toast.LENGTH_LONG).show() btn_start.stop() } } } }
關(guān)于怎么在Android中通過(guò)自定義view實(shí)現(xiàn)滑動(dòng)解鎖效果問(wèn)題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒(méi)有解開(kāi),可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識(shí)。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。