动态设置ImageView.setImageUri后图片在HorizontalScrollView中不显示求助
Hey there! I’ve run into this exact issue before—let’s break down the most likely reasons your ImageViews aren’t showing up, and how to fix them:
1. Permission Issues (Local File URIs)
If you’re loading images from the device’s storage (like photos from the gallery), missing permissions could block image loading entirely:
- For Android 10 (API 29) and below: You need the
READ_EXTERNAL_STORAGEpermission in yourAndroidManifest.xml, plus runtime permission requests before accessing files. - For Android 11+ (API 30+): Partitioned storage restricts direct access to most files via
file://URIs. Use the MediaStore API to retrieve content URIs, or requestMANAGE_EXTERNAL_STORAGEonly if your app truly needs full storage access (Google discourages this for most use cases).
Add the permissions to your manifest first:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="29"/> <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" android:minSdkVersion="30" tools:ignore="ScopedStorage"/>
2. Incorrect URI Format (Android 7.0+)
Starting with Android 7.0 (API 24), using file:// URIs will throw a FileUriExposedException—you need to use FileProvider to generate a secure content:// URI instead.
Here’s how to set it up:
- Add a FileProvider entry to your
AndroidManifest.xml:
<application> ... <provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths"/> </provider> </application>
- Create
res/xml/file_paths.xmlto define accessible directories:
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-files-path name="my_images" path="Pictures/"/> <!-- Add other paths like external-storage-path if needed --> </paths>
- Generate the valid content URI for your file:
File imageFile = new File(yourImagePath); Uri imageUri = FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", imageFile);
Use this imageUri to set on your ImageView.
3. Missing Layout Parameters for Dynamic ImageViews
When adding ImageViews dynamically, you must explicitly set LayoutParams—without them, the view might have a width/height of 0 and appear invisible.
Example of setting proper params for your LinearLayout:
LinearLayout imageDisplayer = findViewById(R.id.imageDisplayer); // Create and configure the ImageView ImageView imageView = new ImageView(this); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( dpToPx(200), // Convert dp to pixels for consistent sizing LinearLayout.LayoutParams.MATCH_PARENT ); params.setMargins(dpToPx(8), 0, dpToPx(8), 0); // Add spacing between images imageView.setLayoutParams(params); imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); // Ensure images fit nicely // Helper method to convert dp to pixels private int dpToPx(int dp) { return (int) (dp * getResources().getDisplayMetrics().density + 0.5f); } // Set your URI and add to the layout imageView.setImageURI(imageUri); imageDisplayer.addView(imageView);
4. Use an Image Loading Library (More Reliable)
The built-in setImageURI() method is finicky with large images or invalid URIs. Libraries like Glide handle caching, error handling, and URI compatibility automatically.
Example with Glide:
- Add the dependency to your module-level
build.gradle:
implementation 'com.github.bumptech.glide:glide:4.16.0' annotationProcessor 'com.github.bumptech.glide:compiler:4.16.0'
- Load the image with error handling:
Glide.with(this) .load(imageUri) .placeholder(R.drawable.placeholder) // Show a placeholder while loading .error(R.drawable.load_error) // Show an error if loading fails .into(imageView);
This makes it easy to tell if the issue is with the URI (you’ll see the error image instead of blank space).
5. Manually Refresh the Layout (Rarely Needed)
Most of the time, addView() triggers an automatic layout refresh, but if you’re adding images in a loop or off the main thread, you might need to force it:
imageDisplayer.invalidate(); imageDisplayer.requestLayout();
Just ensure all UI operations run on the main thread!
内容的提问来源于stack exchange,提问作者android_monstertjie

