using onClick to open details depending on the position of Recycler view - android

I want to open more details when I click on the item using the position and set the datils in the activity.
You can write your suggestion in Java or Kotlin :)

Create Constructor in adapter class :
public DataAdapter(List<Pojo> dataList, OnItemClickListener listener) {
this.dataList = dataList;
this.listener = listener;
}
Create OnBindViewHolder() method and get position :
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
final Pojo movie = dataList.get(position);
holder.Showid.setText(movie.getCatagory_id());
holder.fname.setText(movie.getCatagory_name());
holder.thumbNail.setImageUrl(movie.getCatagory_thumbnailUrl(), imageLoader);
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override public void onClick(View v) {
listener.onItemClick(movie.getSubCatagoryArrayList());
}
});
}
In MainActivity.class create on Interface :
public interface OnItemClickListener {
void onItemClick(ArrayList<Pojo2> item);
}

first of all recyclerView OnClick method to get position of Click item
like this method
int position=getAdapterPosition();
than get position of item (like modelArrayList.get(getAdapterPosition());)
than send id to next activity and id to get data in database and set all the details in next activity
final code
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int position=getAdapterPosition();
ModelClass model = modelArrayList.get(getAdapterPosition());
Long id = model.getId();
Intent i = new Intent(v.getContext(), NextActivity.class);
i.putExtra("id",id);
v.getContext().startActivity(i);
}
});
and NextActivity code
Long id = getActivity().getIntent().getExtras().getLong("id", 0);

Related

How to send value from onItemClick RecycleView to other java class

#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
String clicktemplate = modelClassesListt.get(i).getTitle();
Toast.makeText(Template.this ,modelClassesListt.get(i).getTitle() , Toast.LENGTH_SHORT).show();
}
I want to send this clicktemplate string value to other class
You have to put value in Intent or Bundle and send it to the next screen.
Here is an example for pass data in Activity.
Intent intent = new Intent(this, YourNextActivity.class);
intent.putExtra("key_clicktemplate", clicktemplate);
startActivity(intent);
To get value in next screen like below
String value = getIntent().getExtras().getString("key_clicktemplate");
You can use several approaches to implement your need.below thread will be useful to you.
How to pass values from RecycleAdapter to MainActivity or Other Activities
In your recyclerview class add onclicklistener interface and include your listener in constructor:
private final OnItemClickListener listener;
public interface OnItemClickListener {
void onItemClick(myObject item, int position, String message);
}
public MyRecyclerViewAdapter(Activity pActivity, ArrayList<myObject> pList, int pItemLayout, OnItemClickListener listener) {
activity = pActivity;
rewardsList = pList;
layoutID=pItemLayout;
this.listener = listener;
}
Then. in onCreateViewHolder:
#Override
public void onBindViewHolder(MyHolder holder, int position) {
myObject currentItem = rewardsList.get(position);
holder.bindList(currentItem, listener, position);
}
Next, in your ViewHolder add:
class MyHolder extends RecyclerView.ViewHolder {
View masterView;
MyHolder(View itemView) {
super(itemView);
masterView = itemView;
}
void bindList(final myObject item, final OnItemClickListener listener, int position){
masterView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.onItemClick(item, position,"edit");
}
});
...
Finally, in calling activity/fragment:
MyRecyclerViewAdapter adapter = new MyRecyclerViewAdapter(mActivity, list, R.layout.item, new MyRecyclerViewAdapter.OnItemClickListener() {
#Override
public void onItemClick(MyObject item, int position, String message) {
//item clicks handled here
switch (message){
case ITEM_OPEN:
// Do whatever you need with clicked item here
break;
case ITEM_EDIT:
// Do whatever you need with clicked item here
break;
}
}
}, mRecyclerView);

Onclick for each button inside RecyclerView items

