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的密度适配逻辑不同:
- 系统直接加载src的逻辑:设置
android:src时,系统会根据当前设备的屏幕密度,自动匹配对应密度目录(mdpi/hdpi/xhdpi等)下的图片,并按密度比例缩放,最终显示尺寸符合预设的适配规则。 - 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
相关产品推荐
相关产品推荐

