Android developmentAndroid tutorial

How to add a recyclerView inside another recyclerView Android Example

Hi, Developer in this Android Tutorial I am sharing an Android recyclerView inside another recyclerView. There is am a simple example to show rest API response multiple Array list. the response of the API Array list in a side-on Any other Array list. So let’s How to add a recyclerView inside another recyclerView Android Example.

{   “httpStatus”:“OK”,
“body”:{

         “createdAt”:“2020-04-11T12:13:26Z”,
“eventSchedule”:[

            {

               “id”:397,
“startDate”:“2020-04-12T03:30:22Z”,
“endDate”:“2020-04-12T05:30:22Z”,
“description”:null,
“topic”:“Tea Time”,
“title”:“Morning”,
“speakers”:[

                  {

                     “id”:1,
“fullName”:“Codeplayon”,
“email”:“codeplayon@gmail.com”,
“phone”:“1234567890”,
“designation”:“Lead”,
“origanizationName”:“Bellurbis”,
“profileImageUrl”:“https://www.codeplayon.com/”,
“personType”:“speaker”
}
               ]
            }
        ],}}
That is Array list response you can see the Array list in said on Array list. To Show this response in RecyalerView in Said on RecyclerView. we have a Creating activity and add recycler view in their layout file . and call a Rest Api to get Response and using Volley JSON parser you can Parser the response in RecyclerView List.
So Let’ start on Android Create your Project and with empty Activity.
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation "androidx.drawerlayout:drawerlayout:1.0.0"
    implementation 'com.google.android.material:material:1.1.0'
    implementation "androidx.coordinatorlayout:coordinatorlayout:1.1.0"
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
    implementation 'com.android.volley:volley:1.1.0'
    implementation 'de.hdodenhof:circleimageview:2.1.0'
    implementation 'androidx.cardview:cardview:1.0.0'
    implementation 'androidx.recyclerview:recyclerview:1.1.0'
    implementation 'com.squareup.picasso:picasso:2.5.2'
    implementation 'com.joanzapata.iconify:android-iconify-fontawesome:2.1.+'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
}

Step 1: Main Activity XML File Source code.

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:visibility="gone"
    android:orientation="vertical">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/Event_RecyclerView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp"
        android:orientation="vertical" />

</LinearLayout>

 Step 2 Main Java Class Source Code.

public class EventDetails_Screen extends AppCompatActivity  {

   
    ImageView Event_Image;
    TextView Event_DetTitle,Event_DetDescription,Event_DetLocation;
    RecyclerView Event_RecyclerView;
    private Event_Adupter rAdupter1;
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        supportRequestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
        setContentView(R.layout.activity_event_details__screen);

        FindViewById();
        EventDetails();        
    }
@SuppressLint({"NewApi", "WrongConstant"})
public void FindViewById(){
    Event_Image =(ImageView)findViewById(R.id.Event_Image);
    Event_DetLocation=(TextView)findViewById(R.id.Event_DetLocation);
    EventAjendat_RecyclerView=(RecyclerView)findViewById(R.id.EventAjendat_RecyclerView);
   
}

