Android 控件自动贴边实现实例详解
正文
最近接到个需求,需要在用户与App交互时,把SDK中之前实现过的悬浮控件贴边隐藏,结束交互后延迟一段时间再自动显示。本篇文章介绍一下实现的思路。
判断交互
用户与App交互、结束交互可以通过监听触摸事件来实现。建议使用的Activity
的dispatchTouchEvent
,Activity
下的所有触摸事件分发时都会回调此方法,代码如下:
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 App中的Activity组件
这篇文章主要介绍了通过Android App中的Activity组件,包括Activity的定义和继承以及启动等基本知识,需要的朋友可以参考下2016-04-04Android Spinner和GridView组件的使用示例
Spinner其实是一个列表选择框,不过Android的列表选择框并不需要显示下拉列表,而是相当于弹出一个菜单供用户选择,GridView是一个在二维可滚动的网格中展示内容的控件。网格中的内容通过使用adapter自动插入到布局中2022-03-03Android利用碎片fragment实现底部标题栏(Github模板开源)
Fragment可以作为Activity的组成部分,一个Activity可以有多个Fragment,这篇文章主要介绍了Android利用碎片fragment实现底部标题栏(Github模板开源),需要的朋友可以参考下2019-12-12Android编程实现的自定义弹窗(PopupWindow)功能示例
这篇文章主要介绍了Android编程实现的自定义弹窗(PopupWindow)功能,结合简单实例形式分析了Android自定义弹窗实现方法与相关注意事项,需要的朋友可以参考下2017-03-03Android编程实现图片放大缩小功能ZoomControls控件用法实例
这篇文章主要介绍了Android编程实现图片放大缩小功能ZoomControls控件用法,结合具体实例形式分析了Android ZoomControls控件实现图片缩放的具体操作方法与相关注意事项,需要的朋友可以参考下2017-09-09Android WebRTC 对 AudioRecord 的使用技术分享
这篇文章主要介绍了Android WebRTC 对 AudioRecord 的使用技术分享,AudioRecord 是 Android 基于原始PCM音频数据录制的类,接下来和小编进入文章了解更详细的内容吧2022-02-02Android使用TextInputLayout创建登陆页面
这篇文章主要为大家详细介绍了Android使用TextInputLayout创建登陆页面,具有一定的参考价值,感兴趣的小伙伴们可以参考一下2017-10-10
最新评论