Android inflate two layouts in recycler view adapter - java

i am trying to inflate two different layouts in one recycler view. Here is my adapter code.
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.ArrayList;
public class HomeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private ArrayList<myHome> homeData;
private static final int TYPE_FEATURED = 1;
private static final int TYPE_OTHER = 2;
public HomeAdapter(ArrayList<myHome> myDataset) {
this.homeData = myDataset;
}
public class FeaturedViewHolder extends RecyclerView.ViewHolder {
public TextView title;
public TextView author;
public FeaturedViewHolder(View itemView) {
super(itemView);
this.title = (TextView)itemView.findViewById(R.id.title);
this.author = (TextView)itemView.findViewById(R.id.recvid_auth);
}
}
public class otherVidViewHolder extends RecyclerView.ViewHolder {
public TextView rec_title;
public TextView rec_author;
public otherVidViewHolder(View itemView) {
super(itemView);
this.rec_title = (TextView)itemView.findViewById(R.id.recvid_title);
this.rec_author = (TextView)itemView.findViewById(R.id.description);
}
}
#Override
public int getItemViewType(int position) {
// Just as an example, return 0 or 2 depending on position
// Note that unlike in ListView adapters, types don't have to be contiguous
return (position == 0? TYPE_FEATURED : TYPE_OTHER);
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
RecyclerView.ViewHolder viewHolder;
LayoutInflater inflater = LayoutInflater.from(viewGroup.getContext());
switch (viewType) {
case TYPE_FEATURED :
View v1 = inflater.inflate(R.layout.layout_home_view, viewGroup, false);
viewHolder = new FeaturedViewHolder(v1);
//return new FeaturedViewHolder(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.layout_home_view, viewGroup, false));
break;
case TYPE_OTHER :
View v2 = inflater.inflate(R.layout.layout_home_other, viewGroup, false);
viewHolder = new otherVidViewHolder(v2);
//return new otherVidViewHolder(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.layout_home_other, viewGroup, false));
break;
default: return null;
}
return viewHolder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int i) {
if(viewHolder.getItemViewType() == TYPE_FEATURED) {
FeaturedViewHolder featuredViewHolder = (FeaturedViewHolder) viewHolder;
featuredViewHolder.title.setText(homeData.get(i).getTitle());
featuredViewHolder.author.setText(homeData.get(i).getUser());
} else {
otherVidViewHolder otherViewHolder = (otherVidViewHolder) viewHolder;
otherViewHolder.rec_title.setText(homeData.get(i).getViews());
}
}
#Override
public int getItemCount() {
return homeData.size();
}
the code is running properly but it only shows one layout, the other layout which is the layout_home_other is not showing. is it possible to show the two layouts? the two layouts also have different datas to show. how will i retun the size of the second layout in getItemCount() also? thank you for all the help i will get.
here is the dataset.
public class myHome {
String title;
String user;
String views;
String url;
String duration;
public myHome(String title, String user, String views, String url, String duration) {
this.title = title;
this.user = user;
this.views = views;
this.url = url;
this.duration = duration;
}
public String getTitle() {
return title;
}
public String getUser() {
return user;
}
public String getViews() {
return views;
}
public String getUrl() {
return url;
}
public String getDuration() {
return duration;
}
}

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
// CONSTRUCTOR
public RecyclerViewAdapter(Context context,"OTHER PARAMETERS) {
this.context = context;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view ;
switch (viewType){
case -1:
view = inflater.inflate(R.layout.LAYOUTONE, null, false);
return new ExpiredViewHolder(view);
case 0:
view = inflater.inflate(R.layout.LAYOUTTWO, null, false);
return new ActiveViewHolder(view);
}
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder instanceof ExpiredViewHolder) {
((ExpiredViewHolder) holder).bind(tickerList.get(position));
} else {
if (holder instanceof ActiveViewHolder) {
((ActiveViewHolder) holder).bind(tickerList.get(position));
}
else {
((FutureViewHolder) holder).bind(tickerList.get(position));
}
}
}
#Override
public int getItemViewType(int position) {
return List.get(position).status;
}
#Override
public int getItemCount() {
return List.size();
}
static class ActiveViewHolder extends RecyclerView.ViewHolder {
//Your layout components
public ActiveViewHolder(View view) {
super(view);
//Instantiate you layout components fromyout view
}
public void bind(Params) {
//PUT TEXT TO YOUR FIELDS OR COMPONENTS
}
}
class ExpiredViewHolder extends RecyclerView.ViewHolder {
public ExpiredViewHolder(View view) {
super(view);
}
public void bind(Params) {
}
}
static class FutureViewHolder extends RecyclerView.ViewHolder {
public FutureViewHolder( View view) {
super(view);
}
public void bind(Params) {
}
}
}
public class MainClass{
RecyclerView mRecyclerView ;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
adapter = new RecyclerViewAdapter(getActivity(), arrayTicker);
mRecyclerView.setAdapter(adapter);
return view;
}
}

Related

How to pass information from one adapter to other?