// Get Request For JSONObject
public void EventDetails(){
final ProgressDialog loading = new ProgressDialog(EventDetails_Screen.this);
loading.setMessage("Please Wait...");
loading.setCanceledOnTouchOutside(false);
loading.show();

JsonObjectRequest req = new JsonObjectRequest(Request.Method.GET, ConfiURL.BaseURL+"public/event/"+EventId, null,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
Log.d("Response", response.toString());

try {
Log.d("JSON", String.valueOf(response));
loading.dismiss();
String Error = response.getString("httpStatus");
if(Error.equals("OK")){
JSONObject Body = response.getJSONObject("body");
JSONObject events = Body.getJSONObject("events")
JSONArray eventSchedule =events.getJSONArray("eventSchedule");
JSONObject categoryTypeId =events.getJSONObject("categoryTypeId");
String Title = events.getString("title");
String Des = events.getString("detail");

EventAjenda(eventSchedule);

}else if(Error.equals("")||Error.equals(null)){

}else {

}

} catch (JSONException e) {
e.printStackTrace();
loading.dismiss();

}

}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
loading.dismiss();
VolleyLog.d("Error", "Error: " + error.getMessage());
if (error instanceof TimeoutError || error instanceof NoConnectionError) {
ContextThemeWrapper ctw = new ContextThemeWrapper(EventDetails_Screen.this, R.style.Theme_AlertDialog);
final android.app.AlertDialog.Builder alertDialogBuilder = new android.app.AlertDialog.Builder(ctw);
alertDialogBuilder.setTitle("No connection");
alertDialogBuilder.setMessage(" Connection time out error please try again ");
alertDialogBuilder.setPositiveButton("ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {

}
});
alertDialogBuilder.show();
}
}
})
{
@Override
public String getBodyContentType() {
return "application/json; charset=utf-8";
}

@Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<String, String>();
headers.put("Authorization", ConfiURL.Token);
return headers;
}
};
RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
queue.add(req);
}



protected void EventAjenda(JSONArray result) {

//this method will be running on UI thread
List<DataObject> data = new ArrayList<>();
data.equals(null);
try {
// Extract data from json and store into ArrayList as class objects
for (int i = 0; i < result.length(); i++) {
JSONObject json_data = result.getJSONObject(i);
JSONArray jsonArray = json_data.getJSONArray("speakers");
DataObject report = new DataObject();
report.mText1 = json_data.getString("id");
report.mText2 = json_data.getString("topic");
report.mText3 = json_data.getString("startDate");
report.mText4 = (json_data.getString("endDate"));
report.mText5 = (json_data.getString("title"));
report.mText6 = (json_data.getString("description"));
report.mText7 =String.valueOf(jsonArray);
data.add(report);
}
// Setup and Handover data to recyclerview
Event_RecyclerView = (RecyclerView) findViewById(R.id.EventAjendat_RecyclerView);
rAdupter1 = new EventAjenda_Adupter(EventDetails_Screen.this, data);
Event_RecyclerView.setAdapter(rAdupter1);
Event_RecyclerView.setHasFixedSize(true);
Event_RecyclerView.setLayoutManager(new LinearLayoutManager(EventDetails_Screen.this));
EventA_RecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {

super.onScrolled(recyclerView, dx, dy);
}
});
// GridLayoutManager gridLayoutManager = new GridLayoutManager(getApplicationContext(),4);
// recyclerView.setLayoutManager(gridLayoutManager);

} catch (JSONException e) {
Toast.makeText(EventDetails_Screen.this, e.toString(), Toast.LENGTH_LONG).show();
}
}

hare we can parser the response and using Adapter class to get and set the Response in recycler view. In Your Mian Adapter, you can implement your Sub Adapter recycerverView. And In CardView layout you can Add this RecyclerView

Step 3:  Main Adapter Class source Code. 