How to get the position for clicked button inside the RecyclerView items
Here's my onBindViewHolder :
public void onBindViewHolder(MyViewHolder holder, int position) {
Masar masar=masrList.get(position);
holder.masarName.setText(masar.getMasarTitle());
holder.masarDesc.setText(masar.getMasarDescreption());
//How to get the Position
holder.masarImg.setImageResource(masar.getMasarImg());
holder.mapBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v ) {
//if you need position, just use recycleViewHolder.getAdapterPosition();
Intent intent = new Intent(v.getContext(), MapsActivity.class);
mContext.startActivity(intent);
}
});
}
If you need in onBindViewHolder only then you can use
holder.getAdapterPosition();
and if you need this position clicked in activity and fragment then you have to use callbacks from holder to activity and fragment and have to pass the same getAdapterPosition();
Edit: Added sample code for listening position click in fragment/activity
step 1: make an interface or callback
public interface RecyclerViewClickListener {
void onClick(View view, int position);
}
step 2: While initializing adapter class in fragment or activity pass the above-created reference as a parameter
public YourAdapter(List<SomeModel> modelList, RecyclerViewClickListener listener){
this.clickListener = listener;
}
step 3: In your ViewHolder or similar Class for view initialization do something like this
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private Button mapBtn;
ViewHolder(View v, RecyclerViewClickListener listener) {
super(v);
mapBtn = findViewById(R.id.mapBtn);
mListener = listener;
mapBtn.setOnClickListener(this);
}
#Override
public void onClick(View view) {
mListener.onClick(view, getAdapterPosition());
}
}
you will get the position in your fragment or activity where you have passed the callback reference while initializing the adapter.
Use holder.getAdapterPosition();
public void onBindViewHolder(final MyViewHolder holder, int position) {
Masar masar=masrList.get(position);
holder.masarName.setText(masar.getMasarTitle());
holder.masarDesc.setText(masar.getMasarDescreption());
//How to get the Position
holder.masarImg.setImageResource(masar.getMasarImg());
holder.mapBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v ) {
Toast.makeText(getContext(), "The position is: "+holder.getAdapterPosition(), Toast.LENGTH_SHORT).show();
Intent intent = new Intent(v.getContext(), MapsActivity.class);
mContext.startActivity(intent);
}
});}

How to Pass Position of RecyclerView to Activity?

I am trying to pass position of recyclerview to another activity where I am calliing retrofit Interface. Can I pass position of Recyclerview item so I can load different post from api
#Override
public void onBindViewHolder(TagAdapter.Tag_ViewHolder holder, final int position) {
holder.tagName.setText(Tags.get(position));
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (position < 8){
int pos = (int) getItemId(position) + 1;
Intent intent = new Intent (view.getContext(), Tag1Post.class);
intent.putExtra("pos", pos);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
}
My EndPoint is
#GET("/tag/{id}/")
Call<Tag> test(#Path("id") int id);
I want to replace id by RecyclerView position.
You can create an interface then transfer the position from the adapter to the activity.
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (position < 8){
int pos = (int) getItemId(position) + 1;
Intent intent = new Intent (view.getContext(), Tag1Post.class);
intent.putExtra("pos", pos);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
//create your interface in Activity, then send it to adapter and call it here:
yourListener.onTransferPosition(position);
}
}
On your activity that implements interface:
public void onTransferPosition(int position) {
this.position= position;
}
Instead of passing the position of Recycler View I pass the id of the particular post to navigate to comment on that post.
1. Provide Intent Extra with id of clicked post on Bindview holder of Adapter
public void onBindViewHolder(PostViewHolder holder, final int position) {
holder.postTitle.setText(posts.get(position).getTitle());
holder.postBody.setText(posts.get(position).getBody());
setAnimation(holder.itemView);
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int id = posts.get(position).getId(); // get Id
Intent intent = new Intent(context, CommentActivity.class);
intent.putExtra("pos", id); // Pass Id
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
});
}
2. Retrieve passed intent data
int mPostId = getIntent().getIntExtra("pos", 0);
3. Pass retrieved data to the retrofit endpoints
Call<List<Comment>> call = apiService.getComments(mPostId);
Retrofit Endpoints
#GET("/posts/{id}/comments/")
Call<List<Comment>> getComments(#Path("id") int id);
I hope this will help someone to encounter this type of problems.
Happy Coding :)
Since you are passing the view position using Intent class you can simply get the position in your second activity as below
int position = getIntent().getExtras().getInt("pos");
Or you can pass value using a interface
public interface OnRecyclerClickListener {
void makeRestCall(int position);
}
Instantiate the interface as follow
onRecyclerClickListener = (OnRecyclerClick) this.mContext;
send the view position like below
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (position < 8){
int pos = (int) getItemId(position) + 1;
startActivity(new Intent (view.getContext(), Tag1Post.class));
onRecyclerClickListener.makeRestCall(pos);
}
}
Finally, implement interface in your second activity
public class SecondActivity extends AppCompatActivity implements OnRecyclerClickListener{
#Override
public void makeRestCall(int pos) {
// do your GET request
}
private AdapterView.OnItemClickListener mOnClickListener;
Use this in your Adapter and ask this from your constructor.
Adapter(AdapterView.OnItemClickListener onClickListener){
this.mOnClickListener=onClickListener;
}
in your onclick method in holder class do like this:
#Override
public void onClick(View view) {
mOnClickListener.onItemClick(null, view, getAdapterPosition(), view.getId());
}
And implement AdapterView.OnItemClickListener in you activity
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
// here you will get the postion of the clicked item
}

