Android中使用Glide为LinearLayout设置背景图时如何保持图片比例?
解决LinearLayout背景左1/3显示图片(保持宽高比)、右2/3显示纯色的问题
你的代码存在几处关键问题:
- 错误地用
Bitmap(resource)创建Drawable,正确应该用BitmapDrawable - 最终将Bitmap直接设为背景,而非创建好的
LayerDrawable - 未给图片Drawable设置显示规则,导致其被拉伸填满整个布局
onResourceReady时LinearLayout可能未完成测量,获取的宽度不准确
方案一:XML LayerList实现(推荐)
静态XML实现更稳定,无需处理代码中的测量逻辑。在drawable文件夹下创建bg_linear_layout.xml:
<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 底层图片:靠左显示,保持宽高比 --> <item> <bitmap android:src="@drawable/backgroundimage" android:gravity="left|center_vertical" android:scaleType="fitStart" /> </item> <!-- 上层灰色遮罩:覆盖右侧2/3区域 --> <item android:left="33.33%"> <shape android:shape="rectangle"> <solid android:color="@android:color/darker_gray" /> </shape> </item> </layer-list>
直接在布局中引用该背景:
<LinearLayout android:id="@+id/myLinearLayout" android:orientation="horizontal" android:layout_height="wrap_content" android:layout_width="match_parent" android:background="@drawable/bg_linear_layout" />
方案二:动态代码修正(适用于动态加载图片场景)
如果图片是网络资源或需动态加载,修正代码如下:
val linearLayout = findViewById<LinearLayout>(R.id.myLinearLayout) // 等待View完成测量后再处理,避免获取到无效宽度 linearLayout.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { override fun onGlobalLayout() { linearLayout.viewTreeObserver.removeOnGlobalLayoutListener(this) val layoutWidth = linearLayout.width if (layoutWidth == 0) return Glide.with(linearLayout.context) .asBitmap() .load(R.drawable.backgroundimage) .into(object : CustomTarget<Bitmap>() { override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) { // 创建图片Drawable,限制宽度为布局的1/3,高度按原比例计算 val targetWidth = layoutWidth / 3 val targetHeight = (resource.height * targetWidth.toFloat() / resource.width).toInt() val bitmapDrawable = BitmapDrawable(linearLayout.resources, resource).apply { gravity = Gravity.LEFT or Gravity.CENTER_VERTICAL setBounds(0, 0, targetWidth, targetHeight) } val colorDrawable = ColorDrawable(Color.GRAY) val layerDrawable = LayerDrawable(arrayOf(bitmapDrawable, colorDrawable)) // 设置灰色层左内边距,使其仅覆盖右侧2/3区域 layerDrawable.setLayerInset(1, layoutWidth / 3, 0, 0, 0) linearLayout.background = layerDrawable } override fun onLoadCleared(placeholder: Drawable?) {} }) } })
你之前尝试的方法无效原因:
dontTransform()仅阻止Glide转换图片,但Drawable仍会被View拉伸填满背景setBounds使用resource.width时,未匹配布局1/3的宽度,且未等待布局测量完成导致数值无效- 将LinearLayout高度设为0会直接隐藏布局,无实际作用
内容的提问来源于stack exchange,提问作者Ankita Jaiswal
相关产品推荐
相关产品推荐