public class EventAjenda_Adupter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private Activity context;
    private LayoutInflater inflater;
    List<DataObject> data = Collections.emptyList();
    private ArrayList<DataObject> arraylist;
    private int lastPosition = -2;
    String DetailsImage,serviceUsed,customerProfile,resourceLink;
    public EventAjenda_Adupter(Activity context, List<DataObject> data) {
        this.context = context;
        // inflater = LayoutInflater.from(context);
        this.data = data;
        this.arraylist = new ArrayList<DataObject>();
        this.arraylist.addAll(data);
    }

    // Inflate the layout when viewholder created
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = inflater.from(parent.getContext()).
                inflate(R.layout.ajenda_card, parent, false);
        EventAjenda_Adupter.MyHolder holder = new EventAjenda_Adupter.MyHolder(view);
        return holder;
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

        // Get current position of item in recyclerview to bind data and assign values from list
        EventAjenda_Adupter.MyHolder myHolder = (EventAjenda_Adupter.MyHolder) holder;
        DataObject current = data.get(position);
        myHolder.Ajenda_Id.setText(current.getmText1());
        myHolder.Ajenda_Topic.setText(Html.fromHtml(current.getmText2()));
        myHolder.Ajenda_Title.setText(Html.fromHtml(current.getmText5()));
        myHolder.Ajenda_Descraption.setText(Html.fromHtml(current.getmText6()));
        try {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
            simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
            Date d = simpleDateFormat.parse(current.getmText3());
            Date d1 = simpleDateFormat.parse(current.getmText4());
            DateFormat time = new SimpleDateFormat("HH:mm a");
            String Date = time.format(d);
            String Date1 = time.format(d1);
            myHolder.Ajenda_Time_Date.setText("Timing:   "+Date+"  To  " +Date1);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        String result= current.getmText7();
        JSONArray mJSONArray = null;
        try {
            mJSONArray = new JSONArray(result);
            myHolder.onPostExecute(mJSONArray);
        } catch (JSONException e) {
            e.printStackTrace();
        }

//        setAnimation(myHolder.itemView, position);

    }

    private void setAnimation(View viewToAnimate, int position)
    {
        // If the bound view wasn't previously displayed on screen, it's animated
        if (position > lastPosition)
        {
            Animation animation = AnimationUtils.loadAnimation(context, android.R.anim.slide_in_left);
            viewToAnimate.startAnimation(animation);
            lastPosition = position;
        }
    }



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


    class MyHolder extends RecyclerView.ViewHolder {

        TextView Ajenda_Time_Date,Ajenda_Descraption,Ajenda_Topic,Ajenda_Title,Ajenda_Id;
        CardView CV;
        RecyclerView Spekar_RecyclerView;
        private SpeakerAdupter rAdapter;

        // create constructor to get widget reference
        public MyHolder(View itemView) {
            super(itemView);
            CV = (CardView) itemView.findViewById(R.id.Event_Ajenda_Card);
            Ajenda_Id = (TextView)itemView.findViewById(R.id.Ajenda_Id);
            Ajenda_Time_Date = (TextView)itemView.findViewById(R.id.Ajenda_Time_Date);
            Ajenda_Descraption = (TextView) itemView.findViewById(R.id.Ajenda_Descraption);
            Ajenda_Topic = (TextView)itemView.findViewById(R.id.Ajenda_Topic);
            Ajenda_Title=(TextView)itemView.findViewById(R.id.Ajenda_Title);
            Spekar_RecyclerView = (RecyclerView)itemView.findViewById(R.id.Spekar_RecyclerView);
        }


        protected void onPostExecute(JSONArray result) {

            //this method will be running on UI thread
            List<DataObject> data = new ArrayList<>();
            data.equals(null);
            try {
                // Extract data from json and store into ArrayList as class objects
                for (int i = 0; i < result.length(); i++) {
                    JSONObject json_data = result.getJSONObject(i);
                    DataObject report = new DataObject();
                    report.mText1 = json_data.getString("id");
                    report.mText2 = json_data.getString("fullName");
                    report.mText3 = json_data.getString("origanizationName");
                    report.Image = json_data.getString("profileImageUrl");
                    data.add(report);
                }
                rAdapter = new SpeakerAdupter(context, data);
                Spekar_RecyclerView.setAdapter(rAdapter);
                Spekar_RecyclerView.setHasFixedSize(true);
                Spekar_RecyclerView.setLayoutManager(new LinearLayoutManager(context));
                Spekar_RecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
                    @Override
                    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {

                        super.onScrolled(recyclerView, dx, dy);
                    }
                });
//            GridLayoutManager gridLayoutManager = new GridLayoutManager(getApplicationContext(),4);
//            recyclerView.setLayoutManager(gridLayoutManager);

            } catch (JSONException e) {
                Toast.makeText(context, e.toString(), Toast.LENGTH_LONG).show();
            }
        }


    }
}