i have two adapters one for my card view and the other one for my drawer. The cards contains links to other options in the app and the drawer contains the same options. What i want is when user clicks on the card, the options in the drawer menu should get selected. Here is my code.
Drawer Adapter:
#SuppressWarnings({"rawtypes", "ConstantConditions"})
public class DrawerAdapter extends RecyclerView.Adapter<DrawerAdapter.ViewHolder> {
private List<DrawerItem> items;
private Map<Class<? extends DrawerItem>, Integer> viewTypes;
private SparseArray<DrawerItem> holderFactories;
private OnItemSelectedListener listener;
public DrawerAdapter(List<DrawerItem> items) {
this.items = items;
this.viewTypes = new HashMap<>();
this.holderFactories = new SparseArray<>();
processViewTypes();
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
ViewHolder holder = holderFactories.get(viewType).createViewHolder(parent);
holder.adapter = this;
return holder;
}
#Override
#SuppressWarnings("unchecked")
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
items.get(position).bindViewHolder(holder);
}
#Override
public int getItemCount() {
return items.size();
}
#Override
public int getItemViewType(int position) {
return viewTypes.get(items.get(position).getClass());
}
private void processViewTypes() {
int type = 0;
for (DrawerItem item : items) {
if (!viewTypes.containsKey(item.getClass())) {
viewTypes.put(item.getClass(), type);
holderFactories.put(type, item);
type++;
}
}
}
public void setSelected(int position) {
DrawerItem newChecked = items.get(position);
if (!newChecked.isSelectable()) {
return;
}
for (int i = 0; i < items.size(); i++) {
DrawerItem item = items.get(i);
if (item.isChecked()) {
item.setChecked(false);
notifyItemChanged(i);
break;
}
}
newChecked.setChecked(true);
notifyItemChanged(position);
if (listener != null) {
listener.onItemSelected(position);
}
}
public void setListener(OnItemSelectedListener listener) {
this.listener = listener;
}
static abstract class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private DrawerAdapter adapter;
public ViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
adapter.setSelected(getAdapterPosition());
}
}
public interface OnItemSelectedListener {
void onItemSelected(int position);
}
}
Card Adapter:
public class CardAdapter extends RecyclerView.Adapter<CardAdapter.ViewHolder> {
;
private RecyclerView parentRecycler;
private List<Card> data;
public CardAdapter(List<Card> data) {
this.data = data;
}
#Override
public void onAttachedToRecyclerView(#NonNull RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
parentRecycler = recyclerView;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View v = inflater.inflate(R.layout.item_card, parent, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Card card = data.get(position);
holder.getAdapterPosition();
Glide.with(holder.itemView.getContext())
.asGif()
.load(card.getCardIcon())
.into(holder.gifImageView);
holder.textView.setText(card.getCardName());
}
#Override
public int getItemCount() {
return data.size();
}
class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private GifImageView gifImageView;
private TextView textView;
public ViewHolder(View itemView) {
super(itemView);
gifImageView = itemView.findViewById(R.id.card_gif);
textView = itemView.findViewById(R.id.card_name);
itemView.findViewById(R.id.container).setOnClickListener(this);
}
public void showText() {
int parentHeight = ((View) gifImageView.getParent()).getHeight();
float scale = (parentHeight - textView.getHeight()) / (float) gifImageView.getHeight();
gifImageView.setPivotX(gifImageView.getWidth() * 0.5f);
gifImageView.setPivotY(0);
gifImageView.animate().scaleX(scale)
.withEndAction(new Runnable() {
#Override
public void run() {
textView.setVisibility(View.VISIBLE);
// gifImageView.setColorFilter(Color.BLACK);
}
})
.scaleY(scale).setDuration(200)
.start();
}
public void hideText() {
textView.setVisibility(View.INVISIBLE);
gifImageView.animate().scaleX(1f).scaleY(1f)
.setDuration(200)
.start();
}
#Override
public void onClick(View v) { parentRecycler.smoothScrollToPosition(getAdapterPosition());
}
}
}
}
P.S: I am new to programming any kind of help is appreciated.[As you can see in the image below that I have cards in the main view and the same options are in the drawer menu for example question papers. Now when the user clicks on question paper in the main view the question paper in drawer menu should get selected.[][1]][1]
thank you!
[1]: https://i.stack.imgur.com/FooVb.jpg

RecyclerView is duplicating the first three items on a list

