How to edit and update Recyclerview item? - android

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

Related

item.view on clickListener does not work with my viewholder

I've created an adapter for my Category gridview to show in my Main activity.
Categories are shown inside a CardView.
In order to click on each category, i can only access by the image or the text in the viewholder. that's not ideal, as you have to clicl exactly on the image to open new activity.
I would love to add the "itemview" to be able to click in any point of the cardview. I did it, but it does not work. I can only see the click but nothing happens.
Something like this:
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(context, categoryModel.getCatName(), Toast.LENGTH_SHORT).show();
}
});
My Adapter:
public class categoryCardViewAdpt extends RecyclerView.Adapter<categoryCardViewAdpt.ViewHolder> {
CategoryModel[] categoryModels;
Context context;
public categoryCardViewAdpt (CategoryModel[] categoryModels, MainActivity activity){
this.categoryModels = categoryModels;
this.context = activity;
}
public class ViewHolder extends RecyclerView.ViewHolder {
public ImageView catImageView;
public TextView catTv;
public ViewHolder(#NonNull View itemView) {
super(itemView);
catImageView = (ImageView) itemView.findViewById(R.id.category_img2);
catTv = (TextView) itemView.findViewById(R.id.category_name_2);
}
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view = layoutInflater.inflate(R.layout.card_view_layout,parent,false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
final CategoryModel categoryModel = categoryModels[position];
holder.catTv.setText(categoryModel.getCatName());
holder.catImageView.setImageResource(categoryModel.getCatImage());
holder.catImageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Toast.makeText(context, categoryModel.getCatName(), Toast.LENGTH_SHORT).show();
if (categoryModel.getCatName().equals(R.string.farina)){
Intent intent = new Intent(context, FarinaActivity.class);
context.startActivity(intent);
}
else if (categoryModel.getCatName().equals(R.string.farina_inverso)){
Intent intent = new Intent(context, FarinaInversoActivity.class);
context.startActivity(intent);
//overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left);
}
else if (categoryModel.getCatName().equals(R.string.alcol)){
Intent intent = new Intent(context, AlcolActivity.class);
context.startActivity(intent);
}
else if (categoryModel.getCatName().equals(R.string.panna)){
Intent intent = new Intent(context, PannaActivity.class);
context.startActivity(intent);
}
else if (categoryModel.getCatName().equals(R.string.chocolate)){
Intent intent = new Intent(context, ChocoActivity.class);
context.startActivity(intent);
}
}
});
}
#Override
public int getItemCount() {
return categoryModels.length;
}
}
your holder.catImageView is in your ItemView. so the click event may intercepted by ItemView.
Do not use holder.catImageView.setOnClickListener
use : holder.itemView.setonClickListener.

Null Listener in RecyclerView Adapter