Step 4: Main Card Layout Souce code : 

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/Event_Ajenda_Card"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_margin="10dp"
    app:cardBackgroundColor="@color/Gray5"
    app:cardCornerRadius="2dp"
    xmlns:android="http://schemas.android.com/apk/res/android">


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:padding="10dp">
        <TextView
            android:id="@+id/Ajenda_Id"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:visibility="gone"
            android:textAppearance="@style/page_title" />

        <TextView
            android:id="@+id/Ajenda_Time_Date"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:textStyle="bold"
            android:textAppearance="@style/page_title" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_vertical"
            android:paddingLeft="10dp"
            android:paddingRight="10dp"
            android:orientation="horizontal">

            <TextView
                android:id="@+id/Ajenda_Title"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:singleLine="true"
                android:gravity="center_vertical"
                android:textAppearance="@style/body" />

            <TextView
                android:id="@+id/Ajenda_Topic"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="2"
                android:singleLine="true"
                android:gravity="center_vertical"
                android:textAppearance="@style/body" />

        </LinearLayout>
        <TextView
            android:id="@+id/Ajenda_Descraption"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingLeft="10dp"
            android:paddingRight="10dp"
            android:layout_marginTop="5dp"
            android:maxLines="4"
            android:text="How hyperscale data centers are accelerating and powering a global cloud revolution"
            android:textAppearance="@style/body" />




        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/Spekar_RecyclerView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginTop="10dp"
            android:orientation="vertical" />
    </LinearLayout>
</androidx.cardview.widget.CardView>

Step 5:  Sub RecyclerView Adapter Class Souce Code.

public class SpeakerAdupter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private Context context;
    private LayoutInflater inflater;
    List<DataObject> data = Collections.emptyList();
    private ArrayList<DataObject> arraylist;


    private int lastPosition = -2;
    public SpeakerAdupter(Context context, List<DataObject> data) {
        this.context = context;
        // inflater = LayoutInflater.from(context);
        this.data = data;
        this.arraylist = new ArrayList<DataObject>();
        this.arraylist.addAll(data);
    }

    // Inflate the layout when viewholder created
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = inflater.from(parent.getContext()).
                inflate(R.layout.speaker_card, parent, false);
        SpeakerAdupter.MyHolder holder = new SpeakerAdupter.MyHolder(view);
        return holder;
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

        // Get current position of item in recyclerview to bind data and assign values from list
        SpeakerAdupter.MyHolder myHolder = (SpeakerAdupter.MyHolder) holder;
        DataObject current = data.get(position);
        myHolder.SpeakerId.setText(current.getmText1());
        myHolder.SpeakerName.setText(current.getmText2());
        myHolder.SpeakerOrg.setText(current.getmText3());

        String userImage = current.getImage();
        if (userImage.isEmpty()) {
            Toast.makeText(context, "no image for user", Toast.LENGTH_LONG).show();
        } else {
            Picasso.with(context)
                    .load(userImage)
                    .placeholder(R.drawable.baseline_style_24)
                    .fit()
                    .into( myHolder.Speaker_Image);
        }
//        setAnimation(myHolder.itemView, position);

    }

    private void setAnimation(View viewToAnimate, int position)
    {
        // If the bound view wasn't previously displayed on screen, it's animated
        if (position > lastPosition)
        {
            Animation animation = AnimationUtils.loadAnimation(context, android.R.anim.slide_in_left);
            viewToAnimate.startAnimation(animation);
            lastPosition = position;
        }
    }

    // Filter Class
    public void filter(String charText) {
        charText = charText.toLowerCase(Locale.getDefault());
        data.clear();
        if (charText.length() == 0) {
            data.addAll(arraylist);
        } else {
            for (DataObject wp : arraylist) {
                if (wp.getmText2().toLowerCase(Locale.getDefault()).contains(charText)) {
                    data.add(wp);
                }
            }
        }
        notifyDataSetChanged();
    }

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


    class MyHolder extends RecyclerView.ViewHolder {

        TextView SpeakerName;
        TextView SpeakerId;
        TextView SpeakerOrg;
        ImageView Speaker_Image;
        CardView CV;

        // create constructor to get widget reference
        public MyHolder(View itemView) {
            super(itemView);
            CV = (CardView) itemView.findViewById(R.id.Speaker_CardView);
            SpeakerName = (TextView) itemView.findViewById(R.id.SpeakerName);
            SpeakerId = (TextView) itemView.findViewById(R.id.SpeakerId);
            Speaker_Image = (ImageView) itemView.findViewById(R.id.Speaker_Image);
            SpeakerOrg = (TextView)itemView.findViewById(R.id.SpeakerOrg);

        }
    }
}

