How to Pass Position of RecyclerView to Activity? - android

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
}

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);

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

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);

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 edit and update Recyclerview item?

I'm building a to do app and I'm trying to add the edit function. When an item is clicked, it takes the user to EditItemActivity.java where the user can edit that particular to do. For example, it could be edited from "Do Homework" to "Go to the gym".
So far I've been able to get the item that was clicked and have its text display in the EditText field that will be used for the editing. However, I couldn't figure out how to save the edit when the button is clicked and go back to the main screen.
So in my adapter, I'm calling the intent with extra:
public class ToDoAdapter extends RecyclerView.Adapter<ToDoAdapter.ViewHolder> {
private List<ToDoData> toDoList;
private Context context;
public ToDoAdapter(List<ToDoData> todoList, Context context) {
this.toDoList = todoList;
this.context = context;
}
public ToDoAdapter(Context context){}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
TextView todoView;
public ViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
todoView = itemView.findViewById(R.id.to_do_display);
}
#Override
public void onClick(View view) {
Toast.makeText(context, "position = " + getAdapterPosition(), Toast.LENGTH_SHORT).show();
Intent intent = new Intent(context, EditItemActivity.class);
intent.putExtra("data", todoView.getText());
intent.putExtra("position", getAdapterPosition());
context.startActivity(intent);
}
}
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.to_do_list_item, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
ToDoData todoPosition = toDoList.get(position);
holder.todoView.setText(todoPosition.getToDo());
}
#Override
public int getItemCount() {
return (toDoList == null) ? 0 : toDoList.size();
}
}
And in my EditItemActivity.java, I'm retrieving the text and placing it in my EditText field:
public class EditItemActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit_item);
final ToDoData toDoData = new ToDoData(this);
final ToDoAdapter toDoAdapter = new ToDoAdapter(this);
final EditText editToDo = (EditText)findViewById(R.id.edit_todo_item);
Button button = (Button)findViewById(R.id.save_changes);
final String text = getIntent().getExtras().getString("data");
editToDo.setText(text);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(editToDo.getText().toString() != text){
toDoData.setToDo(editToDo.getText().toString());
toDoAdapter.notifyDataSetChanged();
finish();
}
}
});
}
}
But I don't know how to go further than this unfortunately.
what you will do is that :
1- send view position to edit activity
#Override
public void onClick(View view) {
Toast.makeText(context, "position = " + getAdapterPosition(), Toast.LENGTH_SHORT).show();
Intent intent = new Intent(context, EditItemActivity.class);
intent.putExtra("data", todoView.getText());
intent.putExtra("position", getAdapterPosition());
context.startActivity(intent);
}
2- in edit activity
final String position= getIntent().getExtras().getString("position");
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new intent(this, [PREVIOUS_ACTIVITY]);
intent.putExtra("new data", todoView.getText().toString());
intent.putExtra("position", position);
startActivity(intent);
}
});
4 - in activity which contains the adapter create hashmap hold the upcoming extras (position - text) as ( key - value )
HashMap<Integer, String> hashMap = new HashMap<>();
hashMap.put(position, newText);
5- then pass this hash map to your adapter class when you create its instance. and in onBindViewHolder() check the upcoming view position is contained in hashmap if yes set your new data
if(hashMap.containsKey(position))
view.todoView.setText(hashMap.get(position));

How to prevent Recycler view item from executing the same task twice

