android开发之Android 自定义滑动解锁View

这篇具有很好参考价值的文章主要介绍了android开发之Android 自定义滑动解锁View。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

自定义滑动解锁View

  1. 需求如下:

近期需要做一个类似屏幕滑动解锁的功能,右划开始,左划暂停。

  1. 需求效果图如下
    android开发之Android 自定义滑动解锁View,IT,程序员,android
  2. 实现效果展示
    android开发之Android 自定义滑动解锁View,IT,程序员,android
  3. 自定义view如下

/**

  • Desc 自定义滑动解锁View

  • Author ZY

  • Mail sunnyfor98@gmail.com

  • Date 2021/5/17 11:52

*/

@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传进来

  1. 调用方式如下

/**

  • Desc 自定义滑动解锁View

  • Author ZY

  • Mail sunnyfor98@gmail.com

  • Date 2021/5/28 17:48

*/

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()

        }

    }

}

}

之前封装了一版ZyFrame框架,集工具类、自定义组件、网络请求框架一体,感觉用起来有些厚重,接下来会抽时间做拆分,ZyFrame保留网络请求功能,ZyUI专做自定义组件,ZyTool专做工具类,大概就这样。

文章来源:网络 版权归原作者所有

上文内容不用于商业目的,如涉及知识产权问题,请权利人联系小编,我们将立即处理文章来源地址https://www.toymoban.com/news/detail-637908.html

到了这里,关于android开发之Android 自定义滑动解锁View的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • android 自定义圆角View

    public class CustomView extends View {     private float cornerRadius;     public CustomView(Context context) {         super(context);         init();     }     public CustomView(Context context, AttributeSet attrs) {         super(context, attrs);         TypedArray typedArray = context.obt

    2024年02月11日
    浏览(49)
  • Android 自定义View 之 圆环进度条

      很多时候我们会使用进度条,而Android默认的进度条是长条的,从左至右。而在日常开发中,有时候UI为了让页面更美观,就需要用到圆环进度条,那么本文就是通过自定义写一个圆环进度条,首先看一下效果图:   关于自定义View的基础知识就不再做过多的讲解了,我

    2024年02月10日
    浏览(47)
  • Android:绘制自定义View人脸识别框

    项目开发需要自定义View实现一个人脸框,代码实现很平常,一些细节记录一下,方便以后查阅。 代码实现: FaceView.java 注意: 这里我把FaceView的layout_width、layout_height都设置成了\\\"match_parent\\\" 这里面有个 坑 容易踩到 本次开发时,xml中FaceView控件往上一直到第一层父布局宽、高

    2024年02月09日
    浏览(64)
  • Android 自定义View之圆形进度条

    很多场景下都用到这种进度条,有的还带动画效果, 今天我也来写一个。 写之前先拆解下它的组成: 底层圆形 上层弧形 中间文字 那我们要做的就是: 绘制底层圆形; 在同位置绘制上层弧形,但颜色不同; 在中心点绘制文本,显示进度。 按照这个目标,学习下自定义Vi

    2024年02月09日
    浏览(44)
  • Android 自定义View 之 Dialog弹窗

      在日常开发中用到弹窗是比较多的,常用于提示作用,比如错误操作提示,余额不足提示,退出登录提示等,还有用于数据展示的弹窗,上拉弹窗等等,主要为了简化在日常开发中的使用。   Android中的Dialog弹窗是一种用于展示特定信息或者在用户需要进行某些操作时

    2024年02月16日
    浏览(43)
  • Android自定义View之游戏摇杆键盘实现(一),快手android面试经验

    public class RemoteViewBg { private Bitmap bitmapBg; public RemoteViewBg(Bitmap bitmap) { bitmapBg = bitmap; } //背景的绘图函数 public void draw(Canvas canvas, Paint paint, Rect src0 ,Rect dst0 ) { canvas.drawBitmap(bitmapBg, src0, dst0, paint); } } 重写系统的触摸时间,判断触摸点在背景范围内还是背景范围外 @Override public b

    2024年04月12日
    浏览(46)
  • Android 滑动按钮(开关) SwitchCompat 自定义风格

    原生的SwitchCompat控件如下图,不说不堪入目,也算是不敢恭维了。开个玩笑... 所以我们就需要对SwitchCompat进行自定义风格,效果如下图 代码如下 从上面的xml代码来看其实只需要定制两个东西一个是thumb,另一个是track switch_thumb switch_track_style switch_track_style里面有两个背景如下

    2024年02月03日
    浏览(30)
  • [Android]自定义RecyclerView中View的动画

    官方有一个默认Item动画类DafaultItemAnimator,其中 DefaultItemAnimator 继承了SimpleItemAnimator 继承了 RecyclerView.ItemAnimator SimpleItemAnimator 它是一个包装类,用来判断当前的ViewHolder到底是执行移动、移除、添加或者改变等行为。 DefaultItemAnimator 是执行具体动画类,它负责将viewHolder初始化

    2024年02月11日
    浏览(66)
  • Android 滑动条、Slider、Seekbar深度自定义

    为了更好的满足日常开发中对Slider控件的各种需要,以下我们来看下基于nifty-slider来定制我们所需的各种功能及交互效果 支持滑动条起始值结束值的自定义 支持滑动条指定步长以实现类似刻度的功能 支持对滑块的自定义以添加光环效果、滑块形状,滑块投影、滑块边框、滑

    2024年02月12日
    浏览(43)
  • Android自定义View之游戏摇杆键盘实现(一)

    public class RemoteViewBg { private Bitmap bitmapBg; public RemoteViewBg(Bitmap bitmap) { bitmapBg = bitmap; } //背景的绘图函数 public void draw(Canvas canvas, Paint paint, Rect src0 ,Rect dst0 ) { canvas.drawBitmap(bitmapBg, src0, dst0, paint); } } 重写系统的触摸时间,判断触摸点在背景范围内还是背景范围外 @Override public b

    2024年04月17日
    浏览(54)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包