怎么在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进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。