android怎么实现可拖动的浮动view
发表于:2025-01-18 作者:千家信息网编辑
千家信息网最后更新 2025年01月18日,本篇内容主要讲解"android怎么实现可拖动的浮动view",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"android怎么实现可拖动的浮动view"吧!
千家信息网最后更新 2025年01月18日android怎么实现可拖动的浮动view
本篇内容主要讲解"android怎么实现可拖动的浮动view",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"android怎么实现可拖动的浮动view"吧!
业务来源
页面最小化后,需要出现一个浮动 view 告知用户,防止遮挡视线,需要对 view 做可滑动处理
已知会遇到的问题
1.view 的依赖的布局类型未知【为了后续方便扩展】
外界传递 ViewGroup 自己本身继承 LinearLayout【或者其他 ViewGroup 】
class FloatChannelView(var mContext: Context?, var viewGroup: ViewGroup) : LinearLayout(mContext){ private var mIcon: ImageView = ImageView(context) private var mName: TextView = TextView(context) private var mClose: ImageView = ImageView(context) private var iconWH = dip2Px(38) private var groupPadding = dip2Px(3) private var mViewGroupH = dip2Px(44) private var mViewGroupW = dip2Px(152) private var mBoundaryLeft: Float private var mBoundaryTop: Float private var mBoundaryRight: Float private var mBoundaryBottom: Float private var mScreenWidth = getScreenWidth() // 获取屏幕宽高 private var mScreenHeight = getScreenHeight() private var mDownEventX: Float = 0f // 相对控件的x private var mDownEventY: Float = 0f private var mDownX: Float = 0f // 相对屏幕所在的 x private var mDownY: Float = 0f private var mListener: OnClickListener? = null private var mIsStartAnimation: Boolean = false privateval mDefaultMargin = dip2Px(12) private var mMarginLeft = mDefaultMargin private var mMarginTop = mDefaultMargin private var mMarginRight = mDefaultMargin private var mMarginBottom = mDefaultMargin init { layoutParams = LayoutParams(mViewGroupW, mViewGroupH) setPadding(groupPadding, groupPadding, groupPadding, groupPadding) setBackgroundResource(R.drawable.backage) // 建议加一些透明 orientation = HORIZONTAL gravity = Gravity.CENTER_VERTICAL mBoundaryLeft = mMarginLeft.toFloat() mBoundaryTop = mMarginTop.toFloat() mBoundaryRight = mScreenWidth - mMarginRight.toFloat() mBoundaryBottom = (mScreenHeight - mMarginBottom - dip2Px(85)).toFloat() setView() }}
2.拖动事件影响点击,事件分发处理。
override fun onTouchEvent(event: MotionEvent?): Boolean { if (mIsStartAnimation) { // 动画正在进行无需处理 onTouch return true } if (event == null) { return super.onTouchEvent(event) } mIsOnTouch = true //悬浮区域左上角坐标 val x = x val y = y //悬浮区域宽高 val width = mViewGroupW val height = mViewGroupH when (event.actionMasked) { ACTION_DOWN -> { //点击位置坐标 mDownEventX = event.x mDownEventY = event.y mDownX = x mDownY = y } ACTION_UP -> { mUpTime = System.currentTimeMillis() if (mIsMove && abs(mDownX - x) <= 8f && abs(mDownY - y) <= 8f) { mListener?.onClick(this) } mIsMove = false // 抬起后处理边界溢出问题 resilienceAnimation(x, y, x + mViewGroupW, y + mViewGroupH) } ACTION_MOVE -> { val changeX = event.x.toInt() - mDownEventX val changeY = event.y.toInt() - mDownEventY mIsMove = true if (changeX == 0f && changeY == 0f) { return super.onTouchEvent(event) } val left = (x + changeX).toInt() val top = (y + changeY).toInt() val right = left + mViewGroupW val bottom = top + mViewGroupH layout(left, top, right, bottom) } } return true }
3.拖到边界问题。
拖出边界后做了回弹处理
/** * 超出边界回弹 * @param left 当前 x 方向位置 * @param right 当前 y 方向位置*/ private fun resilienceAnimation(left: Float, top: Float, right: Float, bottom: Float) { var startX = 0f var resilienceX = 0f if (mBoundaryLeft <= left && right <= mBoundaryRight) { // x 方向在范围内 // 不处理 } else if (mBoundaryLeft > left) { // left 溢出 startX = 0f resilienceX = mBoundaryLeft - left } else { // right 方向底部溢出 startX = 0f resilienceX = mBoundaryRight - right } var startY = 0f var resilienceY = 0f if (mBoundaryTop <= top && bottom <= mBoundaryBottom) { // y 方向在范围内 // 不处理 } else if (mBoundaryTop > top) { // top 溢出 startY = 0f resilienceY = mBoundaryTop - top } else { // bottom 溢出 startY = 0f resilienceY = mBoundaryBottom - bottom } if (resilienceX == 0f && resilienceY == 0f) { // 在范围内无需回弹 return } // 超出边界回弹 val phaseFirstDuration: Long = 400 var oAnimPhaseFirstTUpX: ObjectAnimator? = null if (resilienceX != 0f) { oAnimPhaseFirstTUpX = ObjectAnimator.ofFloat(this, "translationX", startX, resilienceX) .setDuration(phaseFirstDuration) } var oAnimPhaseFirstTUpY: ObjectAnimator? = null if (resilienceY != 0f) { oAnimPhaseFirstTUpY = ObjectAnimator.ofFloat(this, "translationY", startY, resilienceY) .setDuration(phaseFirstDuration) } val animatorSet = AnimatorSet() if (oAnimPhaseFirstTUpX != null && oAnimPhaseFirstTUpY != null) { animatorSet.play(oAnimPhaseFirstTUpX).with(oAnimPhaseFirstTUpY) } else if (oAnimPhaseFirstTUpX != null) { animatorSet.play(oAnimPhaseFirstTUpX) } else { animatorSet.play(oAnimPhaseFirstTUpY) } animatorSet.childAnimations[animatorSet.childAnimations.size - 1].addListener(object : Animator.AnimatorListener { override fun onAnimationStart(animation: Animator?) { mIsStartAnimation = true } override fun onAnimationEnd(animation: Animator?) { var l = left var t = top var r = right var b = bottom when { mBoundaryLeft > left -> { // x左边溢出 l = mBoundaryLeft r = mBoundaryLeft + mViewGroupW } mBoundaryRight < right -> { // x右边溢出 l = mBoundaryRight - mViewGroupW r = mBoundaryRight } else -> { // x方向未溢出 } } when { mBoundaryTop > top -> { // y 顶部溢出 t = mBoundaryTop b = mBoundaryTop + mViewGroupH } mBoundaryBottom < bottom -> { // y 底部溢出 t = mBoundaryBottom - mViewGroupH b = mBoundaryBottom } else -> { // y方向未溢出 } } // 只进行偏移,实际位置未变化,需要重置偏移量,并重绘 this@FloatChannelView.translationX = 0f this@FloatChannelView.translationY = 0f layout(l.toInt(), t.toInt(), r.toInt(), b.toInt()) mMarginLeft = l.toInt() mMarginTop = t.toInt() mIsStartAnimation = false } override fun onAnimationCancel(animation: Animator?) {} override fun onAnimationRepeat(animation: Animator?) {} }) animatorSet.start()
到此,相信大家对"android怎么实现可拖动的浮动view"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
方向
浮动
位置
边界
处理
事件
内容
区域
坐标
实际
屏幕
底部
问题
偏移
学习
实用
更深
最小
业务
兴趣
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
网络安全产学研
有什么it自学的软件开发
滨州商城软件开发外包公司
《网络安全法》第三十一条
网络安全 建设加密通信
四级数据库工程师真题库
大话西游手游共话江湖服务器
福州金典网络技术有限公司
智邦互联网科技
网络安全五十字作文
erp用云服务器费用
单一业务服务器集群
后台数据是否在服务器内
hdfs服务器
安顺gpu服务器
用u盘插服务器传数据
网络技术研修总结
服务器刷题
页面上传图片到服务器
手机号如何创建我的世界服务器
登录华为帐号显示网络服务器繁忙
软件开发保守项目
软件工程与软件开发哪个好
华为北京服务器代理云主机
dell服务器硬盘检测软件
软件开发高职学校
越秀区数据网络技术开发推荐厂家
办公室建服务器
wdcp恢复数据库
服务器查看数据库