Im fairly new to android and i am trying to use a RecyclerView to display content hosted on firebase, but when it comes up the first three items are duplicated.
I have tried a few solutions around but none seem to work, any help would be great!
DiscountRecyclerAdapter.java
public class DiscountRecyclerAdapter extends RecyclerView.Adapter<com.cianod.comharapp.DiscountRecyclerAdapter.ViewHolder> {
public List<Discounts> discountsList;
public Context context;
private ImageView discountImageView;
public DiscountRecyclerAdapter(List<Discounts> discountsList){
this.discountsList = discountsList;
}
#Override
public com.cianod.comharapp.DiscountRecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.discount_list_item, parent, false);
context = parent.getContext();
return new com.cianod.comharapp.DiscountRecyclerAdapter.ViewHolder(view);
}
#Override
public void onBindViewHolder(final com.cianod.comharapp.DiscountRecyclerAdapter.ViewHolder holder, int position) {
holder.setIsRecyclable(false);
String discountName = discountsList.get(position).getDiscount_name();
holder.setDiscount_Name(discountName);
String discountDescription = discountsList.get(position).getDiscount_description();
holder.setDiscount_Description(discountDescription);
String discountValue = discountsList.get(position).getDiscount_value();
holder.setDiscount_Value(discountValue);
String image_url = discountsList.get(position).getDiscount_image();
String thumbUri = discountsList.get(position).getDiscount_image();
holder.setDiscount_Image(image_url, thumbUri);
}
#Override
public int getItemCount() {
if(discountsList != null) {
return discountsList.size();
} else {
return 0;
}
}
public class ViewHolder extends RecyclerView.ViewHolder {
private View mView;
private TextView discount_name;
public ViewHolder(View itemView) {
super(itemView);
mView = itemView;
}
public void setDiscount_Name(String message){
discount_name = mView.findViewById(R.id.discount_name);
discount_name.setText(message);
}
public void setDiscount_Description(String message){
discount_name = mView.findViewById(R.id.discount_description);
discount_name.setText(message);
}
public void setDiscount_Value(String message){
discount_name = mView.findViewById(R.id.discount_value);
discount_name.setText(message);
}
public void setDiscount_Image(String downloadUri, String thumbUri){
discountImageView = mView.findViewById(R.id.discount_image);
RequestOptions requestOptions = new RequestOptions();
requestOptions.placeholder(R.drawable.image_placeholder);
Glide.with(context).applyDefaultRequestOptions(requestOptions).load(downloadUri).thumbnail(
Glide.with(context).load(thumbUri)
).into(discountImageView);
}
}
}
I believe the problem is coming from the discount adapter but I cant say for sure. The RecyclerView is displayed on a fragment if that could be influencing it I can attach other pieces if they are necessary.
There is nothing wrong with your code.So maybe you should try to override those two methods in your adapter class
#Override
public long getItemId(int position) {
return position;
}
#Override
public int getItemViewType(int position) {
return position;
}

Create Base Adapters For All Recycler View Adapters

