Make certain items of RecyclerView use different FrameLayouts? - android

I have the following adapter for a RecyclerView:
public class GreenAdapter extends RecyclerView.Adapter<GreenAdapter.NumberViewHolder> {
private final String TAG = GreenAdapter.class.getSimpleName();
private int mNumberItems;
public GreenAdapter(int numberOfItems) {
mNumberItems = numberOfItems;
}
#Override
public NumberViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
Context context = viewGroup.getContext();
int layoutIdForListItem = R.layout.number_list_item;
LayoutInflater inflater = LayoutInflater.from(context);
boolean shouldAttachToParentImmediately = false;
View view = inflater.inflate(layoutIdForListItem, viewGroup, shouldAttachToParentImmediately);
NumberViewHolder viewHolder = new NumberViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(NumberViewHolder holder, int position) {
Log.d(TAG, "#" + position);
holder.bind(position);
}
#Override
public int getItemCount() {
return mNumberItems;
}
class NumberViewHolder extends RecyclerView.ViewHolder {
TextView listItemNumberView;
public NumberViewHolder(View itemView) {
super(itemView);
listItemNumberView = (TextView) itemView.findViewById(R.id.TV1);
}
void bind(int listIndex) {
String[] messages = getResources().getStringArray(R.array.messageArray);
listItemNumberView.setText(messages[listIndex]);
}
}
}
what I want to do is to make the first item of it bigger. My approach would be something like the code below, but I guess there is a better way to do it, right?
public class GreenAdapter extends RecyclerView.Adapter<GreenAdapter.NumberViewHolder> {
boolean isFirst=true;
private final String TAG = GreenAdapter.class.getSimpleName();
private int mNumberItems;
public GreenAdapter(int numberOfItems) {
mNumberItems = numberOfItems;
}
#Override
public NumberViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
Context context = viewGroup.getContext();
int layoutIdForListItem = R.layout.number_list_item;
if(isFirst) {
isFirst=false;
layoutIdForListItem = R.layout.first;
}
LayoutInflater inflater = LayoutInflater.from(context);
boolean shouldAttachToParentImmediately = false;
View view = inflater.inflate(layoutIdForListItem, viewGroup, shouldAttachToParentImmediately);
NumberViewHolder viewHolder = new NumberViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(NumberViewHolder holder, int position) {
Log.d(TAG, "#" + position);
holder.bind(position);
}
#Override
public int getItemCount() {
return mNumberItems;
}
class NumberViewHolder extends RecyclerView.ViewHolder {
TextView listItemNumberView;
public NumberViewHolder(View itemView) {
super(itemView);
listItemNumberView = (TextView) itemView.findViewById(R.id.TV1);
}
void bind(int listIndex) {
String[] messages = getResources().getStringArray(R.array.messageArray);
listItemNumberView.setText(messages[listIndex]);
}
}
}

You should override the getItemViewType method.
Sample
public class GreenAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int VIEW_TYPE_LARGE = 1;
private static final int VIEW_TYPE_REGULAR = 2;
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == VIEW_TYPE_LARGE) {
// supply large layout
}
if (viewType == VIEW_TYPE_REGULAR) {
// supply regular layout
}
return null;
}
#Override
public int getItemViewType(int position) {
return position == 0 ? VIEW_TYPE_LARGE : VIEW_TYPE_REGULAR;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
}
#Override
public int getItemCount() {
return 0;
}
}

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

How to start activity in adapter