I have implemented an Recycler view with its item click inside the Holder class. Each item click opens a new activity. The problem is when user clicks an item twice in a fast tap (very quickly very less span of time), it opens the activity twice.
I can't try below solution:
android:launchMode="singleInstance" as I am using
startActivityForResult() to call the new activity.
android:launchMode="singleTask" is also not working.
How can it be stopped from happening? Please suggest.
Below is my adapter class:
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
RecyclerView.ViewHolder viewHolder = null;
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
switch (viewType) {
case MY_VIEW_TYPE:
View v1 = inflater.inflate(R.layout.created_by_me_item, parent, false);
viewHolder = new ViewHolderCreatedByMe(v1);
break;
}
return viewHolder;
}
#Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
if (holder instanceof ViewHolderCreatedByMe) {
// The data setting method is inside the Holder class
((ViewHolderCreatedByMe) holder).setDataCreatedByMe(mFeedRecordListData.get(position));
} else {
((ViewHolderFooter) holder).setFooterView();
}
}
And below is my holder class:
public class ViewHolderCreatedByMe extends RecyclerView.ViewHolder implements View.OnClickListener {
// ... some class members are declared here
public ViewHolderCreatedByMe(View itemView) {
super(itemView);
// a few more UI components are initialized here
rl_reaction_item_main_layout = (RelativeLayout) itemView.findViewById(R.id.rl_reaction_item_main_layout);
rl_reaction_item_main_layout.setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.rl_reaction_item_main_layout:
Intent intent = new Intent(mActivity, NewActivity.class);
intent.putExtra(NewActivity.KEY_EVENT_ID, UIModel.getEventID());
intent.putExtra(NewActivity.KEY_EVENT_TIME_STAMP, UIModel.getEventLocalTimeStamp());
intent.putExtra(NewActivity.KEY_EVENT_POSITION, getAdapterPosition());
mFragment.startActivityForResult(intent, Constants.REQUEST_CODE);
break;
}
}
you should use a boolean flag to check weather row item is clicked or not like this.
boolean isItemClicked = false;
private void onRecyclerViewItemClick()
{
if(!isItemClicked)
{
isItemClicked = true;
startActivity(new Intent(this, MyActivity.class));
}
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
isItemClicked = false;
}
*Note- I used name onRecyclerViewItemClick() for example here, it will be replaced with your listView's onItemClick
Create an interface to intercept click on the view of your recyclerview item.
For example :
public interface CustomClickListener {
void onClick(UIModel uiModel, int position);
}
Create a method in your adapter class to set the interface defined :
private CustomClickListener mCustomClickListener;
public void setClickListener( CustomClickListener customClickListener ) {
this.mCustomClickListener = customClickListener;
}
Modify your view holder class to this :
public class ViewHolderCreatedByMe extends RecyclerView.ViewHolder implements View.OnClickListener {
// ... some class members are declared here
public ViewHolderCreatedByMe(View itemView) {
super(itemView);
// a few more UI components are initialized here
rl_reaction_item_main_layout = (RelativeLayout) itemView.findViewById(R.id.rl_reaction_item_main_layout);
rl_reaction_item_main_layout.setOnClickListener(this);
}
#Override
public void onClick(View v) {
int position = getAdapterPosition();
if( position != RecyclerView.NO_POSITION && mCustomClickListener != null ) {
mCustomClickListener.onClick(UIModel, position);
}
}
In your fragment class, you would have your adapter defined, set the click listener here :
CustomClickListener customClickListener = new CustomClickListener() {
#Override
void onClick(UIModel uiModel, int position) {
Intent intent = new Intent(getActivity(), NewActivity.class);
intent.putExtra(NewActivity.KEY_EVENT_ID, uiModel.getEventID());
intent.putExtra(NewActivity.KEY_EVENT_TIME_STAMP, uiModel.getEventLocalTimeStamp());
intent.putExtra(NewActivity.KEY_EVENT_POSITION, position);
getActivity().startActivityForResult(intent, Constants.REQUEST_CODE);
adapter.setCustomClickListener(null); //To prevent the event being triggered twice
}
}
adapter.setCustomClickListener( customClickListener );
In your fragment where you have overriden onActivityResult, do this :
#Override
public void onActivityResult( int requestCode, int resultCode, Intent intent ) {
if( requestCode == Constants.REQUEST_CODE ) {
//Do something with the result
adapter.setCustomClickListener(customClickListener); // Make customClickListener a global variable
}
}
Hope this helps. Let me know if you've found a better way to tackle the problem if this doesn't suit your needs. The answer based out of boolean will work, but its a mess to track the boolean when you open and close the app.
Add these flag Intent.FLAG_ACTIVITY_SINGLE_TOP FLAG_ACTIVITY_NEW_TASK FLAG_ACTIVITY_RESET_TASK_IF_NEEDED FLAG_ACTIVITY_CLEAR_TOP
Your click event should look like this
case R.id.rl_reaction_item_main_layout:
Intent intent = new Intent(mActivity, NewActivity.class);
intent.putExtra(NewActivity.KEY_EVENT_ID, UIModel.getEventID());
intent.putExtra(NewActivity.KEY_EVENT_TIME_STAMP, UIModel.getEventLocalTimeStamp());
intent.putExtra(NewActivity.KEY_EVENT_POSITION, getAdapterPosition());
//add these following line
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
mFragment.startActivityForResult(intent, Constants.REQUEST_CODE);
break;

Categories

Resources