Recyclerview holder setting an image text instead of drawable - android

I need your help to display the array texts as image, displaying them as text is working, but is image is not working. below are some explanation.
I have an array of texts that I want to display them in recycler view as an image.
String[] images =
{
"for_honor.png",
"R.drawable.ghost_recon.png",
"R.drawable.horizon_zerod.png",
"R.drawable.mass_effect.png"
};
setting them in this way seems wrong as i am not getting image
((MyViewHolder) holder).getmDataImgView().getResources().getIdentifier(name,"drawable","com.example.pkg.pg.Adapters");
however this code is working it show me them as text not image
// ((MyViewHolder) holder).getmDataTextView().setText(name);
this code im my main activity
MainGridRecView = (RecyclerView) findViewById(R.id.maingridrc);
MainGridRecViewLayoutManager = new LinearLayoutManager(context);
MainGridRecView.setLayoutManager(MainGridRecViewLayoutManager);
MainGridRecViewAdapter = new MainGridRvAdapter( dataHorizontal,dataVertical,MainActivity.this);
MainGridRecView.setAdapter(MainGridRecViewAdapter);
this maingridrvadapter
public class MainGridRvAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final Context mContext;
private ArrayList<ListMainItem> dataHorizontal;
private ArrayList<ListMainItem> dataVertical;
private static final int TYPE_HEADER = 0;
private static final int TYPE_ITEM = 1;
public MainGridRvAdapter(ArrayList<ListMainItem> dataHorizontal, ArrayList<ListMainItem> dataVertical, Context context) {
setDataHorizontal(dataHorizontal);
setDataVertical(dataVertical);
mContext = context;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == TYPE_ITEM) {
//inflate your layout and pass it to view holder
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.row, parent, false);
return new MyViewHolder(v);
} else if (viewType == TYPE_HEADER) {
//inflate your layout and pass it to view holder
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_header, parent, false);
return new MyViewHolderHeader(v);
}
throw new RuntimeException("there is no type that matches the type " + viewType + " + make sure your using types correctly");
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder instanceof MyViewHolder) {
String name = getDataVertical().get(position-1).getImages();
Log.d("###", "Setting name: " + name);
((MyViewHolder) holder).getmDataImgView().getResources().getIdentifier(name,"drawable","com.example.pkg.pg.Adapters");
// int resourceId = Activity.getResources().getIdentifier("testimage", "drawable", "your.package.name");
} else if (holder instanceof MyViewHolderHeader) {
//cast holder to VHHeader and set data for header.
Log.d("####", "HEADER");
}
}
#Override
public int getItemCount() {
return dataVertical.size() + 1;
}
#Override
public int getItemViewType(int position) {
if (isPositionHeader(position)) {
return TYPE_HEADER;
}
return TYPE_ITEM;
}
private boolean isPositionHeader(int position) {
return position == 0;
}
public void setDataHorizontal(ArrayList<ListMainItem> dataHorizontal) {
this.dataHorizontal = dataHorizontal;
}
public ArrayList<ListMainItem> getDataHorizontal() {
return dataHorizontal;
}
public void setDataVertical(ArrayList<ListMainItem> dataVertical) {
this.dataVertical = dataVertical;
}
public ArrayList<ListMainItem> getDataVertical() {
return dataVertical;
}
private class MyViewHolder extends RecyclerView.ViewHolder {
// private final TextView mDataTextView;
private final ImageView mDataImgView;
public MyViewHolder(View v) {
super(v);
// mDataTextView = (TextView) v.findViewById(R.id.data_vertical);
mDataImgView = (ImageView) v.findViewById(R.id.img_vertical);
}
/*
public TextView getmDataTextView() {
return mDataTextView;
}*/
public ImageView getmDataImgView() {
return mDataImgView;
}
}
private class MyViewHolderHeader extends RecyclerView.ViewHolder {
private final RecyclerView mHorizontalRecyclerView;
public MyViewHolderHeader(View v) {
super(v);
mHorizontalRecyclerView = (RecyclerView) v.findViewById(R.id.recycler_view_horizontal);
RecyclerViewAdapterHorizontal mAdapter = new RecyclerViewAdapterHorizontal(getDataHorizontal());
LinearLayoutManager layoutManager
= new LinearLayoutManager(mContext, LinearLayoutManager.HORIZONTAL, false);
mHorizontalRecyclerView.setLayoutManager(layoutManager);
mHorizontalRecyclerView.setAdapter(mAdapter);
}
}
}
layout
<TextView
android:id="#+id/data_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="text"
/>
<ImageView
android:id="#+id/img_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
class RecyclerViewAdapterHorizontal extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final ArrayList<ListMainItem> mData;
private final Context mContext;
public RecyclerViewAdapterHorizontal(ArrayList<ListMainItem> dataHorizontal,Context context) {
mData = dataHorizontal;
mContext=context;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.row, parent, false);
return new RecyclerViewAdapterHorizontal.MyViewHolderHeader(v);
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
String name = mData.get(position).getImages();
Log.d("###", "Setting name: " + name);
// ((RecyclerViewAdapterHorizontal.MyViewHolderHeader) holder).getmDataTextView().setText(name);
((RecyclerViewAdapterHorizontal.MyViewHolderHeader) holder).getmDataImgView().setImageResource(mContext.getResources().getIdentifier(name, "drawable", "com.example.mohamadmouazen.lebgame.Adapters"));
}
#Override
public int getItemCount() {
return mData.size();
}
private class MyViewHolderHeader extends RecyclerView.ViewHolder {
// private final TextView mDataTextView;
private final ImageView mDataImgView;
public MyViewHolderHeader(View v) {
super(v);
// mDataTextView = (TextView) v.findViewById(R.id.data_vertical);
mDataImgView = (ImageView) v.findViewById(R.id.img_vertical);
}
public ImageView getmDataImgView() {
return mDataImgView;
}
/* public TextView getmDataTextView() {
return mDataTextView;
}*/
}
edit
class RecyclerViewAdapterHorizontal extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final ArrayList<ListMainItem> mData;
private final Context mContext;
public RecyclerViewAdapterHorizontal(ArrayList<ListMainItem> dataHorizontal,Context context) {
mData = dataHorizontal;
mContext=context;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.row, parent, false);
return new RecyclerViewAdapterHorizontal.MyViewHolderHeader(v);
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
String name = mData.get(position).getImages();
Log.d("###", "Setting name: " + name);
// ((RecyclerViewAdapterHorizontal.MyViewHolderHeader) holder).getmDataTextView().setText(name);
((RecyclerViewAdapterHorizontal.MyViewHolderHeader) holder).getmDataImgView().setImageResource(mContext.getResources().getIdentifier(name, "drawable", "com.example.pkg.pg.Adapters"));
}
#Override
public int getItemCount() {
return mData.size();
}
private class MyViewHolderHeader extends RecyclerView.ViewHolder {
// private final TextView mDataTextView;
private final ImageView mDataImgView;
public MyViewHolderHeader(View v) {
super(v);
// mDataTextView = (TextView) v.findViewById(R.id.data_vertical);
mDataImgView = (ImageView) v.findViewById(R.id.img_vertical);
}
public ImageView getmDataImgView() {
return mDataImgView;
}
/* public TextView getmDataTextView() {
return mDataTextView;
}*/
}
}

