I tried this many times, but now I am having trouble clicking on a GridView.
Here is my adapter.
public class MoviesAdapter extends RecyclerView.Adapter<MoviesAdapter.MoviesViewHolder>{
private Context context;
private List<Movies> moviesList;
final private MoviesAdapterOnClickHandler mClickHandler;
public interface MoviesAdapterOnClickHandler{
void onClick(String movieId);
}
public MoviesAdapter(Context context, List<Movies> moviesList, MoviesAdapterOnClickHandler mClickHandler ){
this.context = context;
this.moviesList = moviesList;
this.mClickHandler = mClickHandler;
}
#Override
public MoviesViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Context context = parent.getContext();
int layoutIdForListItem = R.layout.movies_row;
LayoutInflater inflater = LayoutInflater.from(context);
boolean shouldAttactToParentImmediately = false;
View view = inflater.inflate(layoutIdForListItem,parent,shouldAttactToParentImmediately);
MoviesViewHolder moviesViewHolder = new MoviesViewHolder(view);
return moviesViewHolder;
}
#Override
public void onBindViewHolder(MoviesViewHolder holder, int position) {
Movies movies = moviesList.get(position);
Picasso.with(context)
.load(NetworkUtils.getImageURL(movies.getImageThumbnail()))
.placeholder(R.drawable.ic_broken_image)
.into(holder.mMovieImage);
Log.v("MovieAdapter",NetworkUtils.getImageURL(movies.getImageThumbnail()));
}
#Override
public int getItemCount() {
return moviesList.size();
}
public void setMoviesData(List<Movies> moviesList){
this.moviesList = moviesList;
notifyDataSetChanged();
}
public class MoviesViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
ImageView mMovieImage;
public MoviesViewHolder(View itemView) {
super(itemView);
mMovieImage = itemView.findViewById(R.id.movieImage);
}
#Override
public void onClick(View v) {
int adapterPosition = getAdapterPosition();
String movieId = moviesList.get(adapterPosition).getMovieId();
Log.v("MovieAdapter",movieId);
mClickHandler.onClick(movieId);
}
}
}
And part of my activity which actually implements the MoviesAdapterOnClickHandler
public class MainActivityFragment extends Fragment
implements LoaderManager.LoaderCallbacks<Object>, MoviesAdapter.MoviesAdapterOnClickHandler {
...
adapter = new MoviesAdapter(getActivity(), moviesArrayList, this);
...
#Override
public void onClick(String position) {
Toast.makeText(getActivity()," id: " + position, Toast.LENGTH_SHORT).show();
}
Any ideas?
Thanks,
Theo
Your view holder implements OnClickListener but you are not setting the listener on your view. You need to do something like view.setOnClickListener(this) in the constructor of the ViewHolder
You forget to add itemView.setOnClickListener(this); inside your MoviesViewHolder Constructor , your MoviesViewHolder implements onClick so you have to add this.
public class MoviesViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
ImageView mMovieImage;
public MoviesViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
mMovieImage = itemView.findViewById(R.id.movieImage);
}
Related
I have a nested recyclerview with Parent RV: representing a category whereas Child RV: represents a list of items of a certain category. Currently I am getting null pointer exception but I have no idea why. I have 2 interface - 1st, takes the position of the child RV (selected item) and the 2nd one - gets the position of parent RV position (i.e. which category was selected), child RV position and title of the selected item.
Issue:
ParentRVAdapter.java:57 -> rvItemClickListener.onChildItemClick(holder.getAdapterPosition(),position,itemTitle);
CatalogItemChildRVAdapter.java:68 -> onItemListener.onItemClick(getAdapterPosition());
Parent Recycler View:
public class ParentRVAdapter extends RecyclerView.Adapter<ParentRVAdapter.ViewHolder> implements CatalogItemChildRVAdapter.onItemListener{
private Context context;
private List<CatalogCategories> categories;
private CatalogItemChildRVAdapter itemChildRVAdapter;
private List<CategoryItem> categoryItemList;
private RVItemClickListener rvItemClickListener;
public void setRvItemClickListener(RVItemClickListener rvItemClickListener) {
this.rvItemClickListener = rvItemClickListener;
}
public ParentRVAdapter(Context context, List<CatalogCategories> categories) {
this.context = context;
this.categories = categories;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return new ViewHolder(LayoutInflater.from(context).inflate(R.layout.home_parentrv_item,parent,false));
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
holder.categoryTv.setText(categories.get(position).getCatTitles());
categoryItemList = categories.get(position).getCategoryItemList();
setCategoriesItemRV(holder.itemRv, categoryItemList);
itemChildRVAdapter.setMonItemListener(new CatalogItemChildRVAdapter.onItemListener() {
#Override
public void onItemClick(int position) {
String itemTitle = categoryItemList.get(position).getTitle();
rvItemClickListener.onChildItemClick(holder.getAdapterPosition(),position,itemTitle);
System.out.println("Works");
}
});
}
#Override
public int getItemCount() {
return categories.size();
}
#Override
public void onItemClick(int position) {}
public static final class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
TextView categoryTv;
RecyclerView itemRv;
public ViewHolder(#NonNull View itemView) {
super(itemView);
categoryTv = itemView.findViewById(R.id.categoriesTv);
itemRv = itemView.findViewById(R.id.itemRv);
}
#Override
public void onClick(View view) {
}
}
private void setCategoriesItemRV(RecyclerView recyclerView, List<CategoryItem> categoryItemList){
itemChildRVAdapter = new CatalogItemChildRVAdapter(context,categoryItemList,this);
recyclerView.setLayoutManager(new LinearLayoutManager(context, RecyclerView.HORIZONTAL,false));
recyclerView.setAdapter(itemChildRVAdapter);
}
public interface RVItemClickListener{
void onChildItemClick (int parentPos, int childPos, String item);
}
}
Child RecyclerView:
public class CatalogItemChildRVAdapter extends RecyclerView.Adapter<CatalogItemChildRVAdapter.ViewHolder> {
private Context context;
private List<CategoryItem> categoryItemList;
private onItemListener monItemListener;
public void setMonItemListener(onItemListener monItemListener) {
this.monItemListener = monItemListener;
}
public CatalogItemChildRVAdapter(Context context, List<CategoryItem> categoryItemList, onItemListener monItemListener) {
this.context = context;
this.categoryItemList = categoryItemList;
this.monItemListener = monItemListener;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.childrv_eacat_item,parent,false);
return new ViewHolder(view,monItemListener);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
holder.image.setImageResource(categoryItemList.get(position).getImage());
holder.itemname.setText(categoryItemList.get(position).getTitle());
}
#Override
public int getItemCount() {
return categoryItemList.size();
}
public static final class ViewHolder extends RecyclerView.ViewHolder {
ImageView image;
TextView itemname;
//onItemListener onItemListener;
int itempos;
public ViewHolder(#NonNull View itemView, onItemListener onItemListener) {
super(itemView);
//this.onItemListener = onItemListener;
image = itemView.findViewById(R.id.categoryitemIv1);
itemname = itemView.findViewById(R.id.categoryitemTv1);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onItemListener.onItemClick(getAdapterPosition());
itempos = getAdapterPosition();
System.out.println("Clicked at postion: "+itempos);
}
});
}
/* #Override
public void onClick(View view) {
onItemListener.onItemClick(getAdapterPosition());
itempos = getAdapterPosition();
System.out.println("Clicked at postion: "+itempos);
} */
}
public interface onItemListener{
void onItemClick(int position);
} }
I have an error that says:
error: cannot find symbol
Vholder.setData(mValues.get(position));
^
symbol: method setData(Object)
location: variable Vholder of type ViewHolder
How do I fix these?
Here is the code: This is my Adapter class for my grid layout. I do not know why it is not working.
public class TrackAdapter extends RecyclerView.Adapter {
ArrayList mValues;
Context mContext;
protected ItemListener mListener;
public TrackAdapter(Context context, ArrayList values, ItemListener itemListener) {
mValues = values;
mContext = context;
mListener=itemListener;
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TextView textView;
public ImageView imageView;
public RelativeLayout relativeLayout;
TrackData data;
public ViewHolder(View v) {
super(v);
v.setOnClickListener(this);
textView = (TextView) v.findViewById(R.id.textView);
imageView = (ImageView) v.findViewById(R.id.imageView);
relativeLayout = (RelativeLayout) v.findViewById(R.id.relativeLayout);
}
public void setData(TrackData data) {
this.data = data;
textView.setText(data.text);
imageView.setImageResource(data.icon);
relativeLayout.setBackgroundColor(Color.parseColor(data.gridBGColor));
}
#Override
public void onClick(View view) {
if (mListener != null) {
mListener.onItemClick(data);
}
}
}
#Override
public TrackAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.makati_recycler_grid_track, parent, false);
return new ViewHolder(view);
}
#Override
**public void onBindViewHolder(#NonNull RecyclerView.ViewHolder Vholder, int position) {
Vholder.setData(mValues.get(position));
}**
#Override
public int getItemCount() {
return mValues.size();
}
public interface ItemListener {
void onItemClick(TrackData data);
}
}
or here is the line
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder Vholder, int position) {
Vholder.setData(mValues.get(position));
}
You have to extend your TrackAdapter with RecyclerView Type. ie.
public class TrackAdapter extends RecyclerView.Adapter< ViewHolder >
You should cast RecyclerView.ViewHolder to TrackAdapter.ViewHolder like this:
if (Vholder instanceof TrackAdapter.ViewHolder){
((TrackAdapter.ViewHolder)Vholder).setData(mValues.get(position));
}
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();
});
}
}
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);
}
}):
After I changed the parameter of onBindViewHolder,it turned gray,and not be called,why? Here is my adapter:
public class Myadapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context;
private List<String> lists;
private OnItemClickListener onItemClickListener;
public Myadapter(Context context, List<String> lists) {
this.context = context;
this.lists = lists;
}
public interface OnItemClickListener {
void onItemClick(View view, int postion);
void onItemLongClick(View view, int postion);
}
public void setOnItemClickListener(OnItemClickListener listener) {
this.onItemClickListener = listener;
}
#Override
public void onBindViewHolder(final myViewHolder holder, int position) {
holder.textView.setText(lists.get(position));
if (onItemClickListener != null) {
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int postion = holder.getLayoutPosition();//得到当前点击item的位置postion
onItemClickListener.onItemClick(holder.itemView, postion);
}
});
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
int postion = holder.getLayoutPosition();
onItemClickListener.onItemLongClick(holder.itemView, postion);
return true;
}
});
}
}
#Override
public int getItemCount() {
return lists.size();
}
#Override
public myViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(context).inflate(R.layout.item,parent,false);
myViewHolder viewHolder = new myViewHolder(itemView);
return viewHolder;
}
public class myViewHolder extends RecyclerView.ViewHolder{
TextView textView;
public myViewHolder(View itemView){
super(itemView);
textView =(TextView)itemView.findViewById(R.id.text);
}
}
}
It says Myadapter must either be declared abstract of implement abstract method onBindViewHolder(VH,int) in "Adapter"
Since you are trying to use your own ViewHolder for this adapter you need to use it as the type when extending RecyclerView.Adapter.
Change:
public class Myadapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
To:
public class Myadapter extends RecyclerView.Adapter<myViewHolder> {