Create Base Adapters For All Recycler View Adapters
Asked Answered
M

6

9
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.

Marquismarquisate answered 5/10, 2018 at 10:55 Comment(6)
every item selection mean on full row or some item component click?Autolysis
every item selection or setting value on particular row item.Marquismarquisate
You can set clicks in overrided bindView method in child class, is there any issue?Autolysis
See google.co.in/…Autolysis
I think I did not get issue, but you will get many ideas by seeing these generic adapters on githubAutolysis
you should try this github.com/manojbhadane/GenericAdapterTrantrance
S
9
    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();
            }
        });
    }




}
Schiller answered 11/1, 2019 at 10:3 Comment(2)
good update this method @Override public int getItemCount() { return dataList == null ? 0 : dataList.size(); }Henrique
This adapter has issue of recycling viewholder, so i changed a bit see my below answer .. thanks for the base structure @rupaliAudsley
D
2

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;
    }

}
Dinerman answered 5/10, 2018 at 11:0 Comment(5)
public class absadapter extends BaseAdapters { } I want to get access of holder in absadapter.Marquismarquisate
if you want to handle on click events you can do that in bindviewholder() methodDinerman
BindView is already defined in parent class , i want to access it in child class.Marquismarquisate
You can try using ButterKnife Library refer this link:github.com/JakeWharton/butterknifeDinerman
see this answer if it helps #26245639Wandawander
A
2

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());
            }
        });
    }
}
Audsley answered 27/5, 2020 at 15:56 Comment(1)
there is a catch, here we performing findViewById again and again on each binding.Brittbritta
B
1

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.
    }
    //...
}
Bengt answered 14/10, 2018 at 18:0 Comment(0)
A
1

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);
}
Autolysis answered 15/10, 2018 at 10:31 Comment(0)
H
0

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

Hanford answered 15/10, 2018 at 12:9 Comment(2)
I don't want to create holder in child class. I have created generic holder in base class which will contain reference of every layout set to adapter .Marquismarquisate
ok thats fine, then u can perform the onclick listner using interface in each child classHanford

© 2022 - 2024 — McMap. All rights reserved.