Step 6:  Sub RecycerView Card Layout Souce Code.

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    xmlns:app="http://schemas.android.com/tools"
    android:id="@+id/Speaker_CardView"
    android:layout_height="wrap_content"
    card_view:cardCornerRadius="8dp"
    app:ignore="NamespaceTypo">

<LinearLayout
    android:layout_width="match_parent"
    android:padding="8dp"
    android:layout_height="match_parent"
    android:orientation="horizontal">


    <de.hdodenhof.circleimageview.CircleImageView
        android:id="@+id/Speaker_Image"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_gravity="center"
        android:layout_marginLeft="15dp"
        android:src="@drawable/baseline_person_24"
        app:civ_border_color="@color/White"
        app:civ_border_width="2dp" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingLeft="15dp"
        android:orientation="vertical">

        <TextView
            android:id="@+id/SpeakerName"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:textStyle="bold"
            android:gravity="left"
            android:singleLine="true"
            android:padding="2dp"
            android:text="Parmit Malik"
            android:textAppearance="@style/name"/>
        <TextView
            android:id="@+id/SpeakerOrg"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="left"
            android:singleLine="true"
            android:padding="2dp"
            android:text="Parmit Malik"
            android:textAppearance="@style/position"/>

        <TextView
            android:id="@+id/SpeakerId"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="left"
            android:padding="2dp"
            android:visibility="gone"
            android:text="Parmit Malik"
            android:textAppearance="?android:textAppearanceSmall"/>

    </LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>

Step 7: Data Model Class Souce code.

public class DataObject {
    public String mText1;
    public String mText2;
    public String mText3;
    public String mText4;
    public String mText5;
    public String mText6;
    public String mText7;
    public String categoryName;
    public String mText8;
    public  String mText9;
    public  String mText10;
    public String Image;
    public String Image1;
    private boolean isSelected;

    public String getImage() {
        return Image;
    }

    public void setImage(String image) {
        Image = image;
    }

    public String getImage1() {
        return Image1;
    }

    public void setImage1(String image) {
        Image1 = image;
    }

    public String getmText1() {
        return mText1;
    }

    public void setmText1(String mText1) {
        this.mText1 = mText1;
    }

    public String getmText2() {
        return mText2;
    }

    public void setmText2(String mText2) {
        this.mText2 = mText2;
    }

    public String getmText3() {
        return mText3;
    }

    public void setmText3(String mText3) {
        this.mText3 = mText3;
    }

    public String getmText4() {
        return mText4;
    }

    public void setmText4(String mText4) {
        this.mText4 = mText4;
    }

    public String getmText5() {
        return mText5;
    }

    public void setmText5(String mText5) {
        this.mText5 = mText5;
    }
    public String getmText6() {
        return mText6;
    }

    public void setmText6(String mText6) {
        this.mText6 = mText6;
    }

    public String getmText7() {
        return mText7;
    }

    public void setmText7(String mText7) {
        this.mText7 = mText7;
    }

    public String getCategoryName() {
        return categoryName;
    }

    public void setCategoryName(String categoryName) {
        this.categoryName = categoryName;
    }
    public String getmText8() {
        return mText8;
    }

    public void setmText8(String mText8) {
        this.mText8 = mText8;
    }

    public String getmText9() {
        return mText9;
    }

    public void setmText9(String mText9) {
        this.mText9 = mText9;
    }

    public String getmText10() {
        return mText10;
    }

    public void setmText10(String mText10) {
        this.mText10 = mText10;
    }

    public boolean isSelected() {
        return isSelected;
    }

    public void setSelected(boolean isSelected) {
        this.isSelected = isSelected;
    }

}