Change your images array to ints:
int[] images = {
R.drawable.for_honor,
R.drawable.ghost_recon,
R.drawable.horizon_zerod,
R.drawable.mass_effect
};
and set the image something like so:
int resourceId = images[position]; // <-- apply your actual logic here
...getmDataImgView().setImageResource(resourceId);

A method int getIdentifier (String name, String defType, String defPackage) returns resource identifier for the given resource name. In other words it returns the R.drawable.your_name .
When you set the text it works because TextView is expecting the String type.
Plus you actually do not set anything to your ImageView. Your mistake is here:
((MyViewHolder) holder).getmDataImgView().getResources().getIdentifier(name,"drawable","com.example.pkg.pg.Adapters");
You just getting the identifier from the resource. Instead to set the image you should do:
((MyViewHolder) holder).getmDataImgView().setImageResource(mContext.getResources().getIdentifier(name,"drawable","com.example.pkg.pg.Adapters"));
By the way it is not reccomended to hardcode your resources names in the string. Do it in the proper way by setting resource identifier directly.

Related

How to create MultipleView type Recycler-View correctly?

how to create recyclerview with multipe view type. i was tried with my code ,but this is method isnt working actually.
i was got my code from this reference
https://stackoverflow.com/a/26245463/12192293
How the correctly way to create multiple view type into recycler-view?
adapter code :
private static final int THIS_DATE = 0;
private static final int THIS_DATA = 1;
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
if (viewType == THIS_DATE){
return new DateViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_money_manager_date, parent, false));
}else{
return new DataViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_money_manager, parent, false));
}
}
#SuppressLint({"SetTextI18n", "ResourceType"})
#Override
public void onBindViewHolder(#NonNull final RecyclerView.ViewHolder holder, int position) {
final MoneyManager moneyManager = moneyManagers.get(position);
Resources resources = context.getResources();
getCurrentBalance();
getTotalIncome();
if (getItemViewType(position) == THIS_DATE){
DateViewHolder dateViewHolder = (DateViewHolder) holder;
dateViewHolder.textDate.setText(moneyManager.getDate());
}else{
DataViewHolder dataViewHolder = (DataViewHolder) holder;
dataViewHolder.textName.setText(moneyManager.getName());
if (moneyManager.getExpense() != 0){
dataViewHolder.textMoney.setText(NumberFormat.getCurrencyInstance(new Locale("id", "id")).format(moneyManager.getExpense()));
dataViewHolder.textMoney.setTextColor(resources.getColor(R.color.colorExpense));
}else{
dataViewHolder.textMoney.setText(NumberFormat.getCurrencyInstance(new Locale("id", "id")).format(moneyManager.getIncome()));
dataViewHolder.textMoney.setTextColor(resources.getColor(R.color.colorIncome));
}
}
}
private void getTotalIncome() {
long totalIncome = 0;
for (MoneyManager moneyManager : moneyManagers){
totalIncome += moneyManager.getIncome();
}
moneyManagerFragment.textTotalIncome.setText(NumberFormat.getCurrencyInstance(new Locale("id","id")).format(totalIncome));
}
private void getCurrentBalance() {
long yourBalance = 0;
for (MoneyManager moneys : moneyManagers){
yourBalance += moneys.getIncome() - moneys.getExpense();
}
moneyManagerFragment.textMoney.setText(NumberFormat.getCurrencyInstance(new Locale("id", "id")).format(yourBalance));
}
#Override
public int getItemCount() {
return moneyManagers.size();
}
#Override
public int getItemViewType(int position) {
if(position == 0){
return THIS_DATE;
}else{
return THIS_DATA;
}
}
private class DateViewHolder extends RecyclerView.ViewHolder {
TextView textDate;
public DateViewHolder(#NonNull View itemView) {
super(itemView);
textDate = itemView.findViewById(R.id.textDate);
}
}
private class DataViewHolder extends RecyclerView.ViewHolder{
TextView textName , textMoney, textDate;
ImageView imageCategory;
public DataViewHolder(#NonNull View itemView) {
super(itemView);
textName = itemView.findViewById(R.id.textName);
textMoney = itemView.findViewById(R.id.textIncomeOrExpense);
imageCategory = itemView.findViewById(R.id.imageCategory);
textDate = itemView.findViewById(R.id.textDateTime);
}
}
Some help or suggestion will be appreciate, and sorry for bad grammar before

