Everything works well and my onClick in my recyclerView is working in getting the positions of my items, but what my design calls for is to be able to click an item of the recyclerView and open up a new activity (as a popover or pop up). I can achieve this but my problems comes with the information I need to display on the popover. The information comes like this inside the activity (inside a Firebase value call)
attributeList.removeAll(attributeList);
for (DataSnapshot child : dataSnapshot.child("Attribute").getChildren()){
Attribute attribute = child.getValue(Attribute.class);
attribute_list newAttributeList = new attribute_list( attribute.Name + ": " + attribute.Value);
attributeList.add(newAttributeList);
}
attributeAdapter = new attribute_list_adapter(attributeList, getContext());
recyclerAttribute.setAdapter(attributeAdapter);
This works perfectly for displaying the information, but there's more then just a "value" and a "name" associated with the click.
Basically when I select an item, I need to get the position of the item clicked (which I have) and compare it to the position inside attributeList so I can call a Firebase call (or pass the data somehow) to the popover to display values from the "Attribute" class (such as Name, Value, Description, and another list (recyclerView).
My recyclerView:
public class attribute_list_adapter extends RecyclerView.Adapter<attribute_list_adapter.ViewHolder> {
private List<attribute_list> listItems;
private Context context;
public attribute_list_adapter(List<attribute_list> listItems, Context context) {
this.listItems = listItems;
this.context = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.attribute_list, parent, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
attribute_list listItem = listItems.get(position);
holder.txtTitle.setText(listItem.getTxtTitle());
}
#Override
public int getItemCount() {
return listItems.size();
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TextView txtTitle;
public ViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
txtTitle = (TextView) itemView.findViewById(R.id.txtTitle);
}
#Override
public void onClick(View v) {
}
}
}
This is example:
public class attribute_list_adapter extends RecyclerView.Adapter<attribute_list_adapter.ViewHolder> {
private List<attribute_list> listItems;
private Context context;
public attribute_list_adapter(List<attribute_list> listItems, Context context) {
this.listItems = listItems;
this.context = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.attribute_list, parent, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.itemView.setOnClickListener(new View.onClickListener() {
#Override
public void onClick(View v) {
onItemClickListener.onItemClick(position);
}
});
}
#Override
public int getItemCount() {
return listItems.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView txtberita;
ImageView imgberita;
TextView txtnama;
public ViewHolder(View itemView) {
super(itemView);
txtnama = (TextView) itemView.findViewById(R.id.txtnama);
txtberita = (TextView) itemView.findViewById(R.id.txtberita);
imgberita = (ImageView) itemView.findViewById(R.id.imgberita);
}
}
public void setOnItemClickListener(OnItemClickListener onItemClickListener){
this.onItemClickListener = onItemClickListener;
}
OnItemClickListener onItemClickListener;
public interface OnItemClickListener{
void onItemClick(int position);
}
}
your Activity. in Oncreate()
public class TestActivity extends AppCompatActivity implements attribute_list_adapter.OnItemClickListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
attribute_list_adapter adapter = new attribute_list_adapter(listItems, this);
adapter.setOnItemClickListener(this);
}
#Override
public void onItemClick(int position) {
// code here
}
}
Create an interface something like
public interface OnSingleItemClickListener{
void onSingleItemClick(int position);
}
Then implement it on your ViewHolder like this
public class ViewHolder extends RecyclerView.ViewHolder implements OnSingleItemClickListener {
public ViewHolder(View itemView) {
super(itemView);
}
#Override
void onSingleItemClick(int position){
if(listItems.get(position) == listItems.get(getAdapterPosition)){
// TODO do something here
}
}
now on your OnBindViewHolder inside your adapter you must do this.
holder.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
holder.onSingleItemClick(position);
}
}):
Related
I am using RecyclerView in BottomSheet.The data is fetched successfuly but unable to get click action on the RecyclerView items. This is my BottomSheetAdapter code :
public class BottomSheetAdapter extends RecyclerView.Adapter<BottomSheetAdapter.ViewHolder> {
List<UserDetailsModel> userDetailsModelList;
Context context;
private Onitemclicklistenersuggestion listener;
public BottomSheetAdapter(List<UserDetailsModel> userDetailsModelList, Context context) {
this.userDetailsModelList = userDetailsModelList;
this.context = context;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.bottom_sheet_recycler_items, parent, false);
return new BottomSheetAdapter.ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
UserDetailsModel model = userDetailsModelList.get(position);
holder.firstNameLabel.setText(model.getFirst_name().trim());
}
#Override
public int getItemCount() {
return userDetailsModelList.size();
}
class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView firstNameLabel;
public ViewHolder(#NonNull View itemView) {
super(itemView);
firstNameLabel = itemView.findViewById(R.id.firstNameLabel);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if (listener != null) {
int position = getAdapterPosition();
if (position != RecyclerView.NO_POSITION) {
listener.clicktoupdate(position);
}
}
}
}
public interface Onitemclicklistenersuggestion {
void clicktoupdate(int poistion);
}
public void setOnitemclicklistener(Onitemclicklistenersuggestion mlistener) {
listener = mlistener;
}
}
This is my BottomSheetDialog code :
public class BottomSheetDialog extends BottomSheetDialogFragment
implements BottomSheetAdapter.Onitemclicklistenersuggestion {
bottomSheetAdapter = new BottomSheetAdapter(userDetailsModelList, getActivity());
bottomSheetRecycler.setAdapter(bottomSheetAdapter);
bottomSheetRecycler.setLayoutManager(new LinearLayoutManager(getActivity()));
bottomSheetAdapter.setOnitemclicklistener(new BottomSheetAdapter.Onitemclicklistenersuggestion() {
#Override
public void clicktoupdate(int poistion) {
Log.e("Pos", "Pos");
}
});
bottomSheetAdapter.notifyDataSetChanged();
}
#Override
public void clicktoupdate(int poistion) {
Toast.makeText(getContext(), ""+poistion, Toast.LENGTH_SHORT).show();
}
But after clicking the RecyclerView items neither the Log or the Toast message shows up. Please help me fix it. Thanks in Millions.
Try setting the onClick logic inside your ViewHolder class.
So something like,
class ViewHolder extends RecyclerView.ViewHolder {
TextView firstNameLabel;
public ViewHolder(#NonNull View itemView) {
super(itemView);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// show a toast msg or whatever action you need...
}
});
firstNameLabel = itemView.findViewById(R.id.firstNameLabel);
}
}
I am trying to setup onClickListeners inside my ViewHolder class, but I need the position of each. How can I pass the position from onBindViewHolder to my
ViewHolder class?
#NonNull
#Override
public AdapterAllComments.ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.model_rv_allcomments_container, viewGroup, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull AdapterAllComments.ViewHolder viewHolder, int position) {
}
#Override
public int getItemCount() {
return mCommentId.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
LinearLayout viewHolderLayout;
public ViewHolder(#NonNull View itemView) {
super(itemView);
viewHolderLayout = itemView.findViewById(R.id.item_child_layout);
}
}
this adapter from my other project :
public class ChildrenRvAdapter extends RecyclerView.Adapter<ChildrenRvAdapter.ViewHolder> {
private List<String> mData;
private LayoutInflater mInflater;
private ItemClickListener mClickListener;
private Context context;
public ChildrenRvAdapter(Context context, List<String> data) {
this.mInflater = LayoutInflater.from(context);
this.mData = data;
this.context = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.children_rv_row, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
String name = mData.get(position);
holder.tv_name.setText(name);
setAnimation(holder.itemView, position);
}
#Override
public int getItemCount() {
return mData.size();
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView tv_name;
Button btn_remove;
ViewHolder(View itemView) {
super(itemView);
tv_name = itemView.findViewById(R.id.tv_name);
btn_remove = itemView.findViewById(R.id.btn_remove);
btn_remove.setOnClickListener(this);
}
#Override
public void onClick(View view) {
if (mClickListener != null) mClickListener.onItemClick(view, getAdapterPosition());
}
}
String getItem(int id) {
return mData.get(id);
}
public void setClickListener(ItemClickListener itemClickListener) {
this.mClickListener = itemClickListener;
}
public interface ItemClickListener {
void onItemClick(View view, int position);
}
}
}
so you create interface in your adapter and also declare it in local mClickListener and implement it in ViewHolder class and setonclick where you create the viewholder:
ViewHolder(View itemView) {
super(itemView);
tv_name = itemView.findViewById(R.id.tv_name);
btn_remove = itemView.findViewById(R.id.btn_remove);
btn_remove.setOnClickListener(this);
}
just note that i set it on a button but you can set it on itemView
also on any view that have the setOnClickListener so you can use :
itemView.setOnClickListener(this);
then from your activity or fragment and wherever using the adapter, just implemet the onlick interface and after initializing the adapter use the method that we created public void setClickListener in our adapter, to local interface in the adapter
public void setClickListener(ItemClickListener itemClickListener) {
this.mClickListener = itemClickListener;
}
activity:
public class ChildrenEditDialog extends Dialog implements IChildren.IView, ChildrenRvAdapter.ItemClickListener
and in activity onCreate or somewhere else:
childrenRvAdapter = new ChildrenRvAdapter(c, dataSource);
childrenRvAdapter.setClickListener(this);
and you have onlcick in your activity/fragment/dialog/etc...
Use ViewHolders getAdapterPosition() for getting current position of ViewHolder.
To get the current position of the onBindViewHolder to ViewHolder class getAdapterPosition() can be used.
As an example,
public class ViewHolder extends RecyclerView.ViewHolder{
LinearLayout viewHolderLayout;
viewHolderLayout = itemView.findViewById(R.id.item_child_layout);
public ViewHolder(#NonNull View itemView) {
super(itemView);
viewHolderLayout.setOnClickListener(v -> {
lastClickedPosition = getAdapterPosition();
});
}
}
I have an app which contains recyclerview with imageview and text.When I click on item based on position that is imageview i want image of that image view and set it to another Imageview.To do this I have made interface and implements its method in Activity but need to know that how do i do that
Adapter code:
public interface OnItemClicked {
void onItemClicked(int position);
}
public AvatarListAdapter(Context context, int[] arrayList) {
this.mContext = context;
this.dataModel = arrayList;
}
#Override
public AvatarListAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.avatar_items, parent, false);
return new AvatarListAdapter.ViewHolder(view);
}
#Override
public void onBindViewHolder(AvatarListAdapter.ViewHolder holder, final int position) {
holder.mAvatarImage.setImageResource(dataModel[position]);
holder.mAvatarImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onClick.onItemClicked(position);
}
});
}
public void setOnClick(OnItemClicked onClick) {
this.onClick = onClick;
}
#Override
public int getItemCount() {
return dataModel.length;
}
public class ViewHolder extends RecyclerView.ViewHolder {
private CircleImageView mAvatarImage;
public ViewHolder(View itemView) {
super(itemView);
mAvatarImage = itemView.findViewById(R.id.img_avatar);
}
}
}
Activity code:
private void initializeActions() {
int numberOfColumns = 3;
mAvatarImages.setLayoutManager(new GridLayoutManager(AvatarProfileImage.this, numberOfColumns));
mAdapter = new AvatarListAdapter(AvatarProfileImage.this, avatar);
mAvatarImages.setAdapter(mAdapter);
mAdapter.setOnClick(this);
}
#Override
public void onItemClicked(int position) {
String pos = "You clicked at position " + position;
Toast.makeText(getApplicationContext(), "You clicked position" + pos, Toast.LENGTH_LONG).show();
mAvatarImages.setBackgroundResource(avatar[position]);
}
You can get data by position on OnClick().As you are using local drawable for image resource, One way to do is Modify your viewHolder as follows.This is just a one way you can also use ViewTag.
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
private Circle mAvatarImage;
public ViewHolder(View itemView) {
super(itemView);
mAvatarImage = itemView.findViewById(R.id.img_avatar);
mAvatarImage.setOnClickListener(this);
}
#Override
public void onClick(View v) {
int postion =getAdapterPosition();
int image =arrayList[postion];
// Use this image to forward
}
}
Remove OnClick from onBindViewHolder.
Implement RecycleView onClick() method and get specified data while onclick position.have look
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
private Circle mAvatarImage;
public ViewHolder(View itemView) {
super(itemView);
mAvatarImage = itemView.findViewById(R.id.img_avatar);
mAvatarImage.setOnClickListener(this);
}
#Override
public void onClick(View v) {
int position=arrayList[getAdapterPosition()];
String imagepath = arraylist.get(position).getImagePath
//you can use imagepath anywhere you want either be put in bundle or intent call
}
}
Adapter code should look like this
private final OnItemClickListener listenerOnItemClick;
public interface OnItemClickListener {
void onItemClick(int position); }
public AvatarListAdapter(Context context, int[] arrayList, OnItemClickListener listenerOnItemClick) {
this.mContext = context;
this.dataModel = arrayList;
this.listenerOnItemClick=listenerOnItemClick;
}
#Override
public AvatarListAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.avatar_items, parent, false);
return new AvatarListAdapter.ViewHolder(view); }
#Override
public void onBindViewHolder(AvatarListAdapter.ViewHolder holder, final int position) {
holder.mAvatarImage.setImageResource(dataModel[position]);
holder.mAvatarImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onClick.onItemClicked(position);
}
}); }
public void setOnClick(OnItemClicked onClick) {
this.onClick = onClick; }
#Override
public int getItemCount() {
return dataModel.length; }
public class ViewHolder extends RecyclerView.ViewHolder {
private CircleImageView mAvatarImage;
public ViewHolder(View itemView) {
super(itemView);
mAvatarImage = itemView.findViewById(R.id.img_avatar);
} }
Activity Code
AvatarListAdapter.OnItemClickListener onItemClickListener = new AvatarListAdapter.OnItemClickListener() {
#Override
public void onItemClick(int position) {
//change your Image here
String pos = "You clicked at position " + position;
Toast.makeText(getApplicationContext(), "You clicked position" + pos, Toast.LENGTH_LONG).show();
mAvatarImages.setBackgroundResource(avatar[position]);
}
};
private void initializeActions() {
int numberOfColumns = 3;
mAvatarImages.setLayoutManager(new GridLayoutManager(AvatarProfileImage.this, numberOfColumns));
mAdapter = new AvatarListAdapter(AvatarProfileImage.this, avatar,onItemClickListener );
mAvatarImages.setAdapter(mAdapter);
mAdapter.setOnClick(this);
}
I have to two data sets with different adapters inside a single activity and I want to use notifyDataSetChanged() however its not working for the other adapter. So inside my adapterFirst class I have LongCLickListener which is using notifyDataSetChanged() and I want to call the adapterSecond to notify too if adapterFirst is updated. The AdapterSecond data is not being updated when pressing LongClick
public class AdapterFirst extends RecyclerView.Adapter <AdapterFirst .ViewHolder> {
private List<Object> objectList;
private Context mContext;
AdapterSecond adapterSecond;
public AdapteFirst(List<Object> list) { objectList= list; }
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_list, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
//query method
notifyDataSetChanged(); //working
//here it gets the nullpointerexception error
adapterSecond = new AdapteSecond();
adapterSecond.notifyDataSetChanged();
}
});
}
#Override
public int getItemCount() {
return (objectList != null? objectList.size():0);
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView data;
public ViewHolder(View itemView) {
super(itemView);
data= (TextView) itemView.findViewById(R.id.text);
}
}
}
AdapterSecond
public class AdapterSecond extends
RecyclerView.Adapter <AdapterSecond.ViewHolder> {
private List<Object> objectList;
private Context mContext;
public AdapterSecond () {}
public AdapterSecond (List<Object> list) { objectList= list; }
#Override
public AdapterSecond.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_list_2, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(final AdapterSecond.ViewHolder holder, int position) {
final Object object = objectList.get(holder.getAdapterPosition());
holder.data2.setText(object.getData());
}
#Override
public int getItemCount() {
return (objectList != null? objectList.size():0);
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView data2;
public ViewHolder(View itemView) {
super(itemView);
data2= (TextView) itemView.findViewById(R.id.text2);
}
}
}
Seems like the order of initialization of the adapters have some issues.
Just make sure that you have initialize the secondAdapter before the firstAdapter
secondAdapter= new SecondAdapter();
firstAdapter = new FirstAdapter();
Just check the order in which they initialize!
I have a recyclerview . I click on a item. It is highlighted ( sets background - color) . And then, I click another item , It doesn't remove old highlighted view. My class is very leak . Also could you give me an advice to make more effective ?
public class DrawerMenuShelfListAdapter extends RecyclerView.Adapter<DrawerMenuShelfListAdapter.ViewHolder> implements View.OnClickListener {
private int selectedRow = 0;
public Fragment fragment;
public ViewHolder holder;
public RecyclerView recyclerView;
private ArrayList<ShelfModel> shelfList;
public DrawerMenuShelfListAdapter(Fragment fragment, ArrayList<ShelfModel> shelfList, RecyclerView recyclerView) {
this.shelfList = shelfList;
this.fragment = fragment;
this.recyclerView = recyclerView;
}
public void setItemSelected(int position){
recyclerView.getChildAt(selectedRow).setBackgroundColor(fragment.getActivity().getResources().getColor(android.R.color.transparent));
notifyItemChanged(selectedRow);
selectedRow = position;
recyclerView.getChildAt(selectedRow).setBackgroundColor(fragment.getActivity().getResources().getColor(android.R.color.black));
notifyItemChanged(selectedRow);
}
public void updateList(ArrayList<ShelfModel> list){
shelfList.clear();
shelfList.addAll(list);
notifyDataSetChanged();
notifyItemChanged(selectedRow);
}
#Override
public DrawerMenuShelfListAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v= LayoutInflater.from(parent.getContext())
.inflate(R.layout.navigation_drawer_list_row, parent, false);
holder = new ViewHolder(v);
holder.text = (TextView) v.findViewById(R.id.definitionText);
holder.total = (TextView) v.findViewById(R.id.countText);
holder.editButton = (ImageButton)v.findViewById(R.id.editButton);
holder.text.setTypeface(App.MUSEO_100);
holder.total.setTypeface(App.MUSEO_300);
return holder;
}
#Override
public void onBindViewHolder(ViewHolder holder, final int position) {
final ShelfModel shelfModel = shelfList.get(position);
holder.text.setText(shelfModel.getName());
holder.total.setText(String.valueOf(shelfModel.getTotal()));
holder.shelfId = shelfModel.getShelfId();
holder.itemView.setOnClickListener(this);
}
#Override
public int getItemCount() {
return shelfList.size();
}
#Override
public void onClick(View v) {
int position = recyclerView.getChildLayoutPosition(v);
((DrawerMenuShelfListListener)fragment).onShelfItemClick(shelfList.get(position));
setItemSelected(position);
}
public interface DrawerMenuShelfListListener extends BaseRecyclerViewListener {
void onShelfItemClick(ShelfModel shelfModel);
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView text;
public TextView total;
public ImageView editButton;
public int shelfId;
public ViewHolder(View view) {
super(view);
}
}
}
Ok. I found the solution.If I don't call notifyItemChanged , it works