Listener in Android Studio RecyclerView custom adapter is returning null.
This is the Interface
private OnItemClickListener mlistener;
public interface OnItemClickListener{
void onItemClick(int position, Boolean paid);
}
public void setOnItemClickListener(OnItemClickListener listener){
mlistener = listener;
}
And this is the View Holder with the Listener. This is intended to pass a Boolean to the main activity.
public CartViewHolder(View itemView, ArrayList<Shift> shifts, OnItemClickListener listener) {
super(itemView);
paid = itemView.findViewById(R.id.due_back_paid);
containerView = itemView.findViewById(R.id.container);
paid.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (listener != null){
int position = getAdapterPosition();
if(position != RecyclerView.NO_POSITION){
listener.onItemClick(position, isChecked);
}
}
}
});
containerView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Shift current = (Shift)containerView.getTag();
Intent intent = new Intent(v.getContext(), ViewShiftActivity.class);
intent.putExtra("thisShift", current);
intent.putExtra("shifts", shifts);
v.getContext().startActivity(intent);
}
});
}
}
public LoadAdapter(ArrayList<Shift> shifts){
shiftList = shifts;
}
#NonNull
#Override
public CartViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.shift_row, parent, false);
CartViewHolder mvh = new CartViewHolder(view, shiftList, mlistener);
return mvh;
}
I have used this code in other projects and it works. I have can't seem to figure out what I am missing.
I've been asked to include the activity. The following is this code.
I have not added any code to the onItemClick here yet. waiting for the listener to work.
public class EditShiftActivity extends AppCompatActivity implements LoadAdapter.OnItemClickListener{
private ArrayList<Shift> shifts;
private RecyclerView lRecyclerView;
private LoadAdapter lAdapter;
private RecyclerView.LayoutManager lLayoutManager;
private View view;
private FloatingActionButton fab;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit_shift);
Intent intent = getIntent();
shifts = intent.getParcelableArrayListExtra("shifts");
fab = findViewById(R.id.add_shift_edit);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent1 = new Intent(EditShiftActivity.this, AddShiftActivity.class);
intent1.putExtra("shifts", shifts);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
v.getContext().startActivity(intent1);
}
});
lRecyclerView = findViewById(R.id.shift_recycler);
lLayoutManager = new LinearLayoutManager(this);
lAdapter = new LoadAdapter(shifts);
lRecyclerView.setLayoutManager(lLayoutManager);
lRecyclerView.setAdapter(lAdapter);
}
#Override
public void onItemClick(int position, Boolean paid) {
}
}
Add below line in your code -
lAdapter = new LoadAdapter(shifts);
lAdapter.setOnItemClickListener(this);
You are retrieving the ArrayList<Shifts> from Intent. Check the size of shifts arraylist before sending to the Adapter. There is a chance that if the arraylist passed is empty then the adapter will return null and hence lRecyclerView will not be displayed.
Add this condition before passing data to adapter
//condition to check whether the arraylist is empty or not
if(!shifts.isEmpty()) {
lAdapter = new LoadAdapter(shifts);
//initialising the adapter
lRecyclerView.setAdapter(lAdapter);
}

I am failing to make a succesful indent from adapter

I am setting this adapter for an RecyclerView, I am failing to make an indent from that adapter I don't know why can some body guide me what is going on here because I am not an expert in programming as well in this android.
Below is my Adapter class and Activity class.
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private String[] mDatasetname;
private Integer[] mexp;
private Context context;
public ToggleButton select;
Integer selectedcountint=0;
private Bitmap[] mpro;
private String[] mloc;
private String[] mobj;Context m;
private String[] mselected;
public ArrayList<String> nselected = new ArrayList<>();
public static class MyViewHolder extends RecyclerView.ViewHolder{
public CardView mCardView;
public TextView mTextView;
public TextView texp;
public Button pdf;
public ToggleButton select;
public ImageView pro;
public TextView loc;
public View layout;
Context context;
private RecyclerView.ViewHolder s;
public MyViewHolder(View v){
super(v);
mCardView = (CardView) v.findViewById(R.id.card_view);
mTextView = (TextView) v.findViewById(R.id.tv_text);
texp = (TextView) v.findViewById(R.id.setexp);
pdf = (Button) v.findViewById(R.id.moreinfo);
select = (ToggleButton) v.findViewById(R.id.select);
pro = (ImageView) v.findViewById(R.id.setpropic);
loc = (TextView) v.findViewById(R.id.setlocation);
}
void bind(String name, Integer exp, String location, final Bitmap image, final String obj ) {
mTextView.setText(name);
texp.setText(String.valueOf(exp)+" yrs");
pro.setImageBitmap(image);
loc.setText(location);
pdf.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(Dashboard.this, com.parse.starter.View.class);
intent.putExtra("no", "6382551203");
startActivity(intent);
}
});
}
}
public MyAdapter(Context s,String[] myDataset,Integer[] exp,Bitmap[] pro,String[] loc,String[] obj){
mDatasetname = myDataset;
mexp=exp;
mpro=pro;
mloc=loc;
mobj=obj;
m=s;
}
#Override
public MyAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
context=parent.getContext();
View vs = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_item, parent, false);
MyViewHolder vh = new MyViewHolder(vs);
return vh;
}
#Override
public void onBindViewHolder(final MyViewHolder holder, final int position){
holder.bind(mDatasetname[position],mexp[position],mloc[position],mpro[position],mobj[position]);
}
#Override
public int getItemCount() { return mDatasetname.length; }
}
Solution:
Instead of this:
Intent intent = new Intent(Dashboard.this, com.parse.starter.View.class);
intent.putExtra("no", "6382551203");
startActivity(intent);
Write like this:
Intent intent = new Intent(Dashboard.this, (your_destination_class_name).class);
intent.putExtra("no", "6382551203");
startActivity(intent);
For Example:
Intent intent = new Intent(Dashboard.this, RegisterActivity.class);
intent.putExtra("no", "6382551203");
startActivity(intent);
If you're destination class name is View.class then change it to something else.
If the above method doesn't work,
Replace:
View vs = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_item, parent, false);
with:
View vs = LayoutInflater.from(m).inflate(R.layout.card_item, parent, false);
and try. Hope it works.
first make constructor, adapter wont work with out constructor, its a big miss please check
holder.pdf.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(context,YourIndentClassName.class);
intent.putExtra("no", "6382551203");
context.startActivity(intent);
}
});
Edit your code with this:
pdf.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(context, com.parse.starter.View.class/*should be a proper class name*/);
intent.putExtra("no", "6382551203");
context.startActivity(intent);
}
});
holder.pdf.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(context,YourIndentClassName.class);
intent.putExtra("no", "6382551203");
context.startActivity(intent);
}
});
strong text
use this code in your onBindViewHolder method of RecyclerVieAdapter