Item manages his click or call listener ? (recyclerView)

I have a RecyclerView which contains multiple item types (4 or 5 at least).
Some items can be clicked, sometimes they have two differents clickListener (for example two imageView in one item).
For now, the item manages the clicks himself like this :
item.imageView1.setOnClickListener(....){
startActivity(Activity2);
}
item.imageView2.setOnClickListener(....){
startActivity(Activity1);
}
But I have a problem : I need to put some variables in the activity which will be started, so what is the best way to do this :
1) My item need to know these variables and continues to manage his own click ?
2) My item has a listener which call startActivity with the variables (like the fragment or parent activity or an object dedicated to this) ?
If you need more precisions, ask me.
Thx.
Make an interface for passing those values.
public interface MyRecyclerCallback {
void onItemClicked(Integer o); //insert whatever you want to pass further, possibly translated to form packable to intents
}
Then add it to your adapter from the activity with recycler like you would any listener. Either constructor or by separate method.
Pass it further down to every children upon their creation.
Call it when onClick gets detected with appropriate argument.
The actual argument may be some abstract thing
depending on your logic. It's more of a general idea. That's the way I do it with my recyclers.
In your activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecycler = (RecyclerView) findViewById(R.id.recycler);
MyAdapter adapter = new MyAdapter(this,new MyRecyclerCallback() {
#Override
public void onItemClicked(Integer o) { //any argument you like, might be an abstract
Intent i = new Intent(this,ActivityTwo.class);
i.putExtra(EXTRA_VALUE,o);
startActivity(i);
}
});
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mRecyclerView.setAdapter(adapter);
}
Adapter:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.Child>{
private final Context mContext;
private final MyRecyclerCallback mCallback;
private List<Integer> mChildren;
public MyAdapter(Context ctx, MyRecyclerCallback myRecyclerCallback) {
mContext = ctx;
mCallback = myRecyclerCallback;
mChildren = new ArrayList<>();
}
public void populateList(List<Integer> list ) { //this can be a network call or whatever you like
mChildren.addAll(list);
}
#Override
public Child onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(mContext).inflate(R.layout.item, parent, false);
return new Child(v,mCallback);
}
#Override
public void onBindViewHolder(Child holder, int position) {
holder.setValue1(mChildren.get(position)*3);
holder.setValue2(mChildren.get(position));
}
#Override
public int getItemCount() {
return mChildren.size();
}
public class Child extends RecyclerView.ViewHolder{
View mView1;
View mView2;
private int mValue1;
private int mValue2;
public Child(View itemView, final MyRecyclerCallback mCallback) {
super(itemView);
mView1 = itemView.findViewById(R.id.view1);
mView2 = itemView.findViewById(R.id.view2);
mView1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mCallback.onItemClicked(mValue1);
}
});
mView2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mCallback.onItemClicked(mValue2);
}
});
}
public void setValue1(int position) {
mValue1 = position;
}
public void setValue2(int position) {
mValue2=position;
}
}
}
this a good alternative to handle onclick and onlongclick
ItemClickSupport.addTo(mRecyclerView).setOnItemClickListener(new ItemClickSupport.OnItemClickListener() {
#Override
public void onItemClicked(RecyclerView recyclerView, int position, View v) {
// do it
}
});
http://www.littlerobots.nl/blog/Handle-Android-RecyclerView-Clicks/
You can have a single OnClickListener on your ViewHolder class and use it with an interface to determine the type of item which has been clicked.
For example, say you have a model class called Item :
public class Item {
private int itemType;
private String itemDescription;
private String optionalExtra;
public static final int ITEM_TYPE_1 = 1;
public static final int ITEM_TYPE_2 = 2;
public Item(int itemType, String itemDescription) {
this.itemType = itemType;
this.itemDescription = itemDescription;
}
public Item(int itemType, String itemDescription, String optionalExtra) {
this.itemType = itemType;
this.itemDescription = itemDescription;
this.optionalExtra = optionalExtra;
}
}
You have a custom interface defined to intercept click on items in recyclerview :
public interface CustomClickListener {
void onClickOfItemType1( int position );
void onClickOfItemType2( int position );
}
Inside your adapter for recyclerview, in the viewholder class :
//Similar implementation for other ViewHolders too.
public class ViewHolderType1 extends RecyclerView.ViewHolder implements View.OnClickListener {
ImageView imageView;
TextView textView;
View itemView;
public ViewHolderType1(View view) {
super(view);
this.itemView = view;
//initialize other views here
//Set item click listener on your view
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
int itemPosition = getAdapterPosition();
if( itemPosition != RecyclerView.NO_POSITION ) {
customClickListener.onClickOfItemType1(itemPosition);
//You can call onClickOfItemType2(itemPosition) in your other type of view holder class
}
}
}
In your Activity or Fragment :
Pass the customClickListener as a parameter to your adapeter :
CustomAdapter customAdapter = new CustomAdapter(List<Item> itemList, new CustomClickListener {
#Override
void onClickOfItemType1(int position) {
Item item = itemList.get(position);
//This item is of type 1
//You can implement serializable / parcelable in your item class and use it to directly pass across item to your activity
Intent intent = new Intent(Activity.this, CustomActivity1.class);
intent.putExtra("item", item);
startActivity(intent);
}
#Override
void onClickOfItemType2(int position) {
Item item = itemList.get(position);
//This item is of type 2
//You can implement serializable / parcelable in your item class and use it to directly pass across item to your activity
Intent intent = new Intent(Activity.this, CustomActivity2.class);
intent.putExtra("item", item);
startActivity(intent);
}
});
In case you are trying to trigger different activities on click of different views; inside your viewclicklistener implementation check the view id and trigger the corresponding activity.
#Override
public void onClick(View v) {
int itemPosition = getAdapterPosition();
if( itemPosition != RecyclerView.NO_POSITION ) {
switch(v.getId()) {
case R.id.imageView :
customClickListener.onClickOfItemType1(itemPosition);
break;
case R.id.textView :
customClickListener.onClickOfItemType2(itemPosition);
break;
}
}
}
This is a guide for usage of RecyclerView :
https://guides.codepath.com/android/using-the-recyclerview

