Okay, that's the imagine of how to place a different layout on recyclerview's item. Now we start the coding.
PREPARATION
Compile the following library on your build.gradle (app:module)
compile 'com.android.support:recyclerview-v7:25.0.0'
IMPLEMENTATION
This project place 3 different item on recyclerview's item. So first we create all the layout before start java code
1. activity_main.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
xmlns:tools="http://schemas.android.com/tools" | |
android:id="@+id/activity_main" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
android:paddingBottom="@dimen/activity_vertical_margin" | |
android:paddingLeft="@dimen/activity_horizontal_margin" | |
android:paddingRight="@dimen/activity_horizontal_margin" | |
android:paddingTop="@dimen/activity_vertical_margin" | |
tools:context="com.androidbie.differenctviewonrecyclerviewitem.MainActivity"> | |
<android.support.v7.widget.RecyclerView | |
android:id="@+id/recyclerview" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent"></android.support.v7.widget.RecyclerView> | |
</RelativeLayout> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
android:orientation="vertical" | |
android:id="@+id/ll_input_username_password" | |
android:layout_width="match_parent" | |
android:clickable="true" | |
android:background="?attr/selectableItemBackground" | |
android:layout_height="wrap_content"> | |
<LinearLayout | |
android:layout_margin="15dp" | |
android:layout_width="match_parent" | |
android:orientation="vertical" | |
android:layout_height="wrap_content"> | |
<TextView | |
android:id="@+id/textview_description_input_usernamepassword" | |
android:layout_width="match_parent" | |
android:textColor="@android:color/black" | |
android:layout_height="wrap_content" /> | |
<TextView | |
android:id="@+id/textview_name_input_usernamepassword" | |
android:layout_width="match_parent" | |
android:textColor="@android:color/black" | |
android:layout_height="wrap_content" /> | |
<TextView | |
android:id="@+id/textview_city_input_usernamepassword" | |
android:layout_width="match_parent" | |
android:textColor="@android:color/black" | |
android:layout_height="wrap_content" /> | |
<EditText | |
android:id="@+id/edit_text_username" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:hint="Input username"/> | |
<EditText | |
android:id="@+id/edit_text_password" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:hint="Input Password"/> | |
<LinearLayout | |
android:orientation="horizontal" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content"> | |
<Button | |
android:layout_weight="1" | |
android:id="@+id/button_add_to_list" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:text="Add To List"/> | |
<Button | |
android:layout_weight="1" | |
android:id="@+id/button_done" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:text="Done"/> | |
</LinearLayout> | |
</LinearLayout> | |
<View | |
android:layout_marginTop="10dp" | |
android:layout_width="match_parent" | |
android:background="@android:color/holo_blue_bright" | |
android:layout_height="2dp"/> | |
</LinearLayout> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
android:orientation="vertical" | |
android:id="@+id/ll_progressbar" | |
android:layout_width="match_parent" | |
android:clickable="true" | |
android:background="?attr/selectableItemBackground" | |
android:layout_height="wrap_content"> | |
<LinearLayout | |
android:layout_margin="15dp" | |
android:layout_width="match_parent" | |
android:orientation="vertical" | |
android:layout_height="wrap_content"> | |
<TextView | |
android:id="@+id/textview_description_please_wait" | |
android:layout_width="match_parent" | |
android:textColor="@android:color/black" | |
android:layout_height="wrap_content" /> | |
<TextView | |
android:id="@+id/textview_name_please_wait" | |
android:layout_width="match_parent" | |
android:textColor="@android:color/black" | |
android:layout_height="wrap_content" /> | |
<TextView | |
android:id="@+id/textview_city_please_wait" | |
android:layout_width="match_parent" | |
android:textColor="@android:color/black" | |
android:layout_height="wrap_content" /> | |
<ProgressBar | |
android:layout_marginTop="10dp" | |
android:id="@+id/progressbar_display_account" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" /> | |
<TextView | |
android:gravity="center" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:textColor="@android:color/black" | |
android:layout_marginBottom="10dp" | |
android:text="Your TextView Loading"/> | |
</LinearLayout> | |
<View | |
android:layout_marginTop="10dp" | |
android:layout_width="match_parent" | |
android:background="@android:color/holo_blue_bright" | |
android:layout_height="2dp"/> | |
</LinearLayout> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
android:orientation="vertical" | |
android:layout_width="match_parent" | |
android:id="@+id/ll_detail_view" | |
android:clickable="true" | |
android:background="?attr/selectableItemBackground" | |
android:layout_height="wrap_content"> | |
<LinearLayout | |
android:layout_margin="15dp" | |
android:layout_width="match_parent" | |
android:orientation="vertical" | |
android:layout_height="wrap_content"> | |
<TextView | |
android:id="@+id/textview_description_detail" | |
android:layout_width="match_parent" | |
android:textColor="@android:color/black" | |
android:layout_height="wrap_content" /> | |
<TextView | |
android:id="@+id/textview_name_detail" | |
android:layout_width="match_parent" | |
android:textColor="@android:color/black" | |
android:layout_height="wrap_content" /> | |
<TextView | |
android:id="@+id/textview_city_detail" | |
android:layout_width="match_parent" | |
android:textColor="@android:color/black" | |
android:layout_height="wrap_content" /> | |
<LinearLayout | |
android:layout_marginTop="10dp" | |
android:orientation="horizontal" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content"> | |
<TextView | |
android:layout_weight="1" | |
android:id="@+id/textview_username" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:gravity="center" | |
android:text="Your Textview Detail 1"/> | |
<TextView | |
android:layout_weight="1" | |
android:gravity="center" | |
android:id="@+id/textview_password" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:text="Your Textview Detail 2"/> | |
</LinearLayout> | |
</LinearLayout> | |
<View | |
android:layout_marginTop="10dp" | |
android:layout_width="match_parent" | |
android:background="@android:color/holo_blue_bright" | |
android:layout_height="2dp"/> | |
</LinearLayout> |
1. ItemModel.java
In order program know that item index 0 for Layout A, item index 1 for Layout B and etc, you have to give an indicator in your Object/Mode/Data before transfer to your adapter.
In this project I put an index inside my model class as an indicator. The model namely as ItemModel.java. Paste the following code :
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.androidbie.differenctviewonrecyclerviewitem.models; | |
/** | |
* Created by putuguna on 05/01/17. | |
*/ | |
public class ItemModel { | |
private int index; | |
private String description; | |
private String name; | |
private String city; | |
public ItemModel(int index, String description, String name, String city) { | |
this.index = index; | |
this.description = description; | |
this.name = name; | |
this.city = city; | |
} | |
public ItemModel() { | |
} | |
public int getIndex() { | |
return index; | |
} | |
public void setIndex(int index) { | |
this.index = index; | |
} | |
public String getDescription() { | |
return description; | |
} | |
public void setDescription(String description) { | |
this.description = description; | |
} | |
public String getName() { | |
return name; | |
} | |
public void setName(String name) { | |
this.name = name; | |
} | |
public String getCity() { | |
return city; | |
} | |
public void setCity(String city) { | |
this.city = city; | |
} | |
} |
Like i explained above (on the first paragraph), you have to create you inner class in ViewHolder (Whatever how much it is). If you wanna put 4 different layout, so create 4 different inner class of ViewHolder.
After that, you should to extends RecyclerView.Adapter<RecyclerView.ViewHolder> and then implement all of its methods.
Which method that explain that index 1 for layout A and etc?
For that, you have to override method getItemViewType(int position) manually. Create the condition using if and else. On this method you will use the indicator of your model as the key.
These index or number got from model that we input on MainActivity (explained later).
After you create the condition, in onCreateViewHolder(ViewGroup parent, int viewType) you have to create the condition using case (or anything that related!). The logic is, if method getItemViewType() return index x, than put Layout x. Take a look at the code follows :
To get that the layout x has been return on method onCreateViewHolder(ViewGroup parent, int viewType), you must use an instanceof on method onBindViewHolder(RecyclerView.ViewHolder holder, final int position) . Take a look at the following sample code :
I hope you'll understand how to steps to create a complex adapter like above. Here is the full code of ViewAdapter.java :
3. MainActivity.java
In this class, as usual, just to set the data, define the recyclerview and set the adapter's data to recyclerview. Here the full code of MainActivity.java :
That's all. Compile and run the project. Hope it works well. Thank you.
@Override public int getItemViewType(int position) { ItemModel item = mListItemModel.get(position); if(item.getIndex()==0){ return 0; }else if(item.getIndex()==1){ return 1; }else if(item.getIndex()==2){ return 2; } return super.getItemViewType(position); }
These index or number got from model that we input on MainActivity (explained later).
After you create the condition, in onCreateViewHolder(ViewGroup parent, int viewType) you have to create the condition using case (or anything that related!). The logic is, if method getItemViewType() return index x, than put Layout x. Take a look at the code follows :
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Override | |
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { | |
RecyclerView.ViewHolder holder = null; | |
LayoutInflater inflater = LayoutInflater.from(parent.getContext()); | |
switch (viewType){ | |
case 0: | |
View viewInputUserPassword = inflater.inflate(R.layout.view_input_username_and_password, parent, false); | |
holder = new InputUsernameAndPasswordViewHolder(viewInputUserPassword); | |
break; | |
case 1: | |
View viewLoading = inflater.inflate(R.layout.view_please_wait, parent, false); | |
holder = new LoadingPleaseWaitViewHolder(viewLoading); | |
break; | |
case 2: | |
View viewDetail = inflater.inflate(R.layout.view_detail_usernamepassword, parent, false); | |
holder = new DetailListPasswordAndUsernameViewHolder(viewDetail); | |
break; | |
} | |
return holder; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Override | |
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) { | |
if(holder instanceof InputUsernameAndPasswordViewHolder){ | |
//DO activity of LoadingPleaseWaitViewHolder | |
}else if(holder instanceof LoadingPleaseWaitViewHolder){ | |
//DO activity of LoadingPleaseWaitViewHolder | |
}else if(holder instanceof DetailListPasswordAndUsernameViewHolder){ | |
//DO activity of DetailListPasswordAndUsernameViewHolder | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.androidbie.differenctviewonrecyclerviewitem; | |
import android.content.Context; | |
import android.support.v7.widget.RecyclerView; | |
import android.view.LayoutInflater; | |
import android.view.View; | |
import android.view.ViewGroup; | |
import android.widget.Button; | |
import android.widget.EditText; | |
import android.widget.LinearLayout; | |
import android.widget.TextView; | |
import android.widget.Toast; | |
import com.androidbie.differenctviewonrecyclerviewitem.models.ItemModel; | |
import java.util.List; | |
/** | |
* Created by putuguna on 05/01/17. | |
*/ | |
public class ViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{ | |
private List<ItemModel> mListItemModel; | |
private Context mContext; | |
public ViewAdapter(List<ItemModel> mListItemModel, Context mContext) { | |
this.mListItemModel = mListItemModel; | |
this.mContext = mContext; | |
} | |
// override this method manually | |
@Override | |
public int getItemViewType(int position) { | |
ItemModel item = mListItemModel.get(position); | |
if(item.getIndex()==0){ | |
return 0; | |
}else if(item.getIndex()==1){ | |
return 1; | |
}else if(item.getIndex()==2){ | |
return 2; | |
} | |
return super.getItemViewType(position); | |
} | |
@Override | |
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { | |
RecyclerView.ViewHolder holder = null; | |
LayoutInflater inflater = LayoutInflater.from(parent.getContext()); | |
switch (viewType){ | |
case 0: | |
View viewInputUserPassword = inflater.inflate(R.layout.view_input_username_and_password, parent, false); | |
holder = new InputUsernameAndPasswordViewHolder(viewInputUserPassword); | |
break; | |
case 1: | |
View viewLoading = inflater.inflate(R.layout.view_please_wait, parent, false); | |
holder = new LoadingPleaseWaitViewHolder(viewLoading); | |
break; | |
case 2: | |
View viewDetail = inflater.inflate(R.layout.view_detail_usernamepassword, parent, false); | |
holder = new DetailListPasswordAndUsernameViewHolder(viewDetail); | |
break; | |
} | |
return holder; | |
} | |
@Override | |
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) { | |
ItemModel itemModel = mListItemModel.get(position); | |
if(holder instanceof InputUsernameAndPasswordViewHolder){ | |
((InputUsernameAndPasswordViewHolder) holder).tvDesc.setText("Description = "+itemModel.getDescription()); | |
((InputUsernameAndPasswordViewHolder) holder).tvName.setText("Name = "+itemModel.getName()); | |
((InputUsernameAndPasswordViewHolder) holder).tvCity.setText("City = " + itemModel.getCity()); | |
// do onClick on LinearLayout to see the position of recyclerview item | |
((InputUsernameAndPasswordViewHolder) holder).llInputUsernamePassword.setOnClickListener(new View.OnClickListener() { | |
@Override | |
public void onClick(View view) { | |
Toast.makeText(mContext, "RecyclerView's item position = " + position, Toast.LENGTH_SHORT).show(); | |
} | |
}); | |
}else if(holder instanceof LoadingPleaseWaitViewHolder){ | |
((LoadingPleaseWaitViewHolder) holder).tvDesc.setText("Description = "+itemModel.getDescription()); | |
((LoadingPleaseWaitViewHolder) holder).tvName.setText("Name = "+itemModel.getName()); | |
((LoadingPleaseWaitViewHolder) holder).tvCity.setText(itemModel.getCity()); | |
// do onClick on LinearLayout to see the position of recyclerview item | |
((LoadingPleaseWaitViewHolder) holder).llLoading.setOnClickListener(new View.OnClickListener() { | |
@Override | |
public void onClick(View view) { | |
Toast.makeText(mContext, "RecyclerView's item position = " + position, Toast.LENGTH_SHORT).show(); | |
} | |
}); | |
}else if(holder instanceof DetailListPasswordAndUsernameViewHolder){ | |
((DetailListPasswordAndUsernameViewHolder) holder).tvDesc.setText("Description = "+itemModel.getDescription()); | |
((DetailListPasswordAndUsernameViewHolder) holder).tvName.setText("Name = "+itemModel.getName()); | |
((DetailListPasswordAndUsernameViewHolder) holder).tvCity.setText("City = " + itemModel.getCity()); | |
// do onClick on LinearLayout to see the position of recyclerview item | |
((DetailListPasswordAndUsernameViewHolder) holder).llDetail.setOnClickListener(new View.OnClickListener() { | |
@Override | |
public void onClick(View view) { | |
Toast.makeText(mContext, "RecyclerView's item position = " + position, Toast.LENGTH_SHORT).show(); | |
} | |
}); | |
} | |
} | |
@Override | |
public int getItemCount() { | |
return mListItemModel.size(); | |
} | |
/** | |
* first, create Input ViewHolder of username and password | |
*/ | |
public class InputUsernameAndPasswordViewHolder extends RecyclerView.ViewHolder{ | |
public EditText etUsername; | |
public EditText etPassword; | |
public Button btnAddToList; | |
public Button btnDone; | |
public TextView tvDesc; | |
public TextView tvName; | |
public TextView tvCity; | |
public LinearLayout llInputUsernamePassword; | |
public InputUsernameAndPasswordViewHolder(View itemView) { | |
super(itemView); | |
etPassword = (EditText) itemView.findViewById(R.id.edit_text_password); | |
etUsername = (EditText) itemView.findViewById(R.id.edit_text_username); | |
btnAddToList = (Button) itemView.findViewById(R.id.button_add_to_list); | |
btnDone = (Button) itemView.findViewById(R.id.button_done); | |
tvDesc = (TextView) itemView.findViewById(R.id.textview_description_input_usernamepassword); | |
tvName = (TextView) itemView.findViewById(R.id.textview_name_input_usernamepassword); | |
tvCity = (TextView) itemView.findViewById(R.id.textview_city_input_usernamepassword); | |
llInputUsernamePassword = (LinearLayout) itemView.findViewById(R.id.ll_input_username_password); | |
} | |
} | |
/** | |
* Second, create loading view holder to display loading view after finish input data | |
*/ | |
public class LoadingPleaseWaitViewHolder extends RecyclerView.ViewHolder{ | |
public LinearLayout llLoading; | |
public TextView tvDesc; | |
public TextView tvName; | |
public TextView tvCity; | |
public LoadingPleaseWaitViewHolder(View itemView) { | |
super(itemView); | |
llLoading = (LinearLayout) itemView.findViewById(R.id.ll_progressbar); | |
tvDesc = (TextView) itemView.findViewById(R.id.textview_description_please_wait); | |
tvName = (TextView) itemView.findViewById(R.id.textview_name_please_wait); | |
tvCity = (TextView) itemView.findViewById(R.id.textview_city_please_wait); | |
} | |
} | |
/** | |
* Third, create List ViewHolder to display list of username and password | |
*/ | |
public class DetailListPasswordAndUsernameViewHolder extends RecyclerView.ViewHolder{ | |
public TextView tvUsername; | |
public TextView tvPassword; | |
public TextView tvDesc; | |
public TextView tvName; | |
public TextView tvCity; | |
public LinearLayout llDetail; | |
public DetailListPasswordAndUsernameViewHolder(View itemView) { | |
super(itemView); | |
tvUsername = (TextView) itemView.findViewById(R.id.textview_username); | |
tvPassword = (TextView) itemView.findViewById(R.id.textview_password); | |
tvDesc = (TextView) itemView.findViewById(R.id.textview_description_detail); | |
tvName = (TextView) itemView.findViewById(R.id.textview_name_detail); | |
tvCity = (TextView) itemView.findViewById(R.id.textview_city_detail); | |
llDetail = (LinearLayout) itemView.findViewById(R.id.ll_detail_view); | |
} | |
} | |
} |
In this class, as usual, just to set the data, define the recyclerview and set the adapter's data to recyclerview. Here the full code of MainActivity.java :
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.androidbie.differenctviewonrecyclerviewitem; | |
import android.support.v7.app.AppCompatActivity; | |
import android.os.Bundle; | |
import android.support.v7.widget.DefaultItemAnimator; | |
import android.support.v7.widget.LinearLayoutManager; | |
import android.support.v7.widget.RecyclerView; | |
import com.androidbie.differenctviewonrecyclerviewitem.models.ItemModel; | |
import java.util.ArrayList; | |
import java.util.List; | |
public class MainActivity extends AppCompatActivity { | |
private List<ItemModel> mlistItemModel; | |
private RecyclerView recyclerView; | |
private ViewAdapter mAdapter; | |
@Override | |
protected void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.activity_main); | |
recyclerView = (RecyclerView) findViewById(R.id.recyclerview); | |
mlistItemModel = new ArrayList<>(); | |
mlistItemModel.add(new ItemModel(0,"This Form Login","Android Newbie","Bandung")); | |
mlistItemModel.add(new ItemModel(1,"This Form Loading","Android Expert","Canberra")); | |
mlistItemModel.add(new ItemModel(2,"This Form Detail","Android Middle","Kuala Lumpur")); | |
mlistItemModel.add(new ItemModel(0,"This Form Login","Android Newbie","Bandung")); | |
mlistItemModel.add(new ItemModel(2,"This Form Detail","Android Expert","London")); | |
mlistItemModel.add(new ItemModel(1,"This Form Loading","Android Middle","Barcelona")); | |
mAdapter = new ViewAdapter(mlistItemModel, this); | |
recyclerView.setLayoutManager(new LinearLayoutManager(this)); | |
recyclerView.setItemAnimator(new DefaultItemAnimator()); | |
recyclerView.setAdapter(mAdapter); | |
} | |
} |
EmoticonEmoticon