onBindViewHolder execute first ViewHolder only

I have three ViewHolders CardViewHolder, TitleViewHolder, GridViewHolder, for switching between it when user choose a specific layout, everything working good expect when I trying to switch to Title and Grid Layout/Views, I see only the "Dummy title and default image" that I put it in it's layout
Here's my PostAdapter class:
public class PostAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context;
private List<Item> items;
public static final int CARD_LIST = 0;
public static final int CARD_MAGAZINE = 1;
public static final int TITLE = 2;
public static final int GRID = 3;
private int viewType;
PostAdapter(Context context, List<Item> items) {
this.context = context;
this.items = items;
}
public void setViewType(int viewType) {
this.viewType = viewType;
notifyDataSetChanged();
}
public int getViewType() {
return this.viewType;
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
View view;
if (this.viewType == CARD_LIST) {
view = inflater.inflate(R.layout.card_layout, parent, false);
return new CardViewHolder(view);
} else if (this.viewType == CARD_MAGAZINE) {
view = inflater.inflate(R.layout.card_magazine_layout, parent, false);
return new CardViewHolder(view);
} else if(this.viewType == TITLE){
view = inflater.inflate(R.layout.title_layout, parent, false);
return new TitleViewHolder(view);
}else {
view = inflater.inflate(R.layout.grid_layout,parent,false);
return new GridViewHolder(view);
}
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
int itemType = getItemViewType(position);
final Item item = items.get(position);
final Document document = Jsoup.parse(item.getContent());
final Elements elements = document.select("img");
if (itemType == CARD_LIST || itemType == CARD_MAGAZINE) {
if (holder instanceof CardViewHolder) {
CardViewHolder cardViewHolder = (CardViewHolder) holder;
cardViewHolder.postTitle.setText(item.getTitle());
cardViewHolder.postDescription.setText(document.text());
Log.d("IMAGE", elements.get(0).attr("src"));
Glide.with(context).load(elements.get(0).attr("src"))
.into(cardViewHolder.postImage);
} else if (itemType == TITLE) {
if (holder instanceof TitleViewHolder) {
TitleViewHolder titleViewHolder = (TitleViewHolder) holder;
titleViewHolder.postTitle.setText(item.getTitle());
Log.d("IMAGE", elements.get(0).attr("src"));
Glide.with(context).load(elements.get(0).attr("src"))
.into(titleViewHolder.postImage);
}
}else {
GridViewHolder gridViewHolder = (GridViewHolder) holder;
gridViewHolder.postTitle.setText(item.getTitle());
Log.d("IMAGE", elements.get(0).attr("src"));
Glide.with(context).load(elements.get(0).attr("src"))
.into(gridViewHolder.postImage);
}
}
#Override
public int getItemCount() {
return items.size();
}
public class CardViewHolder extends RecyclerView.ViewHolder {
ImageView postImage;
TextView postTitle;
TextView postDescription;
public CardViewHolder(View itemView) {
super(itemView);
postImage = itemView.findViewById(R.id.postImage);
postTitle = itemView.findViewById(R.id.postTitle);
postDescription = itemView.findViewById(R.id.postDescription);
}
}
public class TitleViewHolder extends RecyclerView.ViewHolder {
TextView postTitle;
MyImageview postImage;
public TitleViewHolder(#NonNull View itemView) {
super(itemView);
postTitle = itemView.findViewById(R.id.postTitle);
postImage = itemView.findViewById(R.id.postImage);
}
}
public class GridViewHolder extends RecyclerView.ViewHolder {
TextView postTitle;
MyImageview postImage;
public GridViewHolder(#NonNull View itemView) {
super(itemView);
postTitle = itemView.findViewById(R.id.postTitle);
postImage = itemView.findViewById(R.id.postImage);
}
}
}
It seems that the first ViewHolder is only implemented in first if block, I tried to find out why the problem was caused by the log, but I don't know why unfortunately.
It is because you didn't give the view type by overriding getItemViewType(int position) method. You need to add the following method in your Adapter:
#Override
public int getItemViewType(int position) {
// this is just an example for returning the type.
// Assuming each item containing a type
return items.get(position).type;
// you can also use an if condition here
// for example
// if(position % 2 == 0) {
// return CARD_LIST;
// } else {
// return CARD_MAGAZINE;
// }
}
[Solved]
The problem was happens because I was checking for the wrong variable getting by method getItemViewType it should be like this
int itemType = getViewType();