public abstract class BaseAdapters extends RecyclerView.Adapter<BaseAdapters.MyViewHolder> implements View.OnClickListener {
protected Context parentContext;
public int layout_id;
protected List<?> dataList = new ArrayList<>();
public class MyViewHolder extends RecyclerView.ViewHolder {
MyViewHolder(View view) {
super(view);
declareViews(view,this);
}
}
#Override
public void onClick(View view) {
onClickViews(view);
}
#Override
public int getItemViewType(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, int i) {
bindView(holder, i);
}
public void notifyList(List<?> filterdNames) {
this.dataList = filterdNames;
notifyDataSetChanged();
}
#Override
public int getItemCount() {
if (dataList.size() == 0)
return 5;
else
return dataList.size();
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int i) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(layout_id, parent, false);
return new MyViewHolder(itemView);
}
public abstract MyViewHolder bindView(MyViewHolder holder, int position);
public abstract void onClickViews(View view);
public abstract void declareViews(View view,MyViewHolder holder);
}
How can i perform on click of every item selection using holder in child class extending with it.
import android.app.Activity;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.List;
public abstract class BaseAdapter extends RecyclerView.Adapter<BaseAdapter.MyViewHolder> {
public int layout_id;
protected List<?> dataList = new ArrayList<>();
Context BASE_CONTEXT;
public View itemview;
public BaseAdapter(Context context) {
this.BASE_CONTEXT = context;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(layout_id, viewGroup, false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder viewHolder, int position) {
onBindViewHold(position, dataList.get(position));
}
public abstract View getView(View view);
#Override
public int getItemCount() {
return dataList.size() == 0 ? 0 : dataList.size();
}
public abstract void onBindViewHold(int position, Object itemView);
class MyViewHolder extends RecyclerView.ViewHolder {
public MyViewHolder(#NonNull View itemView) {
super(itemView);
itemview = itemView;
getView(itemView);
}
}
public <T extends View> T bind(int id) {
return itemview.findViewById(id);
}
}
public class Adapter extends BaseAdapter {
TextView tv;
Adapter(Context context, ArrayList<String> arrayList){
super(context);
dataList=arrayList;
layout_id=R.layout.content_main2;
}
#Override
public View getView(View view) {
tv = bind(R.id.tv);
return view;
}
#Override
public void onBindViewHold( final int position, Object itemView) {
String text=(String) itemView;
Log.e("tv",tv.toString());
tv.setText(text);
tv.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(BASE_CONTEXT, ""+position, Toast.LENGTH_SHORT).show();
}
});
}
}
You can refer this sample adapter class and edit it as per your requirement:
public class absadapter extends RecyclerView.Adapter<absadapter.exViewHolder> {
List<abs.Ex> exList;
Context context;
absadapter(List exList) {
this.exList= exList;
}
public static class exViewHolder extends RecyclerView.ViewHolder{
CardView cardView;
TextView exname;
ImageView exlogo;
exViewHolder(View itemView){
super(itemView);
cardView= itemView.findViewById(R.id.cardView);
exname= itemView.findViewById(R.id.ex_name);
exlogo=itemView.findViewById(R.id.exlogo);
}
}
#Override
public absadapter.exViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
View viewthigh= LayoutInflater.from(parent.getContext()).inflate(R.layout.custom_abslayout,parent,false);
absadapter.exViewHolder evh=new absadapter.exViewHolder(viewthigh);
return evh;
}
#Override
public void onBindViewHolder(final absadapter.exViewHolder holder, final int position){
holder.exname.setText(exList.get(position).name);
holder.exlogo.setImageResource(exList.get(position).logoId);
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (position == 0 ){
v.getContext().startActivity(new Intent(v.getContext(), abdetails.class));
}
if (position == 1) {
v.getContext().startActivity(new Intent(v.getContext(), declinecrunch.class));
}
if (position == 2) {
v.getContext().startActivity(new Intent(v.getContext(), dumsidebend.class));
}
}
});
}
#Override
public void onAttachedToRecyclerView(RecyclerView recyclerView){
super.onAttachedToRecyclerView(recyclerView);
}
#Override
public int getItemCount() {
return exList.size();
}
Refer this for Main Class:
public class abs extends AppCompatActivity {
RecyclerView recyclerView;
Context context;
private List<Ex> exlist;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_abs);
recyclerView= findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
LinearLayoutManager layoutManager=new LinearLayoutManager(context);
recyclerView.setLayoutManager(layoutManager);
initializeData();
initializeAdapter();
}
private void initializeData(){
exlist=new ArrayList<>();
exlist.add(new abs.Ex("Crunches",R.drawable.crunchesgif));
exlist.add(new abs.Ex("Decline Crunch",R.drawable.declinecrunch));
exlist.add(new abs.Ex("Dumbell Side Bends",R.drawable.dumbbellsidebend));
exlist.add(new abs.Ex("Hanging Leg Raises",R.drawable.hanginglegraises));
exlist.add(new abs.Ex("Incline Leg Raises",R.drawable.inclinelegraises));
exlist.add(new abs.Ex("Kneeling Cable Crunch",R.drawable.cablecrunch));
exlist.add(new abs.Ex("Legs Raises",R.drawable.legraises));
exlist.add(new abs.Ex("Flat Bench Lying Leg Raises",R.drawable.flatbenchlyinglegraise));
exlist.add(new abs.Ex("Seated Jack Knife",R.drawable.seatedjackknife));
exlist.add(new abs.Ex("Twisting Hip Raise",R.drawable.twistinghipraise));
exlist.add(new abs.Ex("Weighted Crunch",R.drawable.weightedcrunch));
exlist.add(new abs.Ex("Plank",R.drawable.plank));
exlist.add(new abs.Ex("Side Plank",R.drawable.sideplank));
exlist.add(new abs.Ex("Superman",R.drawable.superman));
exlist.add(new abs.Ex("Twist Crunch",R.drawable.twistcrunch));
}
public void initializeAdapter(){
absadapter rvadapter=new absadapter(exlist);
recyclerView.setAdapter(rvadapter);
}
class Ex{
String name;
int logoId;
Ex(String name,int logoId){
this.name=name;
this.logoId=logoId;
}
}
This is extend version of rupali answer, i found recycle issue on recycle-view viewholder while scrolling on items. so if needed you can use below one,
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.List;
public abstract class BaseRecyclerViewAdapter extends RecyclerView.Adapter<BaseRecyclerViewAdapter.BaseViewHolder> {
public int layout_id;
protected List<?> dataList = new ArrayList<>();
protected BaseActivity Context;
public BaseRecyclerViewAdapter(BaseActivity context) {
this.Context = context;
}
#NonNull
#Override
public BaseViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(layout_id, viewGroup, false);
return new BaseViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull BaseViewHolder viewHolder, int position) {
onViewHolderBind(viewHolder,position, dataList.get(position));
}
#Override
public int getItemCount() {
return dataList.size();
}
public abstract void onViewHolderBind(BaseViewHolder viewHolder, int position, Object data);
public class BaseViewHolder extends RecyclerView.ViewHolder {
public BaseViewHolder(#NonNull View itemView) {
super(itemView);
}
}
}
Uses
public class LicenseListAdapter extends BaseRecyclerViewAdapter {
public LicenseListAdapter(BaseActivity appLicensePlanActivity, List<LicenseRatePlanResponse> licenseRatePlanResponseData) {
super(appLicensePlanActivity);
dataList = licenseRatePlanResponseData;
layout_id = R.layout.item_list_license_plan;
}
#Override
public void onViewHolderBind(BaseViewHolder viewHolder, int position, Object data) {
Button btnBuyButtonOfLicencePlaneILLP;
TextView lblAmountOfLicencePlaneILLP, lblDayOfLicencePlaneILLP;
lblAmountOfLicencePlaneILLP = viewHolder.itemView.findViewById(R.id.lblAmountOfLicencePlaneILLP);
lblDayOfLicencePlaneILLP = viewHolder.itemView.findViewById(R.id.lblDayOfLicencePlaneILLP);
btnBuyButtonOfLicencePlaneILLP = viewHolder.itemView.findViewById(R.id.btnBuyButtonOfLicencePlaneILLP);
final LicenseRatePlanResponse tempLicensePlan = (LicenseRatePlanResponse) data;
lblAmountOfLicencePlaneILLP.setText(KSUtility.GetFloatWithOutPrecesion(tempLicensePlan.getAmount()).toString() +" only");
lblDayOfLicencePlaneILLP.setText(tempLicensePlan.getValidityDays().toString() +" days");
btnBuyButtonOfLicencePlaneILLP.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
PaymentHelper.OpenPaymentDialog(Context, TransactionType.LicenseRenew, tempLicensePlan.getAmount(),tempLicensePlan.getLicenseRatePlanId());
}
});
}
}
overriding the method which handles click events in sub-classes of "BaseAdapters" should do it( based on your comments on other posts i assume bindView() handles click events; override whichever method you know handles click events):
class new_adapter extends BaseAdapters{
//...
#Override
public MyViewHolder bindView(MyViewHolder holder, int position){
//you could alter how click events are handled here.
}
//...
}
There can be many ways, one of them is, you can use Java Generics.
Set click in your onCreateViewHolder, set click and pass your list item of clicked row, or anything you need. You can customize method onClickViews if you need position or anyother field.
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int position) {
..
itemView.setOnClickListener(v -> onClickViews(itemView, dataList.get(position)));
..
}
and
public abstract void onClickViews(View view, T object);
Use like
public class SampleAdapter extends BaseAdapters<Item> {
#Override
public int getRowLayout() {
return R.layout.row;
}
#Override
public void onClickViews(View view, Item object) {
// row clicked
}
}
I edited your class a bit.
public abstract class BaseAdapters<T> extends RecyclerView.Adapter<BaseAdapters.MyViewHolder> {
protected List<T> dataList = new ArrayList<>();
public class MyViewHolder extends RecyclerView.ViewHolder {
MyViewHolder(View view) {
super(view);
declareViews(view, this);
}
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, int i) {
bindView(holder, i);
}
public void notifyList(List<T> filteredNames) {
dataList = filteredNames;
notifyDataSetChanged();
}
#Override
public int getItemCount() {
return dataList.size();
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int position) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(getRowLayout(), parent, false);
itemView.setOnClickListener(v -> onClickViews(itemView, dataList.get(position)));
return new MyViewHolder(itemView);
}
public abstract #LayoutRes
int getRowLayout();
public abstract MyViewHolder bindView(MyViewHolder holder, int position);
public abstract void onClickViews(View view, T object);
public abstract void declareViews(View view, MyViewHolder holder);
}
The Base Recycler Adapter will be like this
public class BaseRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final int BOTTOM_VIEW_TYPE = 3;
private List<Object> listModels;
private Context mContext;
private OnItemClickListener onClickListener = null;
public BaseRecyclerViewAdapter(Context context) {
this.mContext = context;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;
switch (viewType) {
case BOTTOM_VIEW_TYPE:
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.rv_bottomview_type, parent, false);
return new ChildViewHolder(view);
}
return null;
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
final Object model = listModels.get(position);
if (model != null && model.getId() > 0) {
((BaseViewHolder) holder).bind(model, position);
} else if (model != null) {
((TopViewViewHolder) holder).bind(model, position);
}
}
#Override
public int getItemViewType(int position) {
if (listModels.get(position).getId() > 0) {
return BASE_VIEW_TYPE;
} else {
return TOP_VIEW_TYPE;
}
}
#Override
public int getItemCount() {
return null == listModels ? 0 : listModels.size();
}
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
this.onClickListener = onItemClickListener;
}
private class ChildViewHolder extends RecyclerView.ViewHolder {
TextView tv_bottomName;
BottomViewHolder(View v) {
super(v);
tv_bottomName = v.findViewById(R.id.tv_bottomName);
}
void bind(Object object, final int position) {
tv_bottomName.setOnClickListener(view -> onClickListener.onItemClick(object, tv_bottomName, position));
}
}
}
And use a Custom interface for OnItemClickListner
public interface OnItemClickListener {
void onItemClick(Object object, View view, int position);}
And Implement the listner in activity or fragment

