Wednesday, December 25, 2024
Google search engine
HomeLanguagesJavaContent Placeholder Animation using Shimmer in Android with RecyclerView

Content Placeholder Animation using Shimmer in Android with RecyclerView

We have seen the implementation of Content Placeholder Animation using Shimmer in Android for a simple view. In this article, we will take a look at implementing Content Placeholder Animation using Shimmer in Android with RecyclerView

What we are going to build in this article?

We will be building a simple application in which we will be simply displaying data in our Android RecyclerView from our API. For the purpose of loading data, we will be displaying a content placeholder for the purpose of loading. A sample video is given below to get an idea about what we are going to do in this article. Note that we are going to implement this project using the Java language. 

Step by Step Implementation

Step 1: Create a New Project

To create a new project in Android Studio please refer to How to Create/Start a New Project in Android Studio. Note that select Java as the programming language.

Step 2: Adding dependency for using Facebook Shimmer layout 

Navigate to the app > Gradle Scripts > build.gradle file and add the below dependency to it. 

// below line is used for volley library

implementation ‘com.android.volley:volley:1.1.1’

// below line is used for image loading library

implementation ‘com.squareup.picasso:picasso:2.71828’  

// dependency for using facebook shimmer layout.

implementation ‘com.facebook.shimmer:shimmer:0.5.0’

Now sync your project and move towards your XML file.  

Step 3: Adding permissions for the internet in Android

Navigate to the app > AndroidManifest.xml and add permissions to it for the internet as we are loading data from the internet. 

XML




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


Step 4: Creating a modal class for storing our data

Navigate to the app > java > your app’s package name > Right-click on it > New > Java class and name it as CourseModal and add the below code to it.

Java




public class CourseModal {
    // variables for our course
    // name and description.
    private String courseName;
    private String courseimg;
    private String courseMode;
    private String courseTracks;
 
    public String getCourseName() {
        return courseName;
    }
 
    public void setCourseName(String courseName) {
        this.courseName = courseName;
    }
 
    public String getCourseimg() {
        return courseimg;
    }
 
    public void setCourseimg(String courseimg) {
        this.courseimg = courseimg;
    }
 
    public String getCourseMode() {
        return courseMode;
    }
 
    public void setCourseMode(String courseMode) {
        this.courseMode = courseMode;
    }
 
    public String getCourseTracks() {
        return courseTracks;
    }
 
    public void setCourseTracks(String courseTracks) {
        this.courseTracks = courseTracks;
    }
 
    public CourseModal(String courseName, String courseimg, String courseMode, String courseTracks) {
        this.courseName = courseName;
        this.courseimg = courseimg;
        this.courseMode = courseMode;
        this.courseTracks = courseTracks;
    }
}


Step 5: Creating a layout file for the item of our RecyclerView in Android

Navigate to the app > res > layout > Right-click on it > New > layout resource file and name it as course_rv_item and add the below code to it.  

XML




<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="8dp"
    android:elevation="8dp"
    app:cardCornerRadius="8dp">
 
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
 
        <!--ImageView to display our course image-->
        <ImageView
            android:id="@+id/idIVCourse"
            android:layout_width="match_parent"
            android:layout_height="300dp"
            android:layout_margin="5dp" />
 
        <!--text view for our course name-->
        <TextView
            android:id="@+id/idTVCourseName"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="5dp"
            android:padding="5dp"
            android:text="Course Name "
            android:textColor="@color/black"
            android:textSize="18sp"
            android:textStyle="bold" />
 
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="5dp"
            android:orientation="horizontal"
            android:weightSum="2">
 
            <!--text view for our batch name-->
            <TextView
                android:id="@+id/idTVBatch"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:padding="5dp"
                android:text="Batch"
                android:textColor="@color/black" />
 
            <!--text view to display course tracks-->
            <TextView
                android:id="@+id/idTVTracks"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:padding="5dp"
                android:text="Tracks"
                android:textColor="@color/black" />
        </LinearLayout>
 
    </LinearLayout>
 
</androidx.cardview.widget.CardView>


Step 6: Creating a layout file for our shimmer layout