how to change recyclerview item's layout from outside?

I have a RecyclerView, which has a Button and an EditText.
I have a Button outside of the RecyclerView. On click the outside Button, I want the Button in the RecyclerView toggles between hide and show.
How to do that?
I have tried to send a boolean parameter mEditFlag to the recyclerAdapter, toogle mEditFlag, and notify the adapter the data has changed. but it doesn't work.
mCurrentOrderRecyclerAdapter = new CurrentOrderRecyclerAdapter(this, mEditFlag);
rvOrder.setAdapter(mCurrentOrderRecyclerAdapter);
rlEditOrderList.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mEditFlag = !mEditFlag;
mCurrentOrderRecyclerAdapter.notifyDataSetChanged();
if (mEditFlag) {
ivEditOrderList.setImageResource(R.drawable.order_edit_true);
tvEditOrderList.setText(R.string.order_edit_flag_true);
} else {
ivEditOrderList.setImageResource(R.drawable.order_edit_false);
tvEditOrderList.setText(R.string.order_edit_flag_false);
}
}
});
#Override
public void onBindViewHolder(OrderRecyclerViewHolder holder, final int position) {
if(editFlag) {
holder.rlLeftItemRvOrder.setVisibility(View.VISIBLE);
} else {
holder.rlLeftItemRvOrder.setVisibility(View.GONE);
}
holder.tvNumItemRvOrder.setText(position + "x");
holder.tvDesItemRvOrder.setText("holder.ivFoodItemRvOrder.setImageResource(R.drawable.drawer_menu)");
holder.ivFoodItemRvOrder.setImageResource(R.drawable.drawer_menu);
}
You have to achieve it with your adapter layer.
The Button outside the RecyclerView has to update the item inside the adapter (for example a boolean).
Then notify the change to update (for example with the notifyItemChanged method) the RecyclerView
Somenthing like:
rlEditOrderList.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Update the item inside the adapter
MyObject obj = mAdapter.getItem(position);
obj.myBoolean= true;
mAdapter.notifyItemChanged(position);
}
});
with an adapter like:
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private ArrayList<MyObject> mDataset;
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
//Get the item in the adapter
MyObject obj = getItem(position);
if(obj.myBoolean)
holder.mButtonView.setVisibile(View.VISIBLE);
else
holder.mButtonView.setVisibile(View.GONE);
}
}

Categories

Resources