Recyclerview ClassCastException at onBindViewHolder

I made RecyclerView inside RecyclerView. There is ClassCastException at onBindViewHolder.
The error message here.
java.lang.ClassCastException: com.work.hany.playinseoul.main.adapter.MainRecyclerViewAdapter$TourViewHolder$TourSectionItemsAdapter$TourItemViewHolder cannot be cast to com.work.hany.playinseoul.main.adapter.MainRecyclerViewAdapter$CategoryViewHolder$CategoryItemViewHolder
at com.work.hany.playinseoul.main.adapter.MainRecyclerViewAdapter$CategoryViewHolder$CategoryHorizontalAdapter.onBindViewHolder(MainRecyclerViewAdapter.java:216)
at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:6673)
at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:6714)
But I could not catch ClassCastException at TourSectionItemsAdapter onBindViewHolder.
So, I can't check holder type at TourSectionItemsAdapter onBindViewHolder.
Only I caught ClassCastException at MainRecyclerViewAdapter onBindViewHolder.
But MainRecyclerViewAdapter onBindViewHolder holder type is same cast hodler class. Check screen shot.
My code here.
import android.support.annotation.NonNull;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
...
import java.util.ArrayList;
public class MainRecyclerViewAdapter extends BaseSectionRecyclerAdapter {
private MainRecyclerViewAdapter.ItemListener mainItemListener;
private RecyclerView.RecycledViewPool recycledViewPool;
public interface ItemListener {
void onTourClicked(AreaTour tour);
void onMoreTourClicked(AreaTour tour);
}
public MainRecyclerViewAdapter(ArrayList<Section> sections, MainRecyclerViewAdapter.ItemListener mainItemListener) {
this.mainItemListener = mainItemListener;
this.sections = sections;
}
#Override
public void onAttachedToRecyclerView(#NonNull RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
this.recycledViewPool = recyclerView.getRecycledViewPool();
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
ViewHolder viewHolder = null;
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
Section.ItemType currentItemType = getCurrentItemType(viewType);
View itemView;
switch (currentItemType) {
case CATEGORY:
itemView = inflater.inflate(R.layout.main_recycler_row_category, parent, false);
CategoryViewHolder categoryViewHolder = new CategoryViewHolder(itemView);
categoryViewHolder.categoryRecyclerView.setRecycledViewPool(recycledViewPool);
viewHolder = categoryViewHolder;
break;
case MAIN_TOUR:
itemView = inflater.inflate(R.layout.main_recycler_row_tour, parent, false);
TourViewHolder tourViewHolder = new TourViewHolder(itemView);
tourViewHolder.tourSectionItemsRecyclerView.setRecycledViewPool(recycledViewPool);
viewHolder = tourViewHolder;
break;
}
return viewHolder;
}
private int categoryRecyclerViewScrollPosition = 0;
#Override
public void onViewRecycled(#NonNull ViewHolder holder) {
super.onViewRecycled(holder);
if (Section.ItemType.CATEGORY.getCode() == holder.getItemViewType()) {
CategoryViewHolder categoryViewHolder = CategoryViewHolder.class.cast(holder);
RecyclerView categoryRecyclerView = categoryViewHolder.categoryRecyclerView;
categoryRecyclerViewScrollPosition = categoryRecyclerView.computeHorizontalScrollOffset();
}
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, final int position) {
super.onBindViewHolder(holder, position);
try {
if (Section.ItemType.CATEGORY.getCode() == holder.getItemViewType()) {
CategoryViewHolder categoryViewHolder = CategoryViewHolder.class.cast(holder);
categoryViewHolder.categoryRecyclerView.scrollBy(categoryRecyclerViewScrollPosition, 0);
}
} catch (ClassCastException e) {
Log.e("HANY_TAG", "MainRecyclerViewAdapter.onBindViewHolder" + e.getClass().getSimpleName());
// But.... holder type is CategoryViewHolder.
}
}
class TourViewHolder extends ViewHolder<ArrayList<AreaTour>> {
private ImageView tourSectionImageView;
private TextView tourSectionTitleTextView;
private RecyclerView tourSectionItemsRecyclerView;
public TourViewHolder(View itemView) {
super(itemView);
tourSectionImageView = itemView.findViewById(R.id.tour_content_image_view);
tourSectionTitleTextView = itemView.findViewById(R.id.tour_section_title_text_view);
tourSectionItemsRecyclerView = itemView.findViewById(R.id.tour_section_item_recycler_view);
}
#Override
public void bind(final ArrayList<AreaTour> areaTour) {
String sectionTitle = ConverterUtils.convertContentType(areaTour.get(0).getContentTypeId());
tourSectionTitleTextView.setText(sectionTitle);
ImageLoderUtils.lodeURI(tourSectionImageView, areaTour.get(areaTour.size() - 1).getLargeImage());
TourSectionItemsAdapter tourSectionItemsAdapter = new TourSectionItemsAdapter(areaTour);
tourSectionItemsRecyclerView.setLayoutManager(new GridLayoutManager(itemView.getContext(), 2));
tourSectionItemsRecyclerView.setAdapter(tourSectionItemsAdapter);
}
private class TourSectionItemsAdapter extends RecyclerView.Adapter<TourSectionItemsAdapter.TourItemViewHolder> {
private ArrayList<AreaTour> areaTourList;
private final int SECTION_IMAGE_COUNT = 1;
public TourSectionItemsAdapter(ArrayList<AreaTour> areaTourList) {
this.areaTourList = areaTourList;
}
#NonNull
#Override
public TourItemViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
return new TourItemViewHolder(inflater.inflate(R.layout.main_recycler_row_tour_item, null));
}
#Override
public void onBindViewHolder(#NonNull TourItemViewHolder holder, int position) {
holder.bind(areaTourList.get(position));
}
#Override
public int getItemCount() {
return areaTourList.size() - SECTION_IMAGE_COUNT;
}
class TourItemViewHolder extends ViewHolder<AreaTour> {
private ImageView tourImageView;
private TextView tourTextView;
private TextView tourAddrTextView;
private TextView tourContentShowCountTextView;
public TourItemViewHolder(View itemView) {
super(itemView);
tourImageView = itemView.findViewById(R.id.tour_content_image_view);
tourTextView = itemView.findViewById(R.id.tour_title_text_view);
tourContentShowCountTextView = itemView.findViewById(R.id.tour_show_text_view);
tourAddrTextView = itemView.findViewById(R.id.tour_content_addr_text_view);
}
public void bind(final AreaTour tour) {
ImageLoderUtils.lodeURI(tourImageView, tour.getLargeImage());
tourTextView.setText(tour.getContentTitle());
String countStr = new StringBuilder().append("์กฐํšŒ์ˆ˜ ").append(tour.getReadCount()).toString();
tourContentShowCountTextView.setText(countStr);
tourAddrTextView.setText(tour.getAreaAddress());
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mainItemListener.onTourClicked(tour);
}
});
}
}
}
}
class CategoryViewHolder extends ViewHolder<ArrayList<ContentType>> {
private RecyclerView categoryRecyclerView;
// private TextView categoryTitleView;
public CategoryViewHolder(View itemView) {
super(itemView);
// categoryTitleView = itemView.findViewById(R.id.main_tour_title_text_view);
categoryRecyclerView = itemView.findViewById(R.id.main_tour_recycler_view);
categoryRecyclerView.setHasFixedSize(true);
}
#Override
public void bind(ArrayList<ContentType> data) {
CategoryHorizontalAdapter categoryHorizontalAdapter = new CategoryHorizontalAdapter(data);
LinearLayoutManager layoutManager = new LinearLayoutManager(itemView.getContext(), LinearLayoutManager.HORIZONTAL, false);
categoryRecyclerView.setLayoutManager(layoutManager);
categoryRecyclerView.setAdapter(categoryHorizontalAdapter);
}
private class CategoryHorizontalAdapter extends RecyclerView.Adapter<CategoryItemViewHolder> {
private ArrayList<ContentType> categoryTypes;
public CategoryHorizontalAdapter(ArrayList<ContentType> categoryTypes) {
this.categoryTypes = categoryTypes;
}
#NonNull
#Override
public CategoryItemViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
return new CategoryItemViewHolder(inflater.inflate(R.layout.main_recycler_row_category_item, null));
}
#Override
public void onBindViewHolder(#NonNull CategoryItemViewHolder holder, int position) {
holder.bind(categoryTypes.get(position));
}
#Override
public int getItemCount() {
return categoryTypes.size();
}
}
private class CategoryItemViewHolder extends ViewHolder<ContentType> {
private TextView categoryTitleTextView;
public CategoryItemViewHolder(View itemView) {
super(itemView);
categoryTitleTextView = itemView.findViewById(R.id.category_item_title_text_view);
}
public void bind(ContentType type) {
categoryTitleTextView.setText(type.getName());
}
}
}
}
BaseSectionRecyclerAdapter code.
abstract public class BaseSectionRecyclerAdapter extends RecyclerView.Adapter<ViewHolder> {
protected ArrayList<Section> sections;
#Override
public int getItemCount() {
return sections.size();
}
public <T>void addSection(Section.ItemType type, T data){
sections.add(new Section(type,data));
notifyDataSetChanged();
}
public <T>void updateSection(Section.ItemType type, T data) {
for(int position = 0, end = sections.size(); position < end; position++ ){
if (sections.get(position).getType().equals(type)) {
sections.get(position).setData(data);
notifyItemChanged(position);
}
}
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
holder.bind((sections.get(position).getData()));
}
#Override
public int getItemViewType(int position) {
return sections.get(position).getType().getCode();
}
protected Section.ItemType getCurrentItemType(int position) {
for (Section.ItemType itemType : Section.ItemType.values()) {
if (itemType.getCode() == position) return itemType;
}
return NOTHING;
}
}
ViewHolder code.
public abstract class ViewHolder<T> extends RecyclerView.ViewHolder {
public ViewHolder(View itemView) {
super(itemView);
}
abstract public void bind(T data);
}
I don't understand what I did wrong...
How to solve it?
I just faced that issue that I commented above. I was using the switch case in onBindViewHolderfunction and I haven't written the default case, When I added the default case then the error is fixed.
In your case, you are using an if condition in onBindViewHolder(), just try to add an else to the function and try.
hope you fixed the issue if it is not, then try this one. Thank you.
maybe its late but for the feature readers just define viewPool like this
private val viewPool = RecyclerView.RecycledViewPool()

