Android开发求助:实现图片选择、清除及跨Activity传递功能
Alright, let's build out the complete functionality for your Attachment_class Activity. I'll walk you through each part with full, working code so you can implement everything smoothly.
1. First, Finalize the Layout File (res/layout/attachment.xml)
You'll need a structured layout to arrange your ImageViews and buttons. Here's a flexible ConstraintLayout example that aligns all elements neatly:
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="16dp"> <!-- First Image Section --> <ImageView android:id="@+id/ImgView_One" android:layout_width="200dp" android:layout_height="200dp" android:background="#E0E0E0" android:contentDescription="First selected image" app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent" /> <Button android:id="@+id/Broswe_image_one" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Browse Image 1" app:layout_constraintTop_toBottomOf="@id/ImgView_One" app:layout_constraintStart_toStartOf="@id/ImgView_One" android:layout_marginTop="8dp"/> <Button android:id="@+id/Cancel_ImgView_One" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Cancel" app:layout_constraintTop_toBottomOf="@id/ImgView_One" app:layout_constraintEnd_toEndOf="@id/ImgView_One" android:layout_marginTop="8dp"/> <!-- Second Image Section --> <ImageView android:id="@+id/ImgView_Two" android:layout_width="200dp" android:layout_height="200dp" android:background="#E0E0E0" android:contentDescription="Second selected image" app:layout_constraintTop_toTopOf="parent" app:layout_constraintEnd_toEndOf="parent" /> <Button android:id="@+id/Broswe_image_two" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Browse Image 2" app:layout_constraintTop_toBottomOf="@id/ImgView_Two" app:layout_constraintStart_toStartOf="@id/ImgView_Two" android:layout_marginTop="8dp"/> <Button android:id="@+id/Cancel_ImgView_Two" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Cancel" app:layout_constraintTop_toBottomOf="@id/ImgView_Two" app:layout_constraintEnd_toEndOf="@id/ImgView_Two" android:layout_marginTop="8dp"/> <!-- Next Button --> <Button android:id="@+id/Next_Attch_Btn" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Next" app:layout_constraintBottom_toBottomOf="parent" android:layout_marginTop="32dp"/> </androidx.constraintlayout.widget.ConstraintLayout>
2. Complete the Attachment_class.java Code
We'll use the modern ActivityResultContracts API (replacing the deprecated onActivityResult) to handle gallery selection, add cancel functionality, and pass images to the next Activity. We'll also handle permissions for newer Android versions.
import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.contract.ActivityResultContracts; import androidx.appcompat.app.AppCompatActivity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.provider.MediaStore; import android.view.View; import android.widget.Button; import android.widget.ImageView; public class Attachment_class extends AppCompatActivity { private ImageView img_One, img_Two; private Button btn_Browse_Image_One, btn_Cancel_Image_One; private Button btn_Browse_Image_Two, btn_Cancel_Image_Two; private Button btn_Next; // Store selected image URIs (avoids memory issues vs passing Bitmaps) private Uri imageUriOne, imageUriTwo; // Launcher for gallery selection private final ActivityResultLauncher<Intent> galleryLauncher = registerForActivityResult( new ActivityResultContracts.StartActivityForResult(), result -> { if (result.getResultCode() == RESULT_OK && result.getData() != null) { Uri selectedImageUri = result.getData().getData(); // Map selection to the correct ImageView if (currentBrowseButton == 1) { img_One.setImageURI(selectedImageUri); imageUriOne = selectedImageUri; } else if (currentBrowseButton == 2) { img_Two.setImageURI(selectedImageUri); imageUriTwo = selectedImageUri; } } } ); // Track which browse button was tapped private int currentBrowseButton; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.attachment); initViews(); setupClickListeners(); } private void initViews() { img_One = findViewById(R.id.ImgView_One); btn_Browse_Image_One = findViewById(R.id.Broswe_image_one); btn_Cancel_Image_One = findViewById(R.id.Cancel_ImgView_One); img_Two = findViewById(R.id.ImgView_Two); btn_Browse_Image_Two = findViewById(R.id.Broswe_image_two); btn_Cancel_Image_Two = findViewById(R.id.Cancel_ImgView_Two); btn_Next = findViewById(R.id.Next_Attch_Btn); } private void setupClickListeners() { // Browse Image 1 btn_Browse_Image_One.setOnClickListener(v -> { currentBrowseButton = 1; openGallery(); }); // Cancel Image 1 btn_Cancel_Image_One.setOnClickListener(v -> { img_One.setImageDrawable(null); imageUriOne = null; }); // Browse Image 2 btn_Browse_Image_Two.setOnClickListener(v -> { currentBrowseButton = 2; openGallery(); }); // Cancel Image 2 btn_Cancel_Image_Two.setOnClickListener(v -> { img_Two.setImageDrawable(null); imageUriTwo = null; }); // Next Button: Pass images to next Activity btn_Next.setOnClickListener(v -> { Intent intent = new Intent(Attachment_class.this, NextActivity.class); // Pass URIs as strings (since Uri is parcelable but string is safer) if (imageUriOne != null) { intent.putExtra("IMAGE_URI_ONE", imageUriOne.toString()); } if (imageUriTwo != null) { intent.putExtra("IMAGE_URI_TWO", imageUriTwo.toString()); } startActivity(intent); }); } private void openGallery() { Intent galleryIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); galleryLauncher.launch(galleryIntent); } }
3. Create NextActivity to Receive and Display Images
You'll need a simple Activity to show the passed images. Here's the code:
NextActivity.java
import androidx.appcompat.app.AppCompatActivity; import android.net.Uri; import android.os.Bundle; import android.widget.ImageView; public class NextActivity extends AppCompatActivity { private ImageView imgReceivedOne, imgReceivedTwo; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_next); imgReceivedOne = findViewById(R.id.img_received_one); imgReceivedTwo = findViewById(R.id.img_received_two); // Retrieve passed image URIs String imageUriOneStr = getIntent().getStringExtra("IMAGE_URI_ONE"); String imageUriTwoStr = getIntent().getStringExtra("IMAGE_URI_TWO"); if (imageUriOneStr != null) { Uri imageUriOne = Uri.parse(imageUriOneStr); imgReceivedOne.setImageURI(imageUriOne); } if (imageUriTwoStr != null) { Uri imageUriTwo = Uri.parse(imageUriTwoStr); imgReceivedTwo.setImageURI(imageUriTwo); } } }
res/layout/activity_next.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="16dp" android:gravity="center"> <ImageView android:id="@+id/img_received_one" android:layout_width="200dp" android:layout_height="200dp" android:background="#E0E0E0" android:contentDescription="First received image"/> <ImageView android:id="@+id/img_received_two" android:layout_width="200dp" android:layout_height="200dp" android:background="#E0E0E0" android:contentDescription="Second received image" android:layout_marginTop="16dp"/> </LinearLayout>
4. Add Required Permissions
Add these lines to your AndroidManifest.xml to enable image access:
<!-- For Android 12 and below --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32"/> <!-- For Android 13+ --> <uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
Quick Notes:
- We use
Uriinstead ofBitmapto pass images because Bitmaps can cause memory overflow with large files. - The
ActivityResultContractsAPI is the official recommended replacement foronActivityResult. - Cancel buttons clear both the ImageView and stored URI to ensure no invalid data is passed to the next Activity.
内容的提问来源于stack exchange,提问作者Mohamed Hassan Yousif Binyousi

