I am working on a project in android and i just learn about card view class.
I made a card who generates a toast when user clicks on it.
But i also want my card to call another activity when user clicks on it.
I am posting part of my code below.
btnProceed.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
showToast("Proceed to the next step");
Intent intent = new Intent(MyLocationUsingLocationAPI.this, click_picture.class);
startActivity(intent);
}
});
I have made changes in my code as you said but when i click on proceed button my app crashes.What is wrong with code?
the main idea here is to define your actionClickListener
1. create a custom recycleView Adapter
public class AdapterCustomList extends RecyclerView.Adapter<RecyclerView.ViewHolder>
2. define onItemClickListener interface
public interface OnItemClickListener {
void onItemClick( whateverArgsYouWant );
}
3. make an attribute of the interface and define a setter for it
private OnItemClickListener mOnItemClickListener;
public void setOnItemClickListener(final OnItemClickListener mItemClickListener) {
this.mOnItemClickListener = mItemClickListener;
}
4. append a listener to each item while its created in the adapter class
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
...
OriginalViewHolder vItem = (OriginalViewHolder) holder;
vItem.baseCard.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (mOnItemClickListener != null) {
mOnItemClickListener.onItemClick( whateverArgsYouWant );
}
}
});
}
this method will be called when items of recycle view is created (in case you use card view inside a recycle view)
5. use your onClickListener in the Activity you want
AdapterCustomList mAdapter = new AdapterCustomList (getActivity(), recyclerView,yourListItemsHere));
recyclerView.setAdapter(mAdapter);
// on item list clicked
mAdapter.setOnItemClickListener(new AdapterPostList.OnItemClickListener() {
#Override
public void onItemClick( whateverArgsYouWant ) {
...
statements
...
}
});
Related
Which is the most recommended way of handling click on RecyclerView items?
recyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
private RecyclerView.OnItemTouchListener itemTouchListener;
#Override
public boolean onInterceptTouchEvent(#NonNull RecyclerView recyclerView, #NonNull MotionEvent motionEvent) {
return false;
}
#Override
public void onTouchEvent(#NonNull RecyclerView recyclerView, #NonNull MotionEvent motionEvent) {}
#Override
public void onRequestDisallowInterceptTouchEvent(boolean b) {}
});
Or setting a click listener on an item view inside the adapter?
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Do stuff
}
});
A Best and efficient way to get a click of recycler view item is by using interface as below:
1) First, define one interface as below
public interface OnListItemClick {
void onClick(View view, int position);
}
2) Now, set it from your fragment or activity
OnListItemClick onListItemClick = new OnListItemClick() {
#Override
public void onClick(View view, int position) {
// you will get click here
// do your code here
}
};
youradaptor.setClickListener(onListItemClick);
3) Now create one method in your adapter
public void setClickListener(OnListItemClick context) {
this.onListItemClick = context;
}
4) Now, from your itemview click use as below
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onListItemClick.onClick(view, getAdapterPosition()); // passing click to interface
}
});
Most common way it to use interfaces to handle onClick events inside a Recycler View.
Great read about this topic here
Go for your second opinion. But an interface should be implemented to handle the OnClick Event
I have a RecyclerView with post cards. So there is a like button in every post card. When I tap on a like button. Sometimes it works fine and updates on current item. But after some scroll when I tap on like button it updates on another item simultaneously.
It doesn't send that data to server. But, only the view is updated. Then when I scroll up and down again. The data goes back to normal.
Problem is in the following onClick method:-
FirebaseDatabase.getInstance().getReference().child("topics").child("likes").child(data.getId()).child(username).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.child("like").exists()){
holder.like.setImageResource(R.drawable.ic_favorite_red_500_36dp);
holder.like.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
FirebaseDatabase.getInstance().getReference().child("topics").child("likes").child(data.getId()).child(username).child("like").removeValue();
}
});
}else if(dataSnapshot.child("dislike").exists()) {
holder.like.setImageResource(R.drawable.brokenheart);
holder.like.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
FirebaseDatabase.getInstance().getReference().child("topics").child("likes").child(data.getId()).child(username).child("dislike").removeValue();
}
});
}else{
holder.like.setImageResource(R.drawable.ic_favorite_border_red_500_36dp);
holder.like.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
FirebaseDatabase.getInstance().getReference().child("topics").child("likes").child(data.getId()).child(username).child("dislike").removeValue();
FirebaseDatabase.getInstance().getReference().child("topics").child("likes").child(data.getId()).child(username).child("like").setValue(true);
}
});
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
holder.like.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
FirebaseDatabase.getInstance().getReference().child("topics").child("likes").child(data.getId()).child(username).child("like").removeValue();
FirebaseDatabase.getInstance().getReference().child("topics").child("likes").child(data.getId()).child(username).child("dislike").setValue(true);
return true;
}
});
Full Adapter class https://pastebin.com/UnFGahWT
Try the following:-
Set Your on click listeners in the public ViewHolder(View itemView) method and make Your ViewHolder class implement the View.OnClickListener.
In Adapter add:
public Topic getItem(int position) {
return topics.get(position);
}
In ViewHolder's onClick method add:
int position = getAdapterPosition();
if (position == RecyclerView.NO_POSITION) return;
item = getItem(position);
Thus You will get the exact object You need to change or do something with it.
I have a RecylerView which contains a textView as individual item. Based on the requirement, the background image of the textView will be changed on click after checking the present image.
In simple:
onClick textView TV--> check for the background image of the textview TV--> check if the background image of TV is a, then make it b and viceversa
Please find my code below:
viewHolder.addRemove.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(viewHolder.clicked==0)
{
viewHolder.addRemove.setBackgroundResource(R.mipmap.added);
viewHolder.clicked=1;
groupSlcArray.add(model.getName().trim());
Log.d("groupArr", Arrays.toString(groupSlcArray.toArray()));
}
else
{
viewHolder.addRemove.setBackgroundResource(R.mipmap.addslcgroup);
viewHolder.clicked=0;
groupSlcArray.remove(model.getName().trim());
Log.d("groupArr", Arrays.toString(groupSlcArray.toArray()));
}
}
});
I am unable to find anyway to get the background resource of the textView for checking.Need your help.This question might seem too simple for some. So please before Outvoting, try to give a solution because I have tried all the possible solutions that I found.Thanks in advance
Try following code :
holder.textview.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (holder.textview.getBackground() == getResources().getDrawable(R.drawable.a)){
holder.textview.setBackground(R.drawable.b);
}
else{
holder.textview.setBackground(R.drawable.a);
}
}
});
You have to understand about getView.
Sometimes If you scroll in ListView, This is not an exact Color
So I would like to recommand following ways like this:
1. Add Code on getView
if (groupSlcArray.contain(odel.getName().trim())) {
viewHolder.addRemove.setBackgroundResource(R.mipmap.addslcgroup);
} else {
viewHolder.addRemove.setBackgroundResource(R.mipmap.added);
}
2. Change OnClickListener Event Code
viewHolder.addRemove.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick (View v){
if (groupSlcArray.contain(odel.getName().trim())) {
viewHolder.addRemove.setBackgroundResource(R.mipmap.addslcgroup);
groupSlcArray.remove(model.getName().trim());
Log.d("groupArr", Arrays.toString(groupSlcArray.toArray()));
} else {
viewHolder.addRemove.setBackgroundResource(R.mipmap.added);
groupSlcArray.add(model.getName().trim());
Log.d("groupArr", Arrays.toString(groupSlcArray.toArray()));
}
}
});
Here is a solution that you can use for change background image of each RecyclerView item.
For example, currently, each row of your RecyclerView is a Item, you need to create 1 more field name textViewBackGround for hold the back ground of each row like this
public class Item{
...
public int textViewBackGround = R.drawable.a; // default image a
}
Then in your adapter
public class MyRecyclerViewAdapter extends RecyclerView.Adapter < MyRecyclerViewAdapter.CustomViewHolder > {
private List < Item > itemList;
private Context mContext;
public MyRecyclerViewAdapter(Context context, List < Item > itemList) {
this.itemList = itemList;
this.mContext = context;
}
#Override
public void onBindViewHolder(CustomViewHolder viewHolder, int i) {
Item item = itemList.get(i);
viewHolder.textView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// don't need to get the background of your TextView then change the background, just need to check the datasource. Later on, you absolutely will know that check the datasource for change background of item is a correct way not check the background resource
if (item.textViewBackGround == R.drawable.a) {
viewHolder.textView.setBackgroundResource(R.drawable.b);
item.textViewBackGround = R.drawable.b;
} else {
viewHolder.textView.setBackgroundResource(R.drawable.a);
item.textViewBackGround = R.drawable.a;
}
}
});
viewHolder.textView.setBackgroundResource(item.textViewBackGround); // need to set the background image for `TextView` everytime bind ViewHolder because RecyclerView item will recycle when you scroll (if you don't understand it, you can remove this line, run your app, scroll up/down and you will understand it)
...
}
class CustomViewHolder extends RecyclerView.ViewHolder {
protected TextView textView;
public CustomViewHolder(View view) {
super(view);
...
}
}
}
I am new in android and learning about RecyclerView. I am working with json so that i can get data from server. I followed this tutorial for this. I am not getting how to implement onclicklistner on my recyclerview.
Following your tutorial, on the "bind data" method you can set a click listener. It will as easy as writing:
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// write your code here
}
});
You will also need to change the
int position
to final, like:
#Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder,final int position) {
Item click listeners for RecyclerView
See the answer
you should use ItemClickSupport library :
ItemClickSupport.addTo(recyclerView)
.setOnItemClickListener(new ItemClickSupport.OnItemClickListener() {
#Override
public void onItemClicked(RecyclerView recyclerView, int position, View v) {
/* do your thing */
}
});
#Override
public void onBindViewHolder(ViewHolder holder, final int position) {
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//TODO
}
}
}
If you are talking about onItemClickListener of ListView , unfortunately there is no such method in RecyclerView. What you can do is, give an id to your parent view of RecyclerView item, and set an onClickListener on that in onBindViewHolder.
I saw some different ways of implementing onItemClickListener for RecyclerView. My favourite is to use interface callback:
Interface:
public interface OnClickListener {
void onCardClick(View v);
void onFavouriteButtonClick(View v);
void onRemoveClick(View v);
//Other clickable areas
}
In adapter:
currentView.favouriteButton.setTag(currentItem.getId());
currentView.favouriteButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (OnClickListener != null){
OnClickListener.onFavouriteButtonClick(v);
}
}
});
In main activity/fragment
adapter = new CardAdapter( .... new OnClickListener() {
#Override
public void onFavouriteButtonClick(View v) {
int id = Integer.parse(v.getTag().toString());
//Do your stuff
}
....
});
So, I have some questions:
is it good way of handling things?
will performance be slow if number of items will grow?
any reasons why I shouldn't use this approach?
I think you could improve upon this by not passing the view outside of the adapter.
// Create an object that encapulates the information for each card
public class CardInfo {
// Whatever you want to show in your card
}
// Create a listener for items instead of views
public interface OnCardAction {
void onCardSelected(CardInfo cardInfo);
void onFavoriteSelected(CardInfo cardInfo);
void onCardRemoved(CardInfo cardInfo);
}
// In your adapter
favoriteButton.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
// You many need to check if onCardActionLisetner is null
CardInfo cardInfo = getItemAt(viewHolder.getAdapterPosition());
onCardActionListener.onFavoriteSelected(cardInfo);
}
});
NOTE: If you are passing the listener in the constructor can either make it required (throw error if it is null) or not even create View.OnClickListner to reduce the number of null checks.