Search code examples
androidandroid-imageviewandroid-recyclerview

Android - List images from external storage into Recycleview


I'm trying to do a simple thing and its get all images from the external storage into recycle view and display them.

My problem is that for some reason i recieve null and i dont know why. I successfully getting all the images into array list of string. And then on the Reycleview i'm getting error of null exception. Cant find what im doing wrong.

The log shows me that the error comes from the Recycler.From the method "onBindViewHolder" (i also mentioned this line). It craches holder.imgView.setImageURI(imageUri); - still cant understand why, even though i checked that its not null.

My Code

          private BootstrapButton btnLoadImage;
private RecyclerView rvImages;
private static final int REQUEST_CODE = 1;
private boolean mStoragePermissions;
private ArrayList<String> imageLists;
private ImageViewAdapter adapter;


     @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);


    btnLoadImage = (BootstrapButton)findViewById(R.id.btnLoadImges);
    rvImages = (RecyclerView)findViewById(R.id.rvPictures);


    btnLoadImage.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if(mStoragePermissions){
                imageLists = getFilePaths();
                Log.d("MainActivity",imageLists.toString());
                if(imageLists != null)
                    setAdapter(imageLists);
            }else{
                verifyStoragePermissions();
            }

        }
    });
}

private void setAdapter(ArrayList<String> imageLists) {
    adapter = new ImageViewAdapter(getApplication(),imageLists);
    rvImages.setAdapter(adapter);
    rvImages.setLayoutManager(new GridLayoutManager(getApplication(),3));
    btnLoadImage.setVisibility(View.INVISIBLE);
}

    public ArrayList<String> getFilePaths()
{


    Uri u = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
    String[] projection = {MediaStore.Images.ImageColumns.DATA};
    Cursor c = null;
    SortedSet<String> dirList = new TreeSet<String>();
    ArrayList<String> resultIAV = new ArrayList<String>();

    String[] directories = null;
    if (u != null)
    {
        c = managedQuery(u, projection, null, null, null);
    }

    if ((c != null) && (c.moveToFirst()))
    {
        do
        {
            String tempDir = c.getString(0);
            tempDir = tempDir.substring(0, tempDir.lastIndexOf("/"));
            try{
                dirList.add(tempDir);
            }
            catch(Exception e)
            {
                Log.d("MainActivity",e.getMessage().toString());
            }
        }
        while (c.moveToNext());
        directories = new String[dirList.size()];
        dirList.toArray(directories);

    }

    for(int i=0;i<dirList.size();i++)
    {
        File imageDir = new File(directories[i]);
        File[] imageList = imageDir.listFiles();
        if(imageList == null)
            continue;
        for (File imagePath : imageList) {
            try {

                if(imagePath.isDirectory())
                {
                    imageList = imagePath.listFiles();

                }
                if ( imagePath.getName().contains(".jpg")|| imagePath.getName().contains(".JPG")
                        || imagePath.getName().contains(".jpeg")|| imagePath.getName().contains(".JPEG")
                        || imagePath.getName().contains(".png") || imagePath.getName().contains(".PNG") )
                {
                    String path= imagePath.getAbsolutePath();

                    resultIAV.add(path);
                }
            }
            //  }
            catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    return resultIAV;

}


public class ImageViewAdapter extends RecyclerView.Adapter<ImageViewHolder>{
    private LayoutInflater inflater;
    private Context context;
    private ArrayList<String> data;

    public ImageViewAdapter(Context context, ArrayList<String> data){
        this.context = context;
        this.inflater = LayoutInflater.from(context);
        this.data = data;
    }

    @NonNull
    @Override
    public ImageViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View v = inflater.inflate(R.layout.image_item,parent,false);
        return new ImageViewHolder(v);
    }

    @Override
    public void onBindViewHolder(@NonNull ImageViewHolder holder, int position) {
            String imgSrc = data.get(position);
            Uri imageUri = Uri.parse(imgSrc);

            if(imageUri != null) {
               //**Here i always getting null exception **
                holder.imgView.setImageURI(imageUri);
            }
    }

    @Override
    public int getItemCount() {
        return data.size();
    }

}


public class ImageViewHolder extends RecyclerView.ViewHolder{
    private ImageView imgView;

    public ImageViewHolder(View itemView){
        super(itemView);
        imgView = (ImageView)findViewById(R.id.imageView);
    }
   }
  }

Solution

  • What is null is this in your ImageViewHolder

    ImageView imgView;
    You're using

    imgView = (ImageView)findViewById(R.id.imageView);

    But look that findViewById is finding a view in your activity, and not in your RecyclerView ViewHolder, precisely in your image_item.xml root layout.

    So, just use findViewById in that view:

    public ImageViewHolder(View itemView){
        super(itemView);
        imgView = (ImageView) itemView.findViewById(R.id.imageView);
    }