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

Android:Glide与直接用ImageView加载图片的尺寸差异问题

Glide加载Drawable与直接设置android:src的图片尺寸差异问题

我有一个LaunchActivity,其中包含一个居中的ImageView,同时准备了不同密度的PNG图片。现在遇到的问题是:使用Glide加载该Drawable图片时,和直接在ImageView中设置android:src="@drawable/my_splash_logo"加载的图片尺寸不一致——Glide加载的图片比直接设置src的更大。

相关代码

LaunchActivity.kt

class LaunchActivity : AppCompatActivity() {
    lateinit var newSplashScreen: SplashScreen
    override fun onCreate(savedInstanceState: Bundle?) {
        newSplashScreen = installSplashScreen()
        overridePendingTransition(0, 0)
        super.onCreate(savedInstanceState)
        requestWindowFeature(Window.FEATURE_NO_TITLE)
        setContentView(R.layout.activity_launch)
        setupStatusBar(R.color.transparent)
        (window.decorView.findViewById(Window.ID_ANDROID_CONTENT) as FrameLayout).foreground = null
        window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN)
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            val controller = window.insetsController

            if (controller != null) {
                controller.hide(WindowInsets.Type.statusBars() or WindowInsets.Type.navigationBars())
                controller.systemBarsBehavior = WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
            }
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            val w = window // in Activity's onCreate() for instance
            w.setFlags(
                WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION,
                WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION
            )
            w.setFlags(
                WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
                WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
            )
            w.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION,
                WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
            w.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
                WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
        }
        Glide.with(this)
            .load(R.drawable.my_splash_logo)
            .into(R.id.splash_logo_imageview)
        // 省略其他代码
    }
}

activity_launch.xml

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:layout_width="@dimen/match_constraint"
  android:layout_height="@dimen/match_constraint">

  <androidx.constraintlayout.widget.ConstraintLayout
    android:id="@+id/splash_screen_logo_layout"
    android:layout_width="match_parent"
    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">

    <ImageView
      android:id="@+id/splash_logo_imageview"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_gravity="center"
      app:layout_constraintBottom_toBottomOf="parent"
      app:layout_constraintEnd_toEndOf="parent"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintTop_toTopOf="parent" />

    <LinearLayout
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:layout_gravity="center_horizontal|bottom"
      android:orientation="vertical"
      app:layout_constraintBottom_toBottomOf="parent"
      app:layout_constraintEnd_toEndOf="parent"
      app:layout_constraintStart_toStartOf="parent">

      <include layout="@layout/my_loading_view" />

      <Space
        android:id="@+id/space"
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:layout_gravity="center_horizontal|bottom"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

    </LinearLayout>

  </androidx.constraintlayout.widget.ConstraintLayout>

</merge>

已尝试的解决方案

  • 设置精确像素:.apply(RequestOptions().override(1110, 1144).centerCrop())
  • 使用centerInside()、circleCrop()、fitCenter()等缩放配置

现在想知道,这种尺寸差异的原因是什么,我忽略了哪些细节?


解决方案

问题核心是Glide与系统默认加载Drawable的密度适配逻辑不同:

  1. 系统直接加载src的逻辑:设置android:src时,系统会根据当前设备的屏幕密度,自动匹配对应密度目录(mdpi/hdpi/xhdpi等)下的图片,并按密度比例缩放,最终显示尺寸符合预设的适配规则。
  2. Glide默认加载逻辑:Glide加载本地Drawable时,默认会忽略系统的密度适配,直接以图片的原始像素尺寸加载,导致图片显示比系统加载的更大。

修复方法

让Glide遵循系统的密度适配规则即可,推荐两种方式:

方法一:使用dontTransform()沿用系统适配

Glide.with(this)
    .load(R.drawable.my_splash_logo)
    .dontTransform()
    .into(R.id.splash_logo_imageview)

该方法让Glide完全复用系统加载Drawable的逻辑,和android:src显示效果完全一致,操作最简单。

方法二:手动指定密度缩放(保留Glide变换能力时用)
如果需要保留Glide的其他变换功能,可以通过配置指定密度比例:

val displayMetrics = resources.displayMetrics
Glide.with(this)
    .load(R.drawable.my_splash_logo)
    .apply(RequestOptions()
        .override(Target.SIZE_ORIGINAL)
        .transform(ScaleTransformation(displayMetrics.density)))
    .into(R.id.splash_logo_imageview)

额外注意:确保不同密度目录下的图片尺寸是按标准比例设计的(比如xhdpi是mdpi的2倍、xxhdpi是3倍),这样无论哪种加载方式都能保证显示一致性。


内容的提问来源于stack exchange,提问作者Wicaledon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 09:45:07