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”:{
“eventSchedule”:[
“startDate”:“2020-04-12T03:30:22Z”,
“endDate”:“2020-04-12T05:30:22Z”,
“description”:null,
“topic”:“Tea Time”,
“title”:“Morning”,
“speakers”:[
“fullName”:“Codeplayon”,
“email”:“codeplayon@gmail.com”,
“phone”:“1234567890”,
“designation”:“Lead”,
“origanizationName”:“Bellurbis”,
“profileImageUrl”:“https://www.codeplayon.com/”,
“personType”:“speaker”
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; } }