RecyclerView条目点击设图至Activity的ImageView时非空View报错解决
Hey there, let's break down why you're hitting that frustrating error and get your image loading working smoothly!
Why the Error Happens
The root issue here is that you're trying to directly access the img_back ImageView (from activity_set_back.xml) inside your MoviesAdapter—and that won't work. Adapters are only responsible for inflating and managing RecyclerView item layouts, not the parent Activity's layout. When you call findViewById in the Adapter, it can't traverse up to the Activity's view hierarchy, so it returns null. Trying to set an image to a null View throws that "non null View" error.
The Correct Solution: Use an Interface Callback
We'll use a callback to pass the selected image URL from the Adapter to your Activity, where you can safely access img_back and set the image. Here's how to implement it step by step:
Step 1: Add a Click Listener Interface to Your MoviesAdapter
Modify your MoviesAdapter to define a callback interface and accept it in the constructor:
public class MoviesAdapter extends RecyclerView.Adapter<MoviesAdapter.ViewHolder> { private ArrayList<String> moviesList; private OnItemClickListener clickListener; // Define the callback interface public interface OnItemClickListener { void onMovieItemClicked(String selectedImageUrl); } // Update constructor to accept the listener public MoviesAdapter(ArrayList<String> moviesList, OnItemClickListener listener) { this.moviesList = moviesList; this.clickListener = listener; } // ... Your existing ViewHolder, onCreateViewHolder code ... @Override public void onBindViewHolder(@NonNull ViewHolder holder, int position) { String currentImageUrl = moviesList.get(position); // Set click listener on the entire item view holder.itemView.setOnClickListener(v -> { // Trigger the callback with the selected image URL if (clickListener != null) { clickListener.onMovieItemClicked(currentImageUrl); } }); } public static class ViewHolder extends RecyclerView.ViewHolder { // Initialize your item's views here (e.g., item's ImageView if needed) public ViewHolder(@NonNull View itemView) { super(itemView); // Example: itemImageView = itemView.findViewById(R.id.item_image); } } }
Step 2: Implement the Callback in Your Activity
In your Activity that hosts the RecyclerView and img_back, implement the interface and handle the image loading:
public class SetBackActivity extends AppCompatActivity implements MoviesAdapter.OnItemClickListener { private ImageView imgBack; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_set_back); // Initialize the Activity's ImageView (this will NOT be null here!) imgBack = findViewById(R.id.img_back); // Set up your RecyclerView RecyclerView recyclerView = findViewById(R.id.your_recyclerview_id); recyclerView.setLayoutManager(new LinearLayoutManager(this)); // Pass 'this' as the click listener to the Adapter MoviesAdapter adapter = new MoviesAdapter(moviesList, this); recyclerView.setAdapter(adapter); } @Override public void onMovieItemClicked(String selectedImageUrl) { // Load the selected image into imgBack here // Use a library like Glide or Picasso for reliable image loading (recommended) // Example with Glide: Glide.with(this) .load(selectedImageUrl) .placeholder(R.drawable.placeholder_image) // Optional: add a placeholder .error(R.drawable.error_image) // Optional: add an error fallback .into(imgBack); // If you want to use native Android methods (note: requires async handling for network images) // new ImageLoadTask(selectedImageUrl, imgBack).execute(); } }
Key Notes
- Never access Activity views directly from an Adapter: Adapters should only focus on their own items. Using callbacks keeps your code clean and avoids null reference errors.
- Use Image Loading Libraries: Libraries like Glide or Picasso handle network requests, caching, and image resizing automatically—way better than rolling your own async loader.
内容的提问来源于stack exchange,提问作者Kamalesh M. Talaviya

