如何在同一ViewGroup内按百分比平移圆形图片?
在ViewGroup内按百分比平移圆形图片的实现方案
嗨,针对你想要在同一个ViewGroup内按百分比平移圆形图片的需求,我给你整理了几种实用的实现方案,你可以根据自己的布局场景来选择:
我希望在同一个ViewGroup内按百分比平移这张圆形图片,新位置将根据获取的数据设置为30%、50%或100%等任意比例。
方法一:用ConstraintLayout(最推荐!)
如果你父布局用的是ConstraintLayout,那直接用它自带的百分比偏置属性就能搞定,几乎不用写额外代码:
- 先把圆形图片的父布局设为ConstraintLayout
- 给ImageView加上
app:layout_constraintHorizontal_bias属性,值就是你要的百分比(比如30%填0.3,50%填0.5) - 给你个xml示例:
<androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <ImageView android:id="@+id/circle_img" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/你的圆形图片" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintHorizontal_bias="0.3" /> <!-- 这里就是30%的比例 --> </androidx.constraintlayout.widget.ConstraintLayout>
要是需要根据后台数据动态改比例,代码里这么写就行:
val circleImg = findViewById<ImageView>(R.id.circle_img) val parentLayout = findViewById<ConstraintLayout>(R.id.parent_layout) val constraintSet = ConstraintSet() constraintSet.clone(parentLayout) constraintSet.setHorizontalBias(R.id.circle_img, 0.5f) // 这里动态设成50% constraintSet.applyTo(parentLayout)
方法二:代码动态算平移距离(适配其他布局)
如果你的父布局是LinearLayout、FrameLayout这类普通布局,那就自己算平移距离就行,分两种方式:
方式1:用translationX(简单平移,不改变布局位置)
这种方式是让图片直接平移,不会影响其他View的布局,适合只是视觉上移动的场景:
val circleImg = findViewById<ImageView>(R.id.circle_img) val parentViewGroup = findViewById<ViewGroup>(R.id.parent_layout) // 注意要等父布局测量完再拿宽度,不然会拿到0 parentViewGroup.post { val parentWidth = parentViewGroup.width val targetPercent = 0.3f // 目标30% // 减去自身宽度一半是为了让图片中心对齐比例位置,要是你想让左边缘对齐就去掉这部分 val translateX = parentWidth * targetPercent - circleImg.width / 2 circleImg.translationX = translateX }
方式2:修改LayoutParams(改变布局位置)
要是你需要改变图片在布局里的真实位置(比如影响其他View的排列),就改LayoutParams:
以水平方向的LinearLayout为例:
val circleImg = findViewById<ImageView>(R.id.circle_img) val parentViewGroup = findViewById<LinearLayout>(R.id.parent_layout) parentViewGroup.post { val parentWidth = parentViewGroup.width val targetPercent = 0.5f // 目标50% val params = circleImg.layoutParams as LinearLayout.LayoutParams // 同样,减去自身宽度一半让中心对齐比例 params.leftMargin = (parentWidth * targetPercent - circleImg.width / 2).toInt() circleImg.layoutParams = params }
方法三:自定义ViewGroup(灵活度拉满)
如果需要更复杂的控制,比如同时支持垂直方向的百分比平移,或者有特殊的布局逻辑,那就自定义一个ViewGroup:
class PercentageLayout @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 ) : ViewGroup(context, attrs, defStyleAttr) { private var horizontalPercent = 0.5f // 默认居中50% // 对外暴露设置百分比的方法 fun setHorizontalPercentage(percent: Float) { // 限制在0-1之间,防止传错值 horizontalPercent = percent.coerceIn(0f, 1f) requestLayout() } override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { // 先测量子View的大小 val child = getChildAt(0) measureChild(child, widthMeasureSpec, heightMeasureSpec) // 把ViewGroup的高度设成子View的高度,宽度跟着父布局走 setMeasuredDimension( MeasureSpec.getSize(widthMeasureSpec), child.measuredHeight ) } override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) { val child = getChildAt(0) val childWidth = child.measuredWidth val parentWidth = r - l // 计算左边的位置,让中心对齐目标百分比 val left = (parentWidth * horizontalPercent - childWidth / 2).toInt() // 垂直方向居中 val top = (b - t - child.measuredHeight) / 2 child.layout(left, top, left + childWidth, top + child.measuredHeight) } }
然后在布局里用这个自定义View:
<com.你的包名.PercentageLayout android:id="@+id/percentage_layout" android:layout_width="match_parent" android:layout_height="wrap_content"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/你的圆形图片" /> </com.你的包名.PercentageLayout>
代码里动态设置比例:
val percentageLayout = findViewById<PercentageLayout>(R.id.percentage_layout) percentageLayout.setHorizontalPercentage(0.8f) // 设置成80%的位置
内容的提问来源于stack exchange,提问作者Deepak sahu
相关产品推荐
相关产品推荐