Navigate to the app > res > layout > Right-click on it > New > layout resource file and name it as shimmer_layout and add the below code to it. 

XML




<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="10dp"
    android:elevation="10dp"
    android:visibility="visible"
    app:cardCornerRadius="8dp">
 
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
 
        <!--Image view for displaying our image-->
        <ImageView
            android:layout_width="match_parent"
            android:layout_height="300dp"
            android:layout_margin="5dp"
            android:background="#B3B3B3" />
 
        <!--Text view for displaying our course name-->
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="5dp"
            android:background="#B3B3B3"
            android:padding="5dp"
            android:textColor="@color/black"
            android:textSize="18sp"
            android:textStyle="bold" />
 
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="5dp"
            android:orientation="horizontal"
            android:weightSum="2">
 
            <!--Text view for displaying our batch-->
            <TextView
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_margin="2dp"
                android:layout_weight="1"
                android:background="#B3B3B3"
                android:padding="5dp"
                android:textColor="@color/black" />
 
            <!--Text view for displaying our tracks.-->
            <TextView
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_margin="2dp"
                android:layout_weight="1"
                android:background="#B3B3B3"
                android:padding="5dp"
                android:textColor="@color/black" />
 
        </LinearLayout>
 
    </LinearLayout>
 
</androidx.cardview.widget.CardView>


Step 7: Working with the activity_main.xml file

Navigate to the app > res > layout > activity_main.xml and add the below code to that file. Below is the code for the activity_main.xml file. 

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">
 
    <!--recycler view to display our data-->
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/idRVCourses"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="gone" />
 
    <!--below is the view for our shimmer-->
    <com.facebook.shimmer.ShimmerFrameLayout
        android:id="@+id/shimmerLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:animateLayoutChanges="true"
        android:animationCache="true"
        app:shimmer_repeat_mode="restart"
        app:shimmer_shape="radial">
 
        <!--For shimmer we are creating a same
            layout but setting its background
            as a gray colour and not providing
            any view inside it-->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
             
            <!--below we are displaying multiple
                shimmer layouts using include
                to show them in list format-->
            <include layout="@layout/shimmer_layout" />
            <include layout="@layout/shimmer_layout" />
            <include layout="@layout/shimmer_layout" />
            <include layout="@layout/shimmer_layout" />
            <include layout="@layout/shimmer_layout" />
 
        </LinearLayout>
         
    </com.facebook.shimmer.ShimmerFrameLayout>
     
</RelativeLayout>


Step 8: Creating an Adapter class for setting data to our item of RecyclerView 

Navigate to the app > java > your app’s package name > Right-click on it > New > Java class and name it as CourseRVAdapter and add the below code to it. Comments are added inside the code to understand the code in more detail.

Java




import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
 
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
 
import com.squareup.picasso.Picasso;
 
import java.util.ArrayList;
 
public class CourseRVAdapter extends RecyclerView.Adapter<CourseRVAdapter.ViewHolder> {
     
    // creating a variable for array list and context.
    private ArrayList<CourseModal> courseModalArrayList;
 
    public CourseRVAdapter(ArrayList<CourseModal> courseModalArrayList, Context context) {
        this.courseModalArrayList = courseModalArrayList;
        this.context = context;
    }
 
    private Context context;
 
    @NonNull
    @Override
    public CourseRVAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
         
        // below line is to inflate our layout.
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.course_rv_item, parent, false);
        return new ViewHolder(view);
    }
 
    @Override
    public void onBindViewHolder(@NonNull CourseRVAdapter.ViewHolder holder, int position) {
        // setting data to our views of recycler view.
        CourseModal modal = courseModalArrayList.get(position);
        holder.courseNameTV.setText(modal.getCourseName());
        holder.courseTracksTV.setText(modal.getCourseTracks());
        holder.courseModeTV.setText(modal.getCourseMode());
        Picasso.get().load(modal.getCourseimg()).into(holder.courseIV);
    }
 
    @Override
    public int getItemCount() {
        return courseModalArrayList.size();
    }
 
    public class ViewHolder extends RecyclerView.ViewHolder {
        // creating variables for our views.
        private TextView courseNameTV, courseModeTV, courseTracksTV;
        private ImageView courseIV;
 
        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            // initializing our views with their ids.
            courseNameTV = itemView.findViewById(R.id.idTVCourseName);
            courseModeTV = itemView.findViewById(R.id.idTVBatch);
            courseTracksTV = itemView.findViewById(R.id.idTVTracks);
            courseIV = itemView.findViewById(R.id.idIVCourse);
        }
    }
}


