Tuesday, November 19, 2024
Google search engine
HomeLanguagesJavaHow to Build an Image Gallery Android App with RecyclerView and Glide?

How to Build an Image Gallery Android App with RecyclerView and Glide?

In today’s tech-savvy world, we are accustomed to having all our photos at our fingertips. Whether you’re developing a social media app or a photo-editing tool, integrating a user-friendly image gallery is crucial. This article will walk you through the process of creating a simple yet effective image gallery in Android using RecyclerView, Glide, and permission handling.

Pre-requisites:

To follow this tutorial, you should have: Basic understanding of Android app development using Kotlin or Java Familiarity with RecyclerView, and an Adapter Understanding of Android permission handling Android Studio installed on your machine. Make sure to add the Glide library to your build.gradle file:

XML




implementation("com.github.bumptech.glide:glide:4.14.2")


XML




dependencies {
    implementation("androidx.appcompat:appcompat:1.6.1")
    implementation("com.google.android.material:material:1.9.0")
    implementation("androidx.constraintlayout:constraintlayout:2.1.4")
    implementation("com.github.bumptech.glide:glide:4.14.2")
    testImplementation("junit:junit:4.13.2")
    androidTestImplementation("androidx.test.ext:junit:1.1.5")
    androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
}


Building the Image Gallery

Let’s dive into the main components of our application:

1. Custom Adapter

The GalleryAdapter is a custom adapter responsible for binding images to the RecyclerView. It includes an ArrayList that contains the paths of the images and uses Glide to load them into an ImageView. The ViewHolder inner class references the ImageView where each image will be displayed. Here’s a snapshot of the GalleryAdapter class:

Java




package com.example.piceditor;
 
import android.content.Context;
import android.text.Layout;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
 
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
 
import com.bumptech.glide.Glide;
 
import java.io.File;
import java.util.ArrayList;
 
public class GalleryAdapter extends RecyclerView.Adapter<GalleryAdapter.ViewHolder> {
 
    private Context context;
    private ArrayList<String> images_list;
 
    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view= LayoutInflater.from(context).inflate(R.layout.gellary_item,null,true);
        return new ViewHolder(view);
    }
 
    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        File image_file=new File(images_list.get(position));
        if(image_file.exists()){
            Glide.with(context).load(image_file).into(holder.image);
        }
    }
 
    @Override
    public int getItemCount() {
        return images_list.size();
    }
 
    public GalleryAdapter(Context context, ArrayList<String> images_list) {
        this.context = context;
        this.images_list = images_list;
    }
 
    public class ViewHolder extends RecyclerView.ViewHolder{
        private ImageView image;
        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            image=itemView.findViewById(R.id.gallery_item);
        }
    }
}


2. MainActivity

In MainActivity, we set up the RecyclerView with a GridLayoutManager. We also implement permission handling to access external storage and load the images into our ArrayList.

Java




package com.example.piceditor;
 
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
import static android.os.Environment.MEDIA_MOUNTED;
 
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
 
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.widget.TextView;
import android.widget.Toast;
 
import java.util.ArrayList;
 
public class MainActivity extends AppCompatActivity {
 
    static int PERMISSION_REQUEST_CODE=100;
    RecyclerView recyclerView;
    ArrayList<String> images;
    GalleryAdapter adapter;
    GridLayoutManager manager;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        recyclerView=findViewById(R.id.gallery_recycler);
        images=new ArrayList<>();
        adapter=new GalleryAdapter(this,images);
        manager=new GridLayoutManager(this,3);
 
        recyclerView.setAdapter(adapter);
        recyclerView.setLayoutManager(manager);
        checkPermissions();
 
    }
 
    private void checkPermissions() {
        int result= ContextCompat.checkSelfPermission(getApplicationContext(),READ_EXTERNAL_STORAGE);
    if(result== PackageManager.PERMISSION_GRANTED){
            loadImages();
        }else{
        ActivityCompat.requestPermissions(this,new String[]{READ_EXTERNAL_STORAGE},PERMISSION_REQUEST_CODE);
    }
    }
 
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if(grantResults.length > 0){
        boolean accepted=grantResults[0]==PackageManager.PERMISSION_GRANTED;
        if(accepted){
            loadImages();
        }else{
            Toast.makeText(this,"You have dined the permission",Toast.LENGTH_LONG).show();
        }
    }else{
 
    }
    }
 
    private void loadImages() {
        boolean SDCard= Environment.getExternalStorageState().equals(MEDIA_MOUNTED);
    if(SDCard){
        final String[] colums={MediaStore.Images.Media.DATA,MediaStore.Images.Media._ID};
        final String order=MediaStore.Images.Media.DATE_TAKEN+" DESC";
        Cursor cursor=getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,colums,null,null,order);
        int count =cursor.getCount();
        for(int i=0;i<count;i++){
            cursor.moveToPosition(i);
            int colunmindex=cursor.getColumnIndex(MediaStore.Images.Media.DATA);
            images.add(cursor.getString(colunmindex));
        }
        recyclerView.getAdapter().notifyDataSetChanged();
    }
    }
}


3. XML Layout

The XML layouts for our activity and gallery items are straightforward. We use a RelativeLayout containing a RecyclerView for the main activity. Each item in the RecyclerView is a CardView containing an ImageView.

MainActivity Layout:

In the activity_main.xml file, we layout the RecyclerView along with a TextView displaying “All Photos.”

XML




<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
 
    <TextView
        android:id="@+id/textView3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_marginLeft="30dp"
        android:layout_marginEnd="187dp"
        android:fontFamily="@font/nunito_sans_black"
        android:text="All Photos"
        android:textColor="@color/black"
        android:textSize="22sp" />
 
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/gallery_recycler"
        android:layout_width="383dp"
        android:layout_height="621dp"
        android:layout_alignBottom="@+id/textView3"
        android:layout_marginStart="8dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="8dp"
        android:layout_marginBottom="-636dp"/>
 
</RelativeLayout>


These XML files define the visual structure of our image gallery. By combining the RecyclerView with GridLayoutManager, we achieve a grid-like arrangement for our images, and the CardView ensures a consistent look for each image.

Gallery Item Layout:

For individual gallery items, we use a CardView that wraps an ImageView in gallery_item.xml:

XML




<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
 
    <ImageView
        android:id="@+id/gallery_item"
        android:layout_width="120dp"
        android:layout_height="120dp"
        android:layout_margin="1dp"
        android:scaleType="centerCrop" />
 
</androidx.cardview.widget.CardView>


Running the Application and Viewing the Output

Step 1: Set Up Permissions

Before running the application, make sure to declare the necessary permissions for reading external storage in your AndroidManifest.xml file:

XML




<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>


XML




<?xml version="1.0" encoding="utf-8"?>
    xmlns:tools="http://schemas.android.com/tools">
 
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.PicEditor"
        tools:targetApi="31">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
 
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <meta-data
            android:name="preloaded_fonts"
            android:resource="@array/preloaded_fonts" />
    </application>
 
</manifest>


Step 2: Run the Application

Open the project in Android Studio. Connect your Android device or use an emulator. Press the “Run” button (green play symbol) at the top of Android Studio.

Screenshot-2023-08-05-at-02455

RELATED ARTICLES

Most Popular

Recent Comments