Android 控件自动贴边实现实例详解

 更新时间:2022年11月27日 14:37:41   作者:ChenYhong  
这篇文章主要为大家介绍了Android 控件自动贴边实现实例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

正文

最近接到个需求,需要在用户与App交互时,把SDK中之前实现过的悬浮控件贴边隐藏,结束交互后延迟一段时间再自动显示。本篇文章介绍一下实现的思路。

判断交互

用户与App交互、结束交互可以通过监听触摸事件来实现。建议使用的ActivitydispatchTouchEventActivity下的所有触摸事件分发时都会回调此方法,代码如下:

class AutoEdgeHideActivity : BaseGestureDetectorActivity() {
    override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
        when (ev.action) {
            MotionEvent.ACTION_DOWN -> {
                // 手指按下,开始本次交互
                // 在此实现隐藏逻辑
            }
            MotionEvent.ACTION_UP -> {
                // 手指抬起,结束本次交互
                // 在此实现延迟显示功能
            }
        }
        return super.dispatchTouchEvent(ev)
    }
}

隐藏与显示

想要实现的效果是当用户与App交互时,悬浮控件平移贴边,但保留一部分显示。结束交互延迟一段时间后,悬浮控件平移回原来的位置。

此处通过ValueAnimator来实现,计算好控件的起始和结束位置,然后改变控件的x坐标,代码如下:

private fun xCoordinateAnimator(view: View, startX: Float, endX: Float) {
    val animator = ValueAnimator.ofFloat(startX, endX)
    animator.addUpdateListener {
        // 不断更改控件的X坐标
        view.x = it.animatedValue as Float
    }
    // 设置插值器,速度由快变慢
    animator.interpolator = DecelerateInterpolator()
    // 设置动画的持续时间
    animator.duration = 500
    animator.start()
}

示例

整合之后做了个示例Demo,完整代码如下:

class AutoEdgeHideActivity : BaseGestureDetectorActivity() {
    private lateinit var binding: LayoutAutoEdgeHideActivityBinding
    private var widthPixels: Int = 0
    private val autoShowInterval = 2
    private var interacting = false
    private var hidden = false
    private var lastPositionX: Float = 0f
    private val handler = Handler(Looper.myLooper() ?: Looper.getMainLooper())
    private val autoShowRunnable = Runnable { autoShow() }
    @SuppressLint("SetTextI18n")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.layout_auto_edge_hide_activity)
        widthPixels = resources.displayMetrics.widthPixels
        binding.includeTitle.tvTitle.text = "AutoEdgeHideExample"
        binding.vFloatView.setOnClickListener {
            if (hidden) {
                // 当前为隐藏状态,先显示
                // 把之前的延迟线程先取消
                handler.removeCallbacks(autoShowRunnable)
                autoShow()
                Toast.makeText(this, "手动显示控件", Toast.LENGTH_SHORT).show()
            } else {
                // 相应正常的事件
                Toast.makeText(this, "点击了浮标控件", Toast.LENGTH_SHORT).show()
            }
        }
    }
    override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
        when (ev.action) {
            MotionEvent.ACTION_DOWN -> {
                if (!checkIsTouchFloatView(ev, binding.vFloatView)) {
                    // 起始ACTION_DOWN事件在浮标控件外,自动隐藏浮标控件,标记正在交互
                    interacting = true
                    handler.removeCallbacks(autoShowRunnable)
                    autoHide()
                }
            }
            MotionEvent.ACTION_UP -> {
                if (interacting) {
                    // 交互结束,一定时间后自动显示,时间可以自由配置
                    interacting = false
                    handler.postDelayed(autoShowRunnable, autoShowInterval * 1000L)
                }
            }
        }
        return super.dispatchTouchEvent(ev)
    }
    /**
     * 检查是否触摸浮标控件
     */
    private fun checkIsTouchFloatView(ev: MotionEvent, view: View): Boolean {
        val screenLocation = IntArray(2)
        view.getLocationOnScreen(screenLocation)
        val viewX = screenLocation[0]
        val viewY = screenLocation[1]
        return (ev.x >= viewX && ev.x <= (viewX + view.width)) && (ev.y >= viewY && ev.y <= (viewY + view.height))
    }
    private fun autoShow() {
        if (hidden) {
            hidden = false
            binding.vFloatView.let {
                xCoordinateAnimator(it, it.x, lastPositionX)
            }
        }
    }
    private fun autoHide() {
        if (!hidden) {
            hidden = true
            binding.vFloatView.let {
                // 记录一下显示状态下的x坐标
                lastPositionX = it.x
                // 隐藏时的x坐标,留一点控件的边缘显示(示例中默认控件在屏幕右侧)
                val endX = widthPixels - it.width * 0.23f
                xCoordinateAnimator(it, lastPositionX, endX)
            }
        }
    }
    private fun xCoordinateAnimator(view: View, startX: Float, endX: Float) {
        val animator = ValueAnimator.ofFloat(startX, endX)
        animator.addUpdateListener {
            view.x = it.animatedValue as Float
        }
        animator.interpolator = DecelerateInterpolator()
        animator.duration = 500
        animator.start()
    }
}