Step 9: Working with the MainActivity.java file

Go to the MainActivity.java file and refer to the following code. Below is the code for the MainActivity.java file. Comments are added inside the code to understand the code in more detail.

Java




import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
 
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
 
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonArrayRequest;
import com.android.volley.toolbox.Volley;
import com.facebook.shimmer.ShimmerFrameLayout;
 
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
 
import java.util.ArrayList;
 
public class MainActivity extends AppCompatActivity {
 
    // creating variables for
    // our ui components.
    private RecyclerView courseRV;
 
    // variable for our adapter
    // class and array list
    private CourseRVAdapter adapter;
    private ArrayList<CourseModal> courseModalArrayList;
    private ShimmerFrameLayout shimmerFrameLayout;
 
    // below line is the variable for url from
    // where we will be querying our data.
    String url = "https://jsonkeeper.com/b/WO6S";
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
         
        // initializing our variables.
        courseRV = findViewById(R.id.idRVCourses);
        shimmerFrameLayout = findViewById(R.id.shimmerLayout);
        shimmerFrameLayout.startShimmer();
         
        // below line we are creating a new array list
        courseModalArrayList = new ArrayList<>();
         
        // calling a method to load data.
        getData();
         
        // calling method to
        // build recycler view.
        buildRecyclerView();
    }
 
    private void getData() {
        // creating a new variable for our request queue
        RequestQueue queue = Volley.newRequestQueue(MainActivity.this);
        
        // in this case the data we are getting is in the form
        // of array so we are making a json array request.
        // below is the line where we are making an json array
        // request and then extracting data from each json object.
        JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.GET, url, null, new Response.Listener<JSONArray>() {
            @Override
            public void onResponse(JSONArray response) {
                 
                // on below line we are stopping our shimmer
                // and making its visibility to gone.
                shimmerFrameLayout.stopShimmer();
                shimmerFrameLayout.setVisibility(View.GONE);
                 
                // on below line we are making the
                // recycler view visibility visible.
                courseRV.setVisibility(View.VISIBLE);
                for (int i = 0; i < response.length(); i++) {
                    // creating a new json object and
                    // getting each object from our json array.
                    try {
                         
                        // we are getting each json object.
                        JSONObject responseObj = response.getJSONObject(i);
                         
                        // now we get our response from API in json object format.
                        // in below line we are extracting a string with
                        // its key value from our json object.
                        // similarly we are extracting all the strings from our json object.
                        String courseName = responseObj.getString("courseName");
                        String courseTracks = responseObj.getString("courseTracks");
                        String courseMode = responseObj.getString("courseMode");
                        String courseImageURL = responseObj.getString("courseimg");
                        courseModalArrayList.add(new CourseModal(courseName, courseImageURL, courseMode, courseTracks));
                        buildRecyclerView();
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Toast.makeText(MainActivity.this, "Fail to get the data..", Toast.LENGTH_SHORT).show();
            }
        });
        queue.add(jsonArrayRequest);
    }
 
    private void buildRecyclerView() {
         
        // initializing our adapter class.
        adapter = new CourseRVAdapter(courseModalArrayList, MainActivity.this);
         
        // adding layout manager
        // to our recycler view.
        LinearLayoutManager manager = new LinearLayoutManager(this);
        courseRV.setHasFixedSize(true);
         
        // setting layout manager
        // to our recycler view.
        courseRV.setLayoutManager(manager);
         
        // setting adapter to
        // our recycler view.
        courseRV.setAdapter(adapter);
    }
}


Now run your app and see the output of the app. 

Output: 

RELATED ARTICLES

Most Popular

Recent Comments