Recycle view inside cardview aren't visible

I tried to insert recycleview inside cardview, but it not create it. I think it's problem with adapter, because this type of card created, but not fill recycle view.Now its look like this
There's my recycleview adapter code
public class SubItemsAdapter extends RecyclerView.Adapter<SubItemsAdapter.SubtasksViewHolder>{
private List<Subtask> subtasks;
public SubItemsAdapter(List<Subtask> subtasks){
this.subtasks = subtasks;
}
public class SubtasksViewHolder extends RecyclerView.ViewHolder{
TextView titleTextView;
CheckBox doneCheckBox;
public SubtasksViewHolder(View itemView) {
super(itemView);
titleTextView = (TextView)itemView.findViewById(R.id.subtaskTitle);
doneCheckBox = (CheckBox)itemView.findViewById(R.id.subtaskCheckbox);
}
}
#Override
public SubtasksViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.subtasks_listitem,parent,false);
return new SubtasksViewHolder(v);
}
#Override
public void onBindViewHolder(SubtasksViewHolder holder, int position) {
holder.titleTextView.setText(subtasks.get(position).getText());
holder.doneCheckBox.setChecked(subtasks.get(position).getDone());
}
#Override
public int getItemCount() {
return subtasks.size();
}} `
And my cardview code:
public class TasklistAdapter extends RecyclerView.Adapter<TasklistAdapter.ViewHolder> {
ArrayList<TodoItem> todoItems;
int[] dataTypes;
private static final int SIMPLETODOITEM = 0;
private static final int EXTENDTODOITEM = 1;
Context context;
public TasklistAdapter(ArrayList<TodoItem> todoItems, int[] dataTypes, Context context)
{
this.todoItems = todoItems;
this.dataTypes = dataTypes;
this.context = context;
}
public class SimpleViewHolder extends ViewHolder{
TextView titleTextView;
TextView desciptionTextView;
CheckBox doneCheckBox;
public SimpleViewHolder(View v) {
super(v);
titleTextView = (TextView)v.findViewById(R.id.simpleitem_title_textbox);
desciptionTextView =(TextView)v.findViewById(R.id.simpleitem_description_textbox);
doneCheckBox = (CheckBox)v.findViewById(R.id.simpleitem_checkbox);
}
}
public class ExtendViewHolder extends ViewHolder{
TextView titleTextView;
TextView descTextView;
RecyclerView subtasksListView;
SubItemsAdapter adapter;
RecyclerView.LayoutManager manager;
public ExtendViewHolder(View v) {
super(v);
titleTextView = (TextView)v.findViewById(R.id.extended_card_title);
descTextView = (TextView)v.findViewById(R.id.extended_card_description);
subtasksListView = (RecyclerView)v.findViewById(R.id.subtasks_listview);
manager = new LinearLayoutManager(v.getContext());
}
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v;
switch (viewType)
{
case EXTENDTODOITEM:
v = LayoutInflater.from(parent.getContext()).inflate(R.layout.extendedtodoitem_card, parent, false);
return new ExtendViewHolder(v);
default:
v = LayoutInflater.from(parent.getContext()).inflate(R.layout.simpletodoitem_card,parent,false);
return new SimpleViewHolder(v);
}
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
switch (holder.getItemViewType()){
case EXTENDTODOITEM:
ExtendViewHolder extViewHold = (ExtendViewHolder)holder;
extViewHold.adapter = new SubItemsAdapter(todoItems.get(position).getSubtasks());
extViewHold.titleTextView.setText(todoItems.get(position).getText());
extViewHold.descTextView.setText(todoItems.get(position).getDescription());
extViewHold.subtasksListView.setLayoutManager(extViewHold.manager);
extViewHold.subtasksListView.setAdapter(extViewHold.adapter);
break;
default:
SimpleViewHolder simViewHold = (SimpleViewHolder)holder;
simViewHold.desciptionTextView.setText(todoItems.get(position).getDescription());
simViewHold.titleTextView.setText(todoItems.get(position).getText());
break;
}
}
#Override
public int getItemCount() {
return todoItems.size();
}
#Override
public int getItemViewType(int position) {
return dataTypes[position];
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public ViewHolder(View v) {
super(v);
}
}
}`
in your TasklistAdapter, static class ViewHolder extending RecyclerView.ViewHolder seems useless! and you are trying to inflate and bind data with two heterogeneous layouts with their own viewholder sub-classes! My solution would be to change this :
public class TasklistAdapter extends RecyclerView.Adapter<TasklistAdapter.ViewHolder>
to
public class TasklistAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>

Categories

Resources