效果如图:

以上就是Android 控件自动贴边实现实例详解的详细内容,更多关于Android 控件自动贴边的资料请关注脚本之家其它相关文章!

相关文章

  • Android中Textview超链接实现方式

    Android中Textview超链接实现方式

    TextView中的超链接可以通过几种方式实现:1.Html.fromHtml,2.Spannable,3.Linkify.addLinks。下面分别进行测试,包括修改字体样式,下划线样式,点击事件等,需要的朋友可以参考下
    2016-02-02
  • Android JobScheduler详细介绍

    Android JobScheduler详细介绍

    JobScheduler是Android 5.0引入的系统服务,它可以根据网络状态、充电状态、电量和存储状况等来触发相应的JobService执行任务,它支持多条件组合、持久性任务,以及在API 21以上版本的Android系统中使用,对Android JobScheduler相关知识感兴趣的朋友跟随小编一起看看吧
    2024-09-09
  • Android实现价格走势自定义曲线图

    Android实现价格走势自定义曲线图

    本篇文章主要介绍了Android实现价格走势曲线图,非常具有实用价值,需要的朋友可以参考下
    2017-04-04
  • Android获取屏幕或View宽度和高度的方法

    Android获取屏幕或View宽度和高度的方法

    这篇文章主要介绍了Android获取屏幕或View宽度和高度的方法,涉及Android针对手机屏幕的相关操作技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2016-02-02
  • Android仿QQ左滑删除置顶ListView操作

    Android仿QQ左滑删除置顶ListView操作

    这篇文章主要为大家详细介绍了Android仿QQ左滑删除置顶ListView操作,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-12-12
  • Android开发实现自定义水平滚动的容器示例

    Android开发实现自定义水平滚动的容器示例

    这篇文章主要介绍了Android开发实现自定义水平滚动的容器,涉及Android滚动容器的事件响应、属性运算与修改相关操作技巧,需要的朋友可以参考下
    2017-10-10
  • Android recyclerView横条指示器实现淘宝菜单模块

    Android recyclerView横条指示器实现淘宝菜单模块

    这篇文章主要为大家详细介绍了recyclerView横条指示器实现淘宝菜单模块,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-02-02
  • Android之网络通信案例分析

    Android之网络通信案例分析

    由于一个项目的需要,我研究了一下android的网络通信方式,大体和java平台的很相似,需要的朋友可以参考下
    2012-11-11
  • android读取扫码模组数据的方法

    android读取扫码模组数据的方法

    这篇文章主要为大家详细介绍了android读取扫码模组数据的方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09
  • Android编程实现图片的浏览、缩放、拖动和自动居中效果

    Android编程实现图片的浏览、缩放、拖动和自动居中效果

    这篇文章主要介绍了Android编程实现图片的浏览、缩放、拖动和自动居中效果,以具体实例形式分析了Android针对图片各种常见显示效果的布局及功能实现技巧,需要的朋友可以参考下
    2015-11-11

最新评论