Recyclerview Onclick passing specific data when click cardview into activity

What I'm trying to do is to pass a data from a specific user into another activity using it's userID as unique ID
It keeps send the same data into the other activity, I dont know how to do it
This is code is for the Fragment_Home where I use to get data from Firebase and populate it into the RecyclerView, and where the Onclick is in at the moment.
public class FragmentRO_Home extends Fragment {
private Intent intent;
private DatabaseReference database;
RecyclerView recyclerView;
Recycler_View_Adapter adapter;
TextView TV_nodata;
private String uid;
private String nombre;
public FragmentRO_Home() {
// Required empty public constructor qwe
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_fragment_ro__home,container,false);
database = FirebaseDatabase.getInstance().getReference();
final List<Data> data = new ArrayList();
TV_nodata = (TextView)view.findViewById(R.id.TV_result);
recyclerView = (RecyclerView) view.findViewById(R.id.recyclerview);
adapter = new Recycler_View_Adapter(data, getActivity());
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
fill_with_data();
This is the onclick which I'm using with recyclerview and it's functionable.
recyclerView.addOnItemTouchListener(new CustomRVItemTouchListener(getActivity(), recyclerView, new RecyclerViewItemClickListener() {
#Override
public void onClick(View view, int position) {
if (position == 0){
intent = new Intent(getActivity(), ReportInformation.class);
intent.putExtra("idData",uid);
startActivity(intent);
}else if (position == 1){
intent = new Intent(getActivity(), ReportInformation.class);
intent.putExtra("idData",uid);
startActivity(intent);
}else if (position == 2){
intent = new Intent(getActivity(), ReportInformation.class);
intent.putExtra("idData",uid);
startActivity(intent);
}else if (position == 3){
intent = new Intent(getActivity(), ReportInformation.class);
intent.putExtra("idData",uid);
startActivity(intent);
}else if (position == 5){
intent = new Intent(getActivity(), ReportInformation.class);
intent.putExtra("idData",uid);
startActivity(intent);
}
}
#Override
public void onLongClick(View view, int position) {
}
}));
return view;
}
This is the method to where I populated my recyclerview from getting data's in the firebase.
public void fill_with_data() {
database.child("data_home").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot d) {
if (d.exists()) {
List<Data> list = new ArrayList<>();
for (DataSnapshot dataw : d.getChildren()) {
Data data = dataw.getValue(Data.class);
list.add(data);
uid = (data.usirayd);
nombre = (data.title);
}
for (Data data : list) {
adapter.insert(new Data(data.title, data.description, data.condition, data.time,data.usirayd));
}
}else {
TV_nodata.setVisibility(View.VISIBLE);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
recyclerView.setAdapter(adapter);
}
Try this code
recyclerView.addOnItemTouchListener(new CustomRVItemTouchListener(getActivity(), recyclerView, new RecyclerViewItemClickListener() {
#Override
public void onClick(View view, int position) {
if(data.size()>position){
if (data.get(position)!= null){
intent = new Intent(getActivity(), ReportInformation.class);
intent.putExtra("idData",data.get(position).usirayd);
startActivity(intent);
}
}
}
#Override
public void onLongClick(View view, int position) {
}
}));
return view;
}
Your list is of Data type so what you need to do is make Data class parcleable and then get object form the clicked position and send it to activity.
Sample code is something like this
public void onClick(View view, int position) {
Data dataObject = list.get(position);
intent = new Intent(getActivity(), ReportInformation.class);
intent.putExtra("idData",uid);
intent.putExtra("Data",dataObject);
startActivity(intent);
}
If you want to send single id of clicked position then just get Id from list object and send like this
uid= list.get(postion).getUserId;
and send it in intent
and in other class/activity receice that parcelable object like this
Data dataObjectReceived = getIntent().getExtras().getParcelable("Data");
and if you want to get single entity then get it by its key
When clicking on the cardView you want to pass the data into your activity or fragment for that you need to make one interface for example in my case may use one FriendModel
Interface
public interface OnFriendListClickListener {
void onItemClick(FriendModel model, int position);
}
Activity
public class FriendListActivity extends AppCompactActivity
implements
OnFriendListClickListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.activity_friend);
//...
rvRemoveFriendList.setAdapter(new FriendListAdapter(context, list, this));
}
#Override
public void onItemClick(FriendModel model, int position) {
//your code here
}
}
Adapter
public class FriendListAdapter extends RecyclerView.Adapter<FriendListAdapter.FriendListHolder> {
private List<FriendModel> friendList;
private Context context;
private OnFriendListClickListener listener;
public FriendListAdapter(Context context,
List<FriendModel> friendList,
OnFriendListClickListener listener,) {
this.context = context;
this.friendList = friendList;
this.listener = listener;
}
#Override
public FriendListHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new FriendListHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.row_friend, parent, false));
}
#Override
public void onBindViewHolder(final FriendListHolder holder, int position) {
holder.tvFriendNumber.setText(friendList.get(position).getFriendMobile());
holder.llFriendListItem.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
listener.onItemClick(friendList.get(holder.getAdapterPosition()),
holder.getAdapterPosition());
}
});
}
//......
}

