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
Related
i have a list and i showed that in recycler view
some of items have blue background and other items have gray background
i want to edit selected item background (
The selected item means the item that has been clicked )
this is my adapter class
public class UserAdapter extends RecyclerView.Adapter<UserAdapter.UserViewHolder> {
private Context context;
private List<User> users = new ArrayList<>();
public UserAdapter(List<User> users, Context context) {
this.users = users;
this.context = context;
}
#NonNull
#Override
public UserViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return new UserViewHolder(LayoutInflater.from(context).inflate(R.layout.item_user, parent, false));
}
#Override
public void onBindViewHolder(#NonNull UserViewHolder holder, int position) {
holder.binUser(users.get(position), position);
}
#Override
public int getItemCount() {
return users.size();
}
public class UserViewHolder extends RecyclerView.ViewHolder {
private TextView tvName;
private RelativeLayout rlItemUser;
public UserViewHolder(#NonNull View itemView) {
super(itemView);
tvName = itemView.findViewById(R.id.tv_itemUser_name);
rlItemUser = itemView.findViewById(R.id.itemUser_rootView);
}
public void binUser(User user, int position){
tvName.setText(user.getName());
if (user.getMode().equals("passenger")){
rlItemUser.setBackgroundColor(context.getResources().getColor(R.color.colorGray));
tvName.setTextColor(context.getResources().getColor(R.color.colorPrimary));
} else if (user.getMode().equals("driver")){
rlItemUser.setBackgroundColor(context.getResources().getColor(R.color.colorPrimary));
tvName.setTextColor(context.getResources().getColor(R.color.colorGray));
}
}
}
in the bindUser method:
rlItemUser.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
rtlItemUser.setBackgroundColor(context.getResources().getColor(your color);
adapter.notifyItemChanged(position);
}
});
I'll use RecyclerView And I've more than 10 items in the list And I Have to change a text color and background layout on a single click of the item and else all the item color not change. Please suggest me the right way to solve this issue. I'll try to change the color in BindViewHolder, ViewHolder and Adapter click item but I'm Successful to change the color but unsuccessful to change the color back.
public class LoadVehicleTypeAdapter extends RecyclerView.Adapter<LoadVehicleTypeAdapter.CarTypesHolder> {
private List<TaxiTypeResponse.Message> CarTypesModelsList;
private Context mContext;
VehicleTypeView vehicleTypeView;
setOnitemclick listener;
private SparseBooleanArray selectedItems = new SparseBooleanArray();
int I=-1;
public class CarTypesHolder extends RecyclerView.ViewHolder {
public CustomTextView mCarType;
public CircleImageView mCarTypeImage;
LinearLayout llRoot;
CardView cardView;
private SparseBooleanArray selectedItems = new SparseBooleanArray();
setOnitemclick listener;
public CarTypesHolder(final View view) {
super(view);
mCarType = (CustomTextView) view.findViewById(R.id.frag_cartypes_inflated_name);
mCarTypeImage = (CircleImageView) view.findViewById(R.id.frag_cartype_inflated_frameImage);
llRoot = (LinearLayout)view.findViewById(R.id.root1);
cardView=(CardView) view.findViewById(R.id.cardf);
}
public void setOnItemClickListner(setOnitemclick listener12) {
listener=listener12;
}
}
public void setOnItemClickListner(setOnitemclick listener12) {
listener=listener12;
}
public LoadVehicleTypeAdapter(Context context, List<TaxiTypeResponse.Message> CarTypesModelsList, VehicleTypeView vehicleTypeView) {
this.CarTypesModelsList = CarTypesModelsList;
mContext = context;
this.vehicleTypeView = vehicleTypeView;
}
#Override
public CarTypesHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView;
itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.frag_cartype_inflated_view, parent, false);
return new CarTypesHolder(itemView);
}
#SuppressLint("ResourceType")
#Override
public void onBindViewHolder(final CarTypesHolder holder, final int position) {
TaxiTypeResponse.Message carTypesModel = CarTypesModelsList.get(position);
I=CarTypesModelsList.get(position).getID();
holder.mCarType.setText(carTypesModel.getName());
holder.mCarTypeImage.setBackgroundResource(R.drawable.wait);
int color = Color.parseColor(PreferenceHandler.readString(mContext,PreferenceHandler.SECONDRY_COLOR,"#006fb6"));
holder.llRoot.setSelected(selectedItems.get(position, false));
holder.mCarType.setTextColor(color);
holder.setOnItemClickListner(listener);
holder. llRoot.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
I=position;
if (I==position)
{
holder.llRoot.setBackgroundColor(Color.parseColor("#999999"));
holder.mCarType.setTextColor(Color.parseColor("#ffffff"));
}
else
{
holder.llRoot.setBackgroundColor(Color.parseColor("#f3f3f3"));
holder.mCarType.setTextColor(Color.parseColor("#00000"));
}
}
});
Picasso.with(mContext).load(carTypesModel.getImagePath()).into(holder.mCarTypeImage);
}
#Override
public long getItemId(int position) {
return CarTypesModelsList.get(position).getID();
}
#Override
public int getItemCount() {
return CarTypesModelsList.size();
}
public void setSelection(LinearLayout imageView,CustomTextView textView,boolean value,int position){
if(value){
imageView.setBackgroundColor(Color.parseColor("#999999"));
textView.setTextColor(Color.parseColor("#FFFFFF"));
}else{
System.out.println("11111111111111111000000111111111111");
imageView.setBackgroundColor(Color.parseColor("#f3f3f3"));
textView.setTextColor(Color.parseColor("#2196F3"));
}
}
public interface setOnitemclick{
void ImageClick(int position, String Name,String Description,int id);
void ImageClickfade(int position, String Name,String Description,int id);
}
#Override
public int getItemViewType(int position) {
return position;
}
}
You can try this,
You'll use to update gradle
maven { url "https://maven.google.com" }
and update the code
public class LoadVehicleTypeAdapter extends RecyclerView.Adapter<LoadVehicleTypeAdapter.CarTypesHolder> {
private List<TaxiTypeResponse.Message> CarTypesModelsList;
private Context mContext;
VehicleTypeView vehicleTypeView;
int I=-1;
public class CarTypesHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public CustomTextView mCarType;
public CircleImageView mCarTypeImage;
LinearLayout llRoot;
CardView cardView;
setOnitemclick listener;
public void setOnItemClickListner(setOnitemclick listener)
{
this.listener=listener;
}
public CarTypesHolder(View view) {
super(view);
mCarType = (CustomTextView) view.findViewById(R.id.frag_cartypes_inflated_name);
mCarTypeImage = (CircleImageView) view.findViewById(R.id.frag_cartype_inflated_frameImage);
llRoot = (LinearLayout)view.findViewById(R.id.root1);
cardView=(CardView) view.findViewById(R.id.cardf);
view.setOnClickListener(this);
}
#Override
public void onClick(View v) {
listener.ImageClick(v,getAdapterPosition());
}
}
public LoadVehicleTypeAdapter(Context context, List<TaxiTypeResponse.Message> CarTypesModelsList, VehicleTypeView vehicleTypeView) {
this.CarTypesModelsList = CarTypesModelsList;
mContext = context;
this.vehicleTypeView = vehicleTypeView;
}
#Override
public CarTypesHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.frag_cartype_inflated_view, parent, false);
return new CarTypesHolder(itemView);
}
#SuppressLint("ResourceType")
#Override
public void onBindViewHolder( final CarTypesHolder holder, int position) {
TaxiTypeResponse.Message carTypesModel = CarTypesModelsList.get(position);
holder.mCarType.setText(carTypesModel.getName());
holder.mCarTypeImage.setBackgroundResource(R.drawable.wait);
int color = Color.parseColor(PreferenceHandler.readString(mContext,PreferenceHandler.SECONDRY_COLOR,"#006fb6"));
holder.mCarType.setTextColor(color);
holder.setOnItemClickListner(new setOnitemclick() {
#Override
public void ImageClick(View v,int position1) {
I=position1;
notifyDataSetChanged();
}
});
if (I==position)
{
System.out.println("11100011111....");
holder.llRoot.setBackgroundColor(Color.parseColor("#999999"));
holder.mCarType.setTextColor(Color.parseColor("#ffffff"));
}
else
{
System.out.println("11100011111----");
holder.llRoot.setBackgroundColor(Color.parseColor("#f3f3f3"));
holder.mCarType.setTextColor(Color.parseColor("#2196F3"));
}
Picasso.with(mContext).load(carTypesModel.getImagePath()).into(holder.mCarTypeImage);
}
#Override
public long getItemId(int position) {
return CarTypesModelsList.get(position).getID();
}
#Override
public int getItemCount() {
return CarTypesModelsList.size();
}
public void setSelection(LinearLayout imageView,CustomTextView textView,boolean value,int position){
if(value){
imageView.setBackgroundColor(Color.parseColor("#999999"));
textView.setTextColor(Color.parseColor("#FFFFFF"));
}else{
System.out.println("11111111111111111000000111111111111");
imageView.setBackgroundColor(Color.parseColor("#f3f3f3"));
textView.setTextColor(Color.parseColor("#2196F3"));
}
}
public interface setOnitemclick{
void ImageClick(View view,int position);
}
#Override
public int getItemViewType(int position) {
return position;
}
}
Replace your click like below
public void onBindViewHolder(final CarTypesHolder holder, final int position) {
TaxiTypeResponse.Message carTypesModel = CarTypesModelsList.get(position);
I=CarTypesModelsList.get(position).getID();
holder.mCarType.setText(carTypesModel.getName());
holder.mCarTypeImage.setBackgroundResource(R.drawable.wait);
int color = Color.parseColor(PreferenceHandler.readString(mContext,PreferenceHandler.SECONDRY_COLOR,"#006fb6"));
holder.llRoot.setSelected(selectedItems.get(position, false));
holder.mCarType.setTextColor(color);
holder.setOnItemClickListner(listener);
holder. llRoot.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
I=position;
holder.llRoot.setBackgroundColor(Color.parseColor("#999999"));
holder.mCarType.setTextColor(Color.parseColor("#ffffff"));
notifyDataSetChanged()
}
});
if (I==position)
{
holder.llRoot.setBackgroundColor(Color.parseColor("#999999"));
holder.mCarType.setTextColor(Color.parseColor("#ffffff"));
}
else
{
holder.llRoot.setBackgroundColor(Color.parseColor("#f3f3f3"));
holder.mCarType.setTextColor(Color.parseColor("#00000"));
}
Picasso.with(mContext).load(carTypesModel.getImagePath()).into(holder.mCarTypeImage);
}
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
I have a recycler view that displays a list of items.
Within each item, there is a title and another RecyclerView that display a list of items.
I want to access the click events of the items of the child RecyclerView.
Screenshot of the layout:
The parent RecyclerView:
public class DetailsGroupAdapter extends RecyclerView.Adapter<DetailsGroupAdapter.ViewHolder>{
private static OnItemClickListener listener;
private Context context;
private int lastPosition = -1;
RecyclerView mRecyclerView;
public interface OnItemClickListener {
void onItemClick(View itemView, int position);
void onGroupItemLongClick(View itemView, int groupPosition, int itemPosition);
void onGroupItemClick(View itemView, int groupPosition, int itemPosition);
}
public void setOnItemClickListener(OnItemClickListener listener) {
DetailsGroupAdapter.listener = listener;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView tvTitle;
public CardView cvContainer;
public RecyclerView rvItems;
public ViewHolder(final View itemView)
{
super(itemView);
tvTitle = itemView.findViewById(R.id.group_title);
cvContainer = itemView.findViewById(R.id.container);
rvItems = itemView.findViewById(R.id.rv_group_items);
//click listener setup
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Triggers click upwards to the adapter on click
if (listener != null)
listener.onItemClick(itemView, getLayoutPosition());
}
});
}
public void clearAnimation()
{
cvContainer.clearAnimation();
}
}
private List<DetailsGroup> itemList;
public DetailsGroupAdapter(List<DetailsGroup> itemList)
{
this.itemList = itemList;
}
#Override
public DetailsGroupAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
View layoutView = inflater.inflate(R.layout.item_details_group, parent, false);
mRecyclerView = (RecyclerView) parent;
return new ViewHolder(layoutView);
}
#Override
public void onBindViewHolder(final DetailsGroupAdapter.ViewHolder viewHolder, int groupPosition){
final DetailsGroup detailsGroup = itemList.get(groupPosition);
if(detailsGroup.Title != null){
viewHolder.tvTitle.setText(detailsGroup.Title);
} else {
viewHolder.tvTitle.setVisibility(View.GONE);
}
final DetailsGroupItemsAdapter detailsGroupAdapter = new DetailsGroupItemsAdapter(detailsGroup.itemsList, groupPosition);
detailsGroupAdapter.setOnItemClickListener(new DetailsGroupItemsAdapter.OnItemClickListener() {
#Override
public void onItemClick(View itemView, int position) {
if (listener != null){
listener.onGroupItemClick(itemView, (int) itemView.getTag(), position);
}
}
#Override
public void onLongClick(View itemView, int position) {
if (listener != null){
listener.onGroupItemLongClick(itemView, (int) itemView.getTag(), position);
}
}
});
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context) {};
viewHolder.rvItems.setLayoutManager(linearLayoutManager);
viewHolder.rvItems.setAdapter(detailsGroupAdapter);
}
private void setAnimation(View viewToAnimate, int position)
{
if (position > lastPosition) {
AlphaAnimation anim = new AlphaAnimation(0.0f, 1.0f);
anim.setDuration(1000);
viewToAnimate.startAnimation(anim);
lastPosition = position;
}
}
#Override
public void onViewDetachedFromWindow(final ViewHolder holder)
{
((ViewHolder)holder).cvContainer.clearAnimation();
}
#Override
public long getItemId(int position) {
return itemList.get(position).hashCode();
}
#Override
public int getItemCount()
{
return itemList.size();
}
public void clear() {
itemList.clear();
notifyDataSetChanged();
}
public void addAll(List<DetailsGroup> list){
itemList.addAll(list);
notifyDataSetChanged();
}
}
The child RecyclerView:
public class DetailsGroupItemsAdapter extends RecyclerView.Adapter<DetailsGroupItemsAdapter.ViewHolder>{
private static OnItemClickListener listener;
private Context context;
private int lastPosition = -1;
private int groupPosition;
public interface OnItemClickListener {
void onItemClick(View itemView, int position);
void onLongClick(View itemView,int position);
}
public void setOnItemClickListener(OnItemClickListener listener) {
DetailsGroupItemsAdapter.listener = listener;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView tvTitle;
public TextView tvSubTitle;
public ImageView ivThumbnail;
public LinearLayout llContainer;
public ViewHolder(final View itemView)
{
super(itemView);
ivThumbnail = itemView.findViewById(R.id.thumbnail);
tvTitle = itemView.findViewById(R.id.title);
tvSubTitle = itemView.findViewById(R.id.subtitle);
llContainer = itemView.findViewById(R.id.container);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (listener != null)
listener.onItemClick(itemView, getLayoutPosition());
}
});
itemView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
if (listener != null)
listener.onLongClick(itemView, getLayoutPosition());
return false;
}
});
}
public void clearAnimation()
{
llContainer.clearAnimation();
}
}
private List<ItemDetail> itemList;
public DetailsGroupItemsAdapter(List<ItemDetail> itemList, int groupPosition)
{
this.itemList = itemList;
this.groupPosition = groupPosition;
}
#Override
public DetailsGroupItemsAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
View layoutView = inflater.inflate(R.layout.item_details, parent, false);
return new ViewHolder(layoutView);
}
#Override
public void onBindViewHolder(DetailsGroupItemsAdapter.ViewHolder viewHolder, int position){
viewHolder.itemView.setTag(groupPosition);
ItemDetail itemDetail = itemList.get(position);
if(itemDetail.Title != null){
viewHolder.tvTitle.setText(itemDetail.Title);
} else {
viewHolder.tvTitle.setVisibility(View.GONE);
}
if(itemDetail.Sub_Title != null){
viewHolder.tvSubTitle.setText(itemDetail.Sub_Title);
} else {
viewHolder.tvSubTitle.setVisibility(View.GONE);
}
if(itemDetail.Thumbnail_Enabled){
PicManipulationUtility.SetGenericPictureFromThumbnailType(viewHolder.ivThumbnail, itemDetail.Thumbnail_Type, itemDetail.Thumbnail);
} else {
viewHolder.ivThumbnail.setVisibility(View.GONE);
}
setAnimation(viewHolder.llContainer, position);
}
private void setAnimation(View viewToAnimate, int position)
{
if (position > lastPosition) {
AlphaAnimation anim = new AlphaAnimation(0.0f, 1.0f);
anim.setDuration(1000);
viewToAnimate.startAnimation(anim);
lastPosition = position;
}
}
#Override
public void onViewDetachedFromWindow(final ViewHolder holder)
{
((ViewHolder)holder).llContainer.clearAnimation();
}
#Override
public long getItemId(int position) {
return itemList.get(position).hashCode();
}
#Override
public int getItemCount()
{
return itemList.size();
}
public void clear() {
itemList.clear();
notifyDataSetChanged();
}
public void addAll(List<ItemDetail> list){
itemList.addAll(list);
notifyDataSetChanged();
}
}
The classes used:
ItemDetail and DetailsGroup are POJOs to convert JSON into objects.
What I managed to do so far to temporarily fix the problem is:
In onBindViewHolder of parent RecyclerView, I grabbed the group position.
Then I passed the group position of the parent down to the child
adapter initializer in (DetailsGroupItemsAdapter)
Finally, in the child onBindViewHolder I set the tag to be the parent
group position(viewHolder.itemView.setTag(groupPosition);)
So in the click event of the child, I can say:
listener.onGroupItemClick(itemView, (int) itemView.getTag(), position);
Thus having both the group position and the child position in the bubbled event in my Activity or Fragment.
But I know for sure that the passed group position can change for any reason such as updating group items or removing items.
I want to know if there is a more robust solution to implement the click events of nested items in this case.
I used this https://gist.github.com/riyazMuhammad/1c7b1f9fa3065aa5a46f, especially
CustomItemClickListener.java :
public interface CustomItemClickListener {
public void onItemClick(View v, int position);
}
(Parent) RecyclerView modifications :
public class ItemsListAdapter extends RecyclerView.Adapter<ItemsListAdapter.ViewHolder> {
ArrayList<ItemListSingleItem> data;
Context mContext;
CustomItemClickListener listener;
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View mView = LayoutInflater.from(parent.getContext()).inflate(R.layout.items_list_single_item, parent, false);
final ViewHolder mViewHolder = new ViewHolder(mView);
mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.onItemClick(v, mViewHolder.getPosition());
}
});
return mViewHolder;
}
//[... the other "classical" parts of your code...]
}
Alone, it allowed me to have separate click events on child and parent
With some modifications, it led me to something similar to your "fix", I think, but maybe it'll give you some clues : I am giving the parent position and the parent listener to the child when constructing it, and then a click on the child produces the same behavior as a click on the parent
Child RecyclerView constructor :
public AppsAdapter(ArrayList<PackageInformation.InfoObject> dataSet, CustomOnItemClickListener customItemClickListener, int parentPos) {
appsDataSet = dataSet;
onItemClickListener = customItemClickListener;
parentPosition = parentPos;
}
Child RecyclerView onCreateViewHolder :
#Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
// Create a new view.
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_app, viewGroup, false);
// Create the ViewHolder to return
final AppsAdapter.ViewHolder mViewHolder = new AppsAdapter.ViewHolder(v);
// Add the Listener
v.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) { onItemClickListener.onItemClick(v, parentPosition); }
});
return mViewHolder;
I am new to android, currently I am working on recyclerView implementations. The issue is I want to delete an item after onCreateContextMenu has been called. I am having some problems getting the right reference to my delete option.
Holder Class
public class UploadDrugsHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnCreateContextMenuListener, MenuItem.OnMenuItemClickListener {
//OUR VIEWS
UploadDrugsAdapter uploadDrugsAdapter;
TextView drugName;
ImageView drugImage;
ItemClickListener itemClickListener;
ArrayList<UploadedDrugs> drugs;
public UploadDrugsHolder(View itemView) {
super(itemView);
this.drugName= (TextView) itemView.findViewById(R.id.shopName);
this.drugImage= (ImageView) itemView.findViewById(R.id.model_menu);
itemView.setOnClickListener(this);
itemView.setOnCreateContextMenuListener(this);
}
public void setItemClickListener(ItemClickListener itemClickListener) {
this.itemClickListener=itemClickListener;
}
#Override
public void onClick(View v) {
this.itemClickListener.onItemClick(v,getLayoutPosition());
}
#Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
MenuItem myActionItem = menu.add("delete");
myActionItem.setOnMenuItemClickListener(this);
}
#Override
public boolean onMenuItemClick(MenuItem item) {
// what do i need to write here?
Toast.makeText(itemView.getContext(), "Drug deleted successfully", Toast.LENGTH_SHORT).show();
return false;
}
}
I always put adapter and holder in the same file.
You should do like this:
public class UploadedDrugsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<UploadedDrugs> dataList = new ArrayList<>();
private OnClickUploadedDrugs event;
public UploadedDrugsAdapter (List<UploadedDrugs> dataList, OnClickUploadedDrugs event) {
this.dataList = dataList;
this.event = event;
}
public interface OnClickUploadedDrugs{
void onClickUploadedDrugs(UploadedDrugs uploadedDrugs);
}
public void changeDataSet(List<UploadedDrugs> dataSet){
dataList = dataSet;
notifyDataSetChanged();
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.your_xml_file, parent, false);
return new ViewHolderUploadedDrugs(view);
}
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
try {
final UploadedDrugs model = dataList.get(position);
final ViewHolderUploadedDrugs vh = (ViewHolderUploadedDrugs) holder;
// configure view values
//Event
vh.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(event != null){
event.onClickUploadedDrugs(model);
}
}
});
}catch (Exception e){
Log.e(getClass().getSimpleName(), "Erro ao exibir informaçeõs", e);
}
}
#Override
public int getItemCount() {
return (null != dataList ? dataList.size() : 0);
}
static class ViewHolderUploadedDrugs extends RecyclerView.ViewHolder {
TextView drugName;
ImageView drugImage;
ViewHolderUploadedDrugs(View itemView) {
super(itemView);
this.drugName= (TextView) itemView.findViewById(R.id.shopName);
this.drugImage= (ImageView) itemView.findViewById(R.id.model_menu);
}
}
public List<UploadedDrugs> getDataList() {
return dataList;
}
public void setEvent(OnClickUploadedDrugs event) {
this.event = event;
}
}
Something like:
drugs.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, drugs.size());