如何为ViewPager2设置仅左侧带有圆角的背景图片
我完全懂你碰到的这个棘手问题——既要让图片按自身比例撑满ViewPager2,又得保留左侧的圆角效果,用centerCrop时圆角被图片盖得严严实实,换其他scaleType又填不满容器,确实头疼。下面给你两个实用的解决方案:
方案一:用clipToOutline实现图片圆角裁剪
这个思路是让ImageView自身的轮廓带上左侧圆角,然后把图片裁剪到这个轮廓里,这样图片缩放时就会被圆角“切”出形状,不会覆盖掉圆角效果。
步骤1:修改ImageView布局
去掉原来的android:background,添加android:clipToOutline="true",保持scaleType="centerCrop":
<ImageView android:id="@+id/backgroundImage" android:layout_width="975dp" android:layout_height="match_parent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" android:src="@drawable/grey_hexagon_tiles" android:scaleType="centerCrop" android:clipToOutline="true" />
步骤2:代码中设置自定义轮廓
给ImageView设置只裁剪左侧圆角的OutlineProvider:
val imageView = findViewById<ImageView>(R.id.backgroundImage) imageView.outlineProvider = object : ViewOutlineProvider() { override fun getOutline(view: View, outline: Outline) { val cornerRadius = resources.getDimensionPixelSize(R.dimen.corner_radius_20dp).toFloat() // 用Path绘制仅左侧带圆角的矩形轮廓 val path = Path() path.addRoundRect( RectF(0f, 0f, view.width.toFloat(), view.height.toFloat()), floatArrayOf(cornerRadius, cornerRadius, 0f, 0f, 0f, 0f, cornerRadius, cornerRadius), Path.Direction.CW ) outline.setConvexPath(path) } }
这样设置后,图片会被精准裁剪成左侧带圆角的形状,同时centerCrop的缩放效果完全保留,能填满整个容器。
方案二:用LayerDrawable组合背景与图片
这个方法纯靠XML就能实现,把圆角背景和图片合并成一个图层,让图片叠在圆角背景上方,既保留缩放效果又能显示圆角。
步骤1:创建LayerDrawable文件
新建layer_background.xml:
<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 底层的左侧圆角背景 --> <item android:drawable="@drawable/rounded_corners_left_only"/> <!-- 上层的图片,设置centerCrop缩放 --> <item> <bitmap android:src="@drawable/grey_hexagon_tiles" android:gravity="center" android:scaleType="centerCrop"/> </item> </layer-list>
步骤2:给ImageView设置这个图层
去掉原来的android:background,把android:src指向这个LayerDrawable:
<ImageView android:layout_width="975dp" android:layout_height="match_parent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" android:src="@drawable/layer_background" android:scaleType="centerCrop" />
为啥原来的方法行不通?
你之前的问题核心在于:android:background是绘制在ImageView底层的,而android:src的图片在顶层。用centerCrop时,图片会完全铺满ImageView,直接盖住了底层的圆角背景;换其他scaleType时,图片没填满容器,圆角能看到,但又达不到“撑满”的需求。上面两个方案要么让图片跟着圆角轮廓走,要么把图片和圆角背景绑定成一个整体,完美解决了这两个矛盾点。
内容的提问来源于stack exchange,提问作者Joven Pua