Trouble with intent in RecyclerView

I started in the android programming and and I encountered a problem when i tried to send data from my Adapter to an another activity
.
I want to show the content of "description" in my other activity when I click on an item.
MyAdapter class :
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private final List<FakeNews> list = FakeNewsList.all;
#Override
public int getItemCount() {
return list.size();
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = inflater.inflate(R.layout.list_cell, parent, false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
FakeNews pair = list.get(position);
holder.display(pair);
}
public class MyViewHolder extends RecyclerView.ViewHolder {
private final TextView name;
private final TextView description;
private FakeNews currentPair;
public MyViewHolder(final View itemView) {
super(itemView);
name = ((TextView) itemView.findViewById(R.id.name));
description = ((TextView) itemView.findViewById(R.id.description));
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MyViewHolder.this ,Affich.class);
intent.putExtra("description", String.valueOf((description)));
startActivity(intent);
}
});
}
public void display(FakeNews pair) {
currentPair = pair;
name.setText(pair.title);
}
}
}
Can someone help me?
I assume that you do not really want to pass the TextView to your next activity, but the content which is shown in it. Also, you need to pass a Context to the Intent and startActivity() is a method of an activity, so you need to call it on the context:
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(view.getContext() ,Affich.class);
intent.putExtra("description", description.getText().toString());
view.getContext().startActivity(intent);
}
});
Pass the Context or Activity instance into your adapter class.
then while starting new Activity and suppose instance variable is mContext use like this-
Intent intent = new Intent(mContext ,Affich.class);
intent.putExtra("description", String.valueOf((description)));
mContext.startActivity(intent);
To pass value from TextView to your new activity, do this:
intent.putExtra("description", description.getText().toString());
on your new activity, get the description value using:
String descriptionValue = getIntent().getStringExtra("description");

Categories

Resources