ViewHolderHeader cannot be cast in onBindViewHolder viewholder

Why i am having this error ?
java.lang.ClassCastException: com.example.pc.mytest.MainItemsRCVAdapter$ViewHolderHeader cannot be cast to com.example.pc.mytest.MainItemsRCVAdapter$ViewHolder
I am trying to have to a Recycler one header and one horizontal.
This is the class:
public class MainItemsRCVAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private ArrayList<ListMainItem> mainItems;
private Context mContext;
private static final int TYPE_HEADER = 0;
private static final int TYPE_ITEM = 1;
public MainItemsRCVAdapter(Context context,ArrayList<ListMainItem> maindata) {
setMaindata(maindata);
this.mainItems = maindata;
this.mContext = context;
}
public void setMaindata(ArrayList<ListMainItem> maindatahorizon) {
this.mainItems = maindatahorizon;
}
public ArrayList<ListMainItem> getMaindata() {
return mainItems;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
if (viewType == TYPE_ITEM) {
//inflate your layout and pass it to view holder
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.main_adapter_horizontal, viewGroup, false);
return new ViewHolder(v);
} else if (viewType == TYPE_HEADER) {
//inflate your layout and pass it to view holder
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.main_item_adapter, viewGroup, false);
return new ViewHolderHeader(v);
}
throw new RuntimeException("there is no type that matches the type " + viewType + " + make sure your using types correctly");
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int i) {
if (holder instanceof ViewHolder) {
// String name = getDataVertical().get(position-1).getImages();
String name =mainItems.get(i).geImgName();
String urlimage =mainItems.get(i).getImgUrl();
((ViewHolder) holder).tv_items.setText(mainItems.get(i).geImgName());
// holder.tv_items.setText(mainItems.get(i).geImgName());
Log.d("###", "Setting name: " + name);
Picasso.with(mContext)
.load(R.drawable.upload).resize(240, 120)
.into(((ViewHolder) holder).img_items);
Log.d("###", "Setting url: " + urlimage);
} else if (holder instanceof ViewHolderHeader) {
//cast holder to VHHeader and set data for header.
((ViewHolder) holder).tv_items.setText(mainItems.get(i).geImgName());
Log.d("####", "HEADER");
}
//
// viewHolder.tv_items.setText(mainItems.get(i).geImgName());
// Picasso.with(mContext)
// .load(mainItems.get(i)
// .getImgUrl()).resize(240, 120)
// .into(viewHolder.img_items);
}
#Override
public int getItemCount() {
return mainItems.size();
}
#Override
public int getItemViewType(int position) {
if (isPositionHeader(position)) {
return TYPE_HEADER;
}
return TYPE_ITEM;
}
private boolean isPositionHeader(int position) {
return position == 0;
}
public class ViewHolder extends RecyclerView.ViewHolder{
private TextView tv_items;
private ImageView img_items;
private ImageView mDataImgView;
public ViewHolder(View view) {
super(view);
tv_items = (TextView)view.findViewById(R.id.tv_items_horz);
img_items = (ImageView) view.findViewById(R.id.img_items_horz);
}
public ImageView getmDataImgView()
{
return mDataImgView;
}
}
public class ViewHolderHeader extends RecyclerView.ViewHolder{
private final RecyclerView mHorizontalRecyclerView;
public ViewHolderHeader(View v) {
super(v);
mHorizontalRecyclerView = (RecyclerView) v.findViewById(R.id.recycler_view_horizontal);
MainItemsRCVAdapterHorizontal mAdapter = new MainItemsRCVAdapterHorizontal(getMaindata(), mContext);
LinearLayoutManager layoutManager
= new LinearLayoutManager(mContext, LinearLayoutManager.HORIZONTAL, false);
mHorizontalRecyclerView.setLayoutManager(layoutManager);
mHorizontalRecyclerView.setAdapter(mAdapter);
}
}
}
this is the horizontal
public class MainItemsRCVAdapterHorizontal extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final ArrayList<ListMainItem> mData;
private final Context mContext;
public MainItemsRCVAdapterHorizontal(ArrayList<ListMainItem> dataHorizontal,Context context) {
mData = dataHorizontal;
mContext=context;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.main_adapter_horizontal, parent, false);
return new MainItemsRCVAdapterHorizontal.MyViewHolderHeader(v);
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
String name = mData.get(position).geImgName();
Log.d("###", "Setting name: " + name);
// ((RecyclerViewAdapterHorizontal.MyViewHolderHeader) holder).getmDataTextView().setText(name);
((MainItemsRCVAdapterHorizontal.MyViewHolderHeader) holder).getmDataImgView().setImageResource(mContext.getResources().getIdentifier(name, "drawable", "com.example.mohamadmouazen.lebgame.Adapters"));
}
#Override
public int getItemCount() {
return mData.size();
}
private class MyViewHolderHeader extends RecyclerView.ViewHolder {
// private final TextView mDataTextView;
private final ImageView mDataImgView;
public MyViewHolderHeader(View v) {
super(v);
// mDataTextView = (TextView) v.findViewById(R.id.data_vertical);
mDataImgView = (ImageView) v.findViewById(R.id.img_items_horz);
}
public ImageView getmDataImgView() {
return mDataImgView;
}
/* public TextView getmDataTextView() {
return mDataTextView;
}*/
}
}
Because you are making Invalid Casting.
Check your code:
} else if (holder instanceof ViewHolderHeader) {
//cast holder to VHHeader and set data for header.
((ViewHolder) holder).tv_items.setText(mainItems.get(i).geImgName());
Log.d("####", "HEADER");
}
You are casting ViewHolderHeader to ViewHolder

