android怎么实现可拖动的浮动view
发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,本篇内容主要讲解"android怎么实现可拖动的浮动view",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"android怎么实现可拖动的浮动view"吧!
千家信息网最后更新 2026年11月01日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安全错误
数据库的锁怎样保障安全
上海睿民互联网科技有限公司
广州万易互联网科技有限公司
科技互联网产品
科技平台互联网
互联网金融监管科技数据
互联网中国科技
麻工互联网科技
上海互联网科技有限公司
广州宏创互联网科技
互联网科技ppt模板
上游互联网科技
随着互联网科技发展
汽车互联网创新科技园
互联网科技公司有风险吗
西安小鹰速贷互联网科技有限公司
北京市互联网新科技
中国互联网有什么科技
雨阳互联网卡科技有限公司
杭州披云加互联网科技有限公司
利用互联网等科技手段
中关村互联网科技集团
没上市的科技互联网公司
西安互联网科技公司
成都狮子座互联网科技
多迪互联网科技有限公司
青岛科技大学互联网大赛研究生
群盈汇互联网科技有限公司
互联网企业科技类企业如何做账
科技信息时代互联网发展
数字科技和互联网金融哪个好