You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 22:40:21