Android cards multiple layouts based on position

I want to use different layouts based on card position on screen. For example I need that first card (position 0 uses layout first_card.xml) and other cards should use other_cards.xml layout and it should be positioned horizontally (see picture below (picture taken from official google site)).
Here's my code
public class CardAdapter extends RecyclerView.Adapter<CardAdapter.ViewHolder>{
private List<CardData> mItems;
private Context context;
private SendInfoToCards cardDatas;
private boolean mainMenu;
private static final int FIRST = 1;
private static final int SECOND = 2;
public CardAdapter(Context c, SendInfoToCards datas, boolean main) {
super();
this.context = c;
this.cardDatas = datas;
mItems = datas.getList();
this.mainMenu = main;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int position) {
if(!mainMenu) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.recycler_view_card_item, viewGroup, false);
ViewHolder viewHolder = new ViewHolder(v);
v.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
TextView city = (TextView) v.findViewById(R.id.tv_movie);
String fragmentSwitcher = city.getText().toString();
if (fragmentSwitcher.equals("Zemelapis")) {
switchFragments(0);
} else {
switchFragments(1);
}
}
});
return viewHolder;
} else {
View v;
if(position == 0){
v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.first_layout, viewGroup, false);
}else{
v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.second_layout, viewGroup, false);
}
ViewHolder viewHolder = new ViewHolder(v);
v.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
TextView city = (TextView) v.findViewById(R.id.tv_movie);
String fragmentSwitcher = city.getText().toString();
}
});
return viewHolder;
}
}
private void switchFragments(int nr){
if(nr == 0){
Log.d("TAG", "mapo");
} else {
Intent intent = new Intent(context, DetailTourActivity.class);
context.startActivity(intent);
}
}
#Override
public void onBindViewHolder(ViewHolder viewHolder, int i) {
if(i != 0){
} else {
CardData data = mItems.get(i);
viewHolder.tvMovie.setText(data.getName());
viewHolder.imgThumbnail.setImageResource(data.getThumbnail());
}
}
#Override
public int getItemCount() {
return mItems.size();
}
class ViewHolder extends RecyclerView.ViewHolder{
public ImageView imgThumbnail;
public TextView tvMovie;
public ViewHolder(View itemView) {
super(itemView);
imgThumbnail = (ImageView)itemView.findViewById(R.id.img_thumbnail);
tvMovie = (TextView)itemView.findViewById(R.id.tv_movie);
}
}
}
Sadly but onCreateViewHolder method second argument position is always 0. Why is that? How to fix it?
Here is what your adapter class should roughly look like
public class CardAdapter extends RecyclerView.Adapter<RecylerView.ViewHolder>{
private List<CardData> mItems;
private Context context;
private SendInfoToCards cardDatas;
private boolean mainMenu;
private static final int FIRST = 1;
private static final int SECOND = 2;
public CardAdapter(Context c, SendInfoToCards datas, boolean main) {
super();
this.context = c;
this.cardDatas = datas;
mItems = datas.getList();
this.mainMenu = main;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int type) {
if(type == SECOND){
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.second_layout, viewGroup, false);
return new SecondViewViewHolder(v);
} else {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.first_layout, viewGroup, false);
return new FirstViewViewHolder(v);
}
}
#Override
public void onBindViewHolder(ViewHolder viewHolder, int i) {
if(viewHolder instanceof SecondViewViewHolder){
SecondViewViewHolder secondViewViewHolder = (SecondViewViewHolder) viewHolder;
// bind second views
secondViewViewHolder.imgThumbnail.setImageResource(R.id.img_resource);
} else {
FirstViewViewHolder firstViewViewHolder = (FirstViewViewHolder) viewHolder;
// bind firs view
firstViewViewHolder.imgThumbnail.setImageResource(R.id.img_resource);
}
}
#Override
public int getItemViewType(int position) {
if (position == 0) {
return FIRST;
} else {
return SECOND;
}
}
#Override
public int getItemCount() {
return mItems.size();
}
class FirstViewViewHolder extends RecyclerView.ViewHolder{
public ImageView imgThumbnail;
public TextView tvMovie;
public FirstViewViewHolder(View itemView) {
super(itemView);
imgThumbnail = (ImageView)itemView.findViewById(R.id.img_thumbnail);
tvMovie = (TextView)itemView.findViewById(R.id.tv_movie);
}
}
class SecondViewViewHolder extends RecyclerView.ViewHolder{
public ImageView imgThumbnail;
public TextView tvMovie;
public ImageView imgThumbnail2;
public TextView tvMovie2;
public SecondViewViewHolder(View itemView) {
super(itemView);
//find viewby id
}
}
}
What is changed
Since recyclerview can handle multiple view types you can decide which layout to inflate depending on some condition. You do this by overriding getItemViewTypeMethod() of the RecylerView Adapter
#Override
public int getItemViewType(int position) {
if (position == 0) {
return FIRST;
} else {
return SECOND;
}
}
When creating viewholder. the onCreateViewHolder method will get the view type. Based on the type you should inflate the appropriate layout and return the appropriate viewholder
#Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int type) {
if(type == SECOND){
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.second_layout, viewGroup, false);
return new SecondViewViewHolder(v);
} else {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.first_layout, viewGroup, false);
return new FirstViewViewHolder(v);
}
}
Since there are two layouts involved, I have created two View Holders to hold first and second layouts. (FirstViewHolder & SecondViewHolder). Because of this you have to set your adapter's ViewHolder type to the base ViewHolder class like this
public class CardAdapter extends RecyclerView.Adapter<RecylerView.ViewHolder>{
...
}
and now in the onBindViewHolder method, you can determine which ViewHolder is currently being bound and do your work accordingly
#Override
public void onBindViewHolder(ViewHolder viewHolder, int i) {
if(viewHolder instanceof SecondViewViewHolder){
SecondViewViewHolder secondViewViewHolder = (SecondViewViewHolder) viewHolder;
// bind second views
secondViewViewHolder.imgThumbnail.setImageResource(R.id.img_resource);
} else {
FirstViewViewHolder firstViewViewHolder = (FirstViewViewHolder) viewHolder;
// bind firs view
firstViewViewHolder.imgThumbnail.setImageResource(R.id.img_resource);
}
}
Check this for an example
The thing is that the second parameter is not position, it is viewType.
From the docs:
public abstract VH onCreateViewHolder (ViewGroup parent, int viewType)
Look at public void onBindViewHolder (VH holder, int position, List<Object> payloads), this is what you actually need