What I am trying to do is start an activity in my adapter but it seems that I'm getting an error on my other adapter.
java.lang.ClassCastException: com.lim.fiture.fiture.models.ProgramTracker cannot be cast to com.lim.fiture.fiture.models.ProgramExercise
the error points on my DayExerciseAdapter which it only contains two things; exerciseName and exerciseReps.
This is my DayExerciseAdapter this is where the error is
public class DayExerciseAdapter extends RecyclerView.Adapter<DayExerciseAdapter.ViewHolder> {
private Context context;
private ArrayList<ProgramExercise> programExercises;
public DayExerciseAdapter(Context context, ArrayList<ProgramExercise> programExercises) {
this.context = context;
this.programExercises = programExercises;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.day_exercise_layout_item, parent, false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.exerciseName.setText(programExercises.get(position).getExerciseName().toUpperCase());
holder.exerciseReps.setText(String.valueOf(programExercises.get(position).getReps()));
}
#Override
public int getItemCount() {
return programExercises.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView exerciseName, exerciseReps, doneTxt;
public ViewHolder(View itemView) {
super(itemView);
exerciseName = itemView.findViewById(R.id.exerciseName);
exerciseReps = itemView.findViewById(R.id.exerciseReps);
doneTxt = itemView.findViewById(R.id.doneTxt);
}
}
}
This is where I am starting my activity intent
public class UserProgramWeekAdapter extends RecyclerView.Adapter<UserProgramWeekAdapter.ViewHolder> {
private Context context;
private ArrayList<ProgramTrackerWrapper> programTrackers;
public UserProgramWeekAdapter(Context context, ArrayList<ProgramTrackerWrapper> programTrackers) {
this.context = context;
this.programTrackers = programTrackers;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.activity_user_program_week_adapter, parent, false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(UserProgramWeekAdapter.ViewHolder holder, int position) {
Log.d("UserProgramWeekAdapter", "Day: " + programTrackers.get(position).getDay());
Log.d("UserProgramWeekAdapter", "Size: " + programTrackers.get(position).getProgramTrackers().size());
holder.dayTxt.setText(programTrackers.get(position).getDay());
holder.numberofExercises.setText(programTrackers.get(position).getProgramTrackers().size() + " exercise/s");
boolean isFinished = false;
final int sublistSize = programTrackers.get(position).getProgramTrackers().size();
for (int i = 0; i < sublistSize; i++) {
if (programTrackers.get(position).getProgramTrackers().get(i).isProgramExerciseFinished()) {
isFinished = true;
}
#Override
public int getItemCount() {
return programTrackers.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView dayTxt, exerciseCompleted, numberofExercises;
CardView dayCard;
public ViewHolder(View itemView) {
super(itemView);
dayTxt = itemView.findViewById(R.id.dayTxt);
exerciseCompleted = itemView.findViewById(R.id.exerciseCompleted);
numberofExercises = itemView.findViewById(R.id.numberofExercises);
dayCard = itemView.findViewById(R.id.dayCard);
dayCard.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
((StartProgramActivity) context).setWeekExercisesData(getAdapterPosition());
ArrayList<ProgramTracker> programTrackerWrappers = ((StartProgramActivity) context).getDayOfWeekExercises();
if (programTrackerWrappers.size() > 0) {
context.startActivity(new Intent(context.getApplicationContext(), DayExerciseActivity.class).putExtra("programExercises", programTrackerWrappers));
}else {
CustomToast customToast = new CustomToast(context);
customToast.setTextColor(context.getResources().getColor(R.color.white));
customToast.setBackground(context.getResources().getColor(R.color.color_2));
customToast.showErrorToast("No exercises for this day.");
}
}
});
}
}
What I am getting: //error//
"Error in DayExerciseActivity"
Firstly you should use context instead of context.getApplicationContext and now talk about the problem
you are passing Arrylist of programTracker in putExtra
context.startActivity(new Intent(context.getApplicationContext(), DayExerciseActivity.class).putExtra("programExercises", programTrackerWrappers));
And I am sure that you are in DayExerciseActivity parsing it by ArrayList of programExercise that's why you are getting this casting error.because programTracker can not cast in to programExersce

return value shows variable might not have been initialise while using if else

I am using recycler view and creating a popular list of video ..and I have 2 viewholder 1 for Photo another for Video I use this code for differentiating photo and video ...but when I return view type using if else it shows it is not initialise ...how can I solve this is there any new way I can do this.
this is my image
this is my code
public class Trending_adapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int VIDEO_TYPE=0;
private static final int IMAGE_TYPE=1;
private LayoutInflater mInflater;
private VideoHolder mVideoHolder;
private PhotoHolder mPhotoHolder;
private int viewType;
class PhotoHolder extends RecyclerView.ViewHolder {
public PhotoHolder(View view){
super(view);
}
}
class VideoHolder extends RecyclerView.ViewHolder {
static final int LAYOUT_RES = R.layout.main_list;
private ExoPlayerViewHelper helper;
private CircleImageView profile_image;
//private String likeString;
public VideoHolder(View view) {
super(view);
}
}
public Trending_adapter(List<Photo> moviesList) {
this.moviesList = moviesList;
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
//findViewById...
mContext = parent.getContext();
switch (viewType) {
case VIDEO_TYPE:
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.video_type, parent, false);
mContext = parent.getContext();
return new VideoHolder(v);
case IMAGE_TYPE:
View i = LayoutInflater.from(parent.getContext()).inflate(R.layout.main_list, parent, false);
mContext = parent.getContext();
return new PhotoHolder(i);
}
return null;
}
#Override
public void onBindViewHolder(#NonNull final RecyclerView.ViewHolder holder, final int position) {
// mHolder = holder;
// photo = getItem(position);
// photo = moviesList.get(holder.getAdapterPosition());
// final VideoHolder viewHolder2 = (VideoHolder)holder;
int viewType = getItemViewType(position);
switch ( viewType ) {
case IMAGE_TYPE:
break;
case VIDEO_TYPE:
break;
}
}
#Override
public int getItemCount() {
return moviesList.size();
}
#Override
public int getItemViewType ( int position ) {
int compare;
int viewType ;
if(moviesList.get(position).getPopularlist().contains("true")){
if (moviesList.get(position).getType_post().contains("Photo")) {
viewType = IMAGE_TYPE;
} else {
viewType = VIDEO_TYPE;
}
}
return viewType = over here it shows in red underline under view type;
}
public Photo getItem(int position) {
return moviesList.get(position);
Its because you have not given any view type in the false case of your if condition
if(moviesList.get(position).getPopularlist().contains("true"))
In getItemViewType initiallize int viewType with a default value.
int viewType = IMAGE_TYPE; // default view type
Full code is
#Override
public int getItemViewType ( int position ) {
int compare;
int viewType = DEFAULT_TYPE; // provide a default view if all conditions fail
// rest of the code
return viewType;
}
Just add another field in you model class :
class Photo{
public static final int VIDEO_TYPE=1;
public static final int IMAGE_TYPE=2;
// your fileds
public int type;// ( update this field at the time of building your list
//apply your logic for differentciate VIDEO_TYPE & IMAGE_TYPE )
}
update type as VIDEO_TYPE OR IMAGE_TYPE;
public class Trending_adapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
ArrayList<Photo> moviesList=new ArrayList<>();
public Trending_adapter(List<Photo> moviesList) {
this.moviesList = moviesList;
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
//findViewById...
mContext = parent.getContext();
switch (viewType) {
case Photo.VIDEO_TYPE:
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.video_type, parent, false);
mContext = parent.getContext();
return new VideoHolder(v);
case Photo.IMAGE_TYPE:
View i = LayoutInflater.from(parent.getContext()).inflate(R.layout.main_list, parent, false);
mContext = parent.getContext();
return new PhotoHolder(i);
}
return null;
}
#Override
public int getItemViewType ( int position ) {
return moviesList.get(position).type;
}
#Override
public int getItemCount() {
return moviesList.size();
}
#Override
public void onBindViewHolder(#NonNull final RecyclerView.ViewHolder holder, final int position) {
Photo model=moviesList.get(position);
switch ( model.type ) {
case IMAGE_TYPE:
//do your stuff here for IMAGE_TYPE type
break;
case VIDEO_TYPE:
//do your stuff here for VIDEO_TYPE type
break;
}
}
class VideoHolder extends RecyclerView.ViewHolder {
static final int LAYOUT_RES = R.layout.main_list;
private ExoPlayerViewHelper helper;
private CircleImageView profile_image;
//private String likeString;
public VideoHolder(View view) {
super(view);
}
}
class PhotoHolder extends RecyclerView.ViewHolder {
public PhotoHolder(View view){
super(view);
}
}
}
It works fine for you.

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

Categories

Resources