Implementing RecyclerView with Sectioned Header based on Category

I am trying to implement RecyclerView with custom sectioned header based on list's category. I already have a list that's sorted based on their category, so I want to inflate header if and only if one row's category is different from preceding row's category. I've been figuring out how to do it but something bothering me here. It worked, but does not display the right row. I think it's because of the item count which is increased due to the header. Can anyone help me?
Here is my adapter :
List<Notes> notes;
OnItemClickListener mItemClickListener;
private static final int TYPE_CATEGOORY = 0;
private static final int TYPE_ITEM = 1;
String changing = "";
public OneNoteAdapter(List<Notes> logs) {
this.notes = logs;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if(viewType == TYPE_CATEGOORY){
View itemView = LayoutInflater.
from(parent.getContext()).
inflate(R.layout.category_header, parent, false);
return new HeaderViewHolder(itemView);
}else{
View itemView = LayoutInflater.
from(parent.getContext()).
inflate(R.layout.learn_card, parent, false);
return new ItemViewHolder(itemView);
}
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if(holder instanceof HeaderViewHolder){
Notes note = notes.get(position);
((HeaderViewHolder) holder).vCategoryText.setText(note.category);
}else {
ItemViewHolder item = (ItemViewHolder) holder;
Notes note = notes.get(position);
item.vNotesNote.setText(note.notes);
item.vNotesCat.setText(note.category);
}
}
#Override
public int getItemViewType(int position) {
if((!(notes.get(position).category).equals(changing))){
changing = notes.get(position).category;
return TYPE_CATEGOORY;
}else{
return TYPE_ITEM;
}
}
#Override
public int getItemCount() {
return notes.size();
}
public class ItemViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
protected TextView vNotesNote, vNotesCat;
private final Context context;
public ItemViewHolder(View itemView) {
super(itemView);
vNotesNote = (TextView) itemView.findViewById(R.id.notes_notes);
vNotesCat = (TextView) itemView.findViewById(R.id.notes_category);
context = itemView.getContext();
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if(mItemClickListener != null){
mItemClickListener.onItemClick(v, getPosition());
}
}
}
public class HeaderViewHolder extends RecyclerView.ViewHolder {
protected TextView vCategoryText;
public HeaderViewHolder(View itemView) {
super(itemView);
vCategoryText = (TextView) itemView.findViewById(R.id.category_header_text);
}
}
public interface OnItemClickListener{
public void onItemClick(View v, int poition);
}
public void setOnItemClickListener (final OnItemClickListener mItemClickListener){
this.mItemClickListener = mItemClickListener;
}
}
Thank You
Try to replace your onBindViewHolder and getItemViewType methods with following:
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder instanceof HeaderViewHolder) {
((HeaderViewHolder) holder).vCategoryText.setText(notes.get(position + 1).category);
} else {
ItemViewHolder item = (ItemViewHolder) holder;
Notes note = notes.get(position);
item.vNotesNote.setText(note.notes);
item.vNotesCat.setText(note.category);
if (position + 1 < notes.size() &&
!notes.get(position + 1).category.equals(note.category)) {
notes.add(position + 1, null);
}
}
}
#Override
public int getItemViewType(int position) {
if (notes.get(position) == null) {
return TYPE_CATEGOORY;
} else {
return TYPE_ITEM;
}
}
And you can delete String changing = "";.

Categories

Resources