Multiple selected RecyclerView elements in Activity.java

I have a RecyclerView with data from local JSON in CardView . I need to implement on selected elements when one or some element is clicked (change the background to the selected or selected element) (for example, edit the Line application in the application), but without a button or longpress . But I do not want to use StateListDrawable or (using XML) because I have some JSON data that needs to be processed later.

I need a state in my activity as a logical value or something to save every element that I clicked, but I have no solution again. I read and tried the tutorial, but it does not work. Now it is below my activity:

 adapter.setOnRecyclerViewClickedListener(new Adapter.OnRecyclerViewItemClickedListener() { @Override public void OnRecyclerViewItemClicked(int position) { boolean selectedItem = false; adapter.setOnRecyclerViewClickedListener(new Adapter.OnRecyclerViewItemClickedListener() { @Override public void OnRecyclerViewItemClicked(int position) { /* ------ boolean variabel for adapter but still not work ----- */ JSONObject filteredtableList= null; try { filteredtableList= new JSONObject("response").getJSONObject("tTisch"); } catch (JSONException e) { e.printStackTrace(); } if (recyclerView == null) { try { filteredtableList.has("true"); filteredtableList.put(status, true); } catch (JSONException e) { e.printStackTrace(); } } else { try { filteredtableList.put(status, true); } catch (JSONException e) { e.printStackTrace(); } } adapter.updateData(filteredTableList); //---------------------------------------------------- try { Toast.makeText(TableActivity.this, filteredTableList.getJSONObject(position).getString("tischnr"), Toast.LENGTH_SHORT).show(); } catch (JSONException e) { e.printStackTrace(); } } }); 

Adapter.java

 public int lastCheckedPosition = -1; ......... ......... ......... @Override public void onBindViewHolder(ViewHolder holder, int position) { if (position == lastCheckedPosition) { holder.itemView.setBackgroundResource(R.color.colorRedTableOcc); } else { holder.itemView.setBackgroundResource(R.color.colorTableGreen); } try { currItem = list.getJSONObject(position); holder.txt_no_table.setText(currItem.getString("tischnr")); } catch (JSONException e) { e.printStackTrace(); } } @Override public int getItemCount() { return list.length(); } public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { public TextView txt_no_table; public ViewHolder(View itemView) { super(itemView); itemView.setOnClickListener(this); txt_no_table = (TextView) itemView.findViewById(R.id.txt_no_table_empty); } @Override public void onClick(View itemView) { recyclerViewItemClickedListener.OnRecyclerViewItemClicked(getAdapterPosition()); lastCheckedPosition = getAdapterPosition(); notifyItemRangeChanged(0,list.length()); } } 

Json.json

 .............. "t-tisch": [ { "tischnr": 1, "departement": 1, "normalbeleg": 0, "kellner-nr": 0, "bezeich": "TABLE 01", "roomcharge": false, "betriebsnr": 0 }, { "tischnr": 2, "departement": 1, "normalbeleg": 0, "kellner-nr": 0, "bezeich": "TABLE 02", "roomcharge": false, "betriebsnr": 0 }, ............ 

This my activity looks like

enter image description here

Update

Output:

enter image description here

Now it stands out when I click on an item (thanks @Burhanuddin Rashid), but its still half for my business. I can select only one item (I cannot select multiple / multiple items). I need to deselect again when I click on the highlighted item.

EDITED: I'm trying to write a new object and key in my JSON (JSON code above). In my logic, it will make the flag for each element selected or not, but it still does not work.

EDITED: this is my log error:

  --------- beginning of crash E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.development_laptop.vhp_restotemp, PID: 3590 java.lang.NullPointerException: Attempt to invoke virtual method 'org.json.JSONObject org.json.JSONObject.put(java.lang.String, boolean)' on a null object reference at com.example.development_laptop.vhp_restotemp.TableActivity$1.OnRecyclerViewItemClicked(TableActivity.java:74) at com.example.development_laptop.vhp_restotemp.com.example.development_laptop.vhp_restotemp.recyclerview.source.Adapter$ViewHolder.onClick(Adapter.java:97) at android.view.View.performClick(View.java:5198) at android.view.View$PerformClick.run(View.java:21147) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5417) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
+6
source share
6 answers

I am completely changing my code, but now it works powerfully, here my code looks like this:

  • I am changing my Adapter to a universal adapter. It is not processed by any data, but it is thrown into my work.

     public class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> { public int lastCheckedPosition = -1; private static OnRecyclerViewItemClickedListener recyclerViewItemClickedListener; public void setOnRecyclerViewClickedListener (OnRecyclerViewItemClickedListener l) { recyclerViewItemClickedListener = l; } public interface OnRecyclerViewItemClickedListener { void OnRecyclerViewItemClicked(int position); void OnRecyclerViewItemBind(ViewHolder holder, int position); int OnRecyclerViewItemCount(); } public Adapter() { super(); } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.table_item_empty, parent, false); return new ViewHolder(v); } @Override public void onBindViewHolder(ViewHolder holder, int position) { recyclerViewItemClickedListener.OnRecyclerViewItemBind(holder,position); } @Override public int getItemCount() { return recyclerViewItemClickedListener.OnRecyclerViewItemCount(); } public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { public TextView txt_no_table; public ViewHolder(View itemView) { super(itemView); itemView.setOnClickListener(this); txt_no_table = (TextView) itemView.findViewById(R.id.txt_no_table_empty); } @Override public void onClick(View itemView) { recyclerViewItemClickedListener.OnRecyclerViewItemClicked(getAdapterPosition()); } } } 
  • And My Activity will look like this:

     /*Add Click Listener*/ adapter.setOnRecyclerViewClickedListener(new Adapter.OnRecyclerViewItemClickedListener() { @Override public void OnRecyclerViewItemClicked(int position) { try { JSONObject currTable = filteredTableList.getJSONObject(position); if (currTable.has("selected")) { currTable.put("selected", !currTable.getBoolean("selected")); } else { currTable.put("selected",true); } adapter.notifyItemChanged(position); } catch (JSONException e) { e.printStackTrace(); } try { Toast.makeText(TableActivity.this, filteredTableList.getJSONObject(position).getString("tischnr"), Toast.LENGTH_SHORT).show(); } catch (JSONException e) { e.printStackTrace(); } } @Override public void OnRecyclerViewItemBind(Adapter.ViewHolder holder, int position) { try { JSONObject currTable = filteredTableList.getJSONObject(position); holder.txt_no_table.setText(currTable.getString("tischnr")); int queasy33Index = ProgramMethod.getJSONArrayIndex(queasy33List,"number2", currTable.getInt("tischnr")); if (queasy33Index >= 0) { holder.txt_no_table.setText(holder.txt_no_table.getText() + "-" + queasy33List.getJSONObject(queasy33Index).getString("key")); } if (currTable.has("selected") && currTable.getBoolean("selected")) { holder.itemView.setBackgroundResource(R.color.colorRedTableOcc); } else { holder.itemView.setBackgroundResource(R.color.colorTableGreen); } } catch (JSONException e) { e.printStackTrace(); } } 
  • Now the click listener will save any state and save to a boolean value in my JSON file, as shown below:

Multiple selecion

Click state stored in a boolean value in JSON

Thanks to everyone who offers and a great answer :)

+1
source

You can apply setOnClickListener as follows: -

 View itemView; Context context; @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { itemView = LayoutInflater.from(parent.getContext()) .inflate(R.layout.card_view, parent, false); this.context=parent.getContext(); return new ViewHolder(itemView); } @Override public void onBindViewHolder(final ViewHolder holder, int position) { holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { holder.linearLayout.setBackgroundColor(context.getResources().getColor(R.color.colorAccent,null)); } else { holder.linearLayout.setBackgroundColor(context.getResources().getColor(R.color.colorAccent)); } } }); } 
+3
source

Try the following:

onBindViewHolder:

 if (position == lastCheckedPosition) { holder.itemView.setBackgroundResource(R.drawable.ic_item_selection_background); } else { holder.itemView.setBackgroundResource(R.drawable.ic_item_deselection_background)); } 

And this is on ViewHolder :

  itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { lastCheckedPosition = getAdapterPosition(); notifyItemRangeChanged(0,getItemCount()); } }); 

Create lastCheckedPosition as a global variable

+3
source

Follow below:

Put this code in your onBindViewHolder() method.

  @Override public void onBindViewHolder(final ViewHolder holder, final int position) { final DataModel dataModel = arraylist.get(position); final boolean isSelected = dataModel.isSelected(); if (isSelected) { llParentLayout.setBackgroundColor(Color.Black); } else { llParentLayout.setBackgroundColor(Color.Green); } } public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { public TextView txt_no_table; public ViewHolder(View itemView) { super(itemView); itemView.setOnClickListener(this); txt_no_table = (TextView) itemView.findViewById(R.id.txt_no_table_empty); } @Override public void onClick(View itemView) { final DataModel dataModel = arraylist.get(getAdapterPosition()); recyclerViewItemClickedListener.OnRecyclerViewItemClicked(dataModel); } } 

In your activity:

 adapter.setOnRecyclerViewClickedListener(new Adapter.OnRecyclerViewItemClickedListener() { @Override public void OnRecyclerViewItemClicked(DataModel dataModel) { dataModel.setSelected(!dataModel.isSelected()); adapter.notifyDataSetChanged(); } }); 
+2
source

Try entering the code

Inside

 public Adapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) 

Placed

 View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.view_image_and_text, parent, false); v.setOnClickListener(new MyOnClickListener()); 

And create this class wherever you want.

 class MyOnClickListener implements View.OnClickListener { @Override public void onClick(View v) { int itemPosition = recyclerView.indexOfChild(v); Log.e("Clicked and Position is ",String.valueOf(itemPosition)); } } 

I read before that there is a better way, but I like that it is easy and not difficult.

0
source

All of the above is a very good answer, but I'm sure that choosing this one gives you more flexibility than others.

  recyclerView.addOnItemTouchListener(new RecyclerTouchListener(getActivity(), recyclerView, new SideMenuClickListener() { @Override public void onClick(View view, int position) { } @Override public void onLongClick(View view, int position) { } })); static class RecyclerTouchListener implements RecyclerView.OnItemTouchListener { private GestureDetector gestureDetector; private SideMenuClickListener clickListener; public RecyclerTouchListener(Context context, final RecyclerView recyclerView, final SideMenuClickListener clickListener) { this.clickListener = clickListener; gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() { @Override public boolean onSingleTapUp(MotionEvent e) { return true; } @Override public void onLongPress(MotionEvent e) { View child = recyclerView.findChildViewUnder(e.getX(), e.getY()); if (child != null && clickListener != null) { clickListener.onLongClick(child, recyclerView.getChildPosition(child)); } } }); } @Override public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) { View child = rv.findChildViewUnder(e.getX(), e.getY()); if (child != null && clickListener != null && gestureDetector.onTouchEvent(e)) { clickListener.onClick(child, rv.getChildPosition(child)); } return false; } @Override public void onTouchEvent(RecyclerView rv, MotionEvent e) { } @Override public void onRequestDisallowInterceptTouchEvent(boolean b) { } } 
0
source

Source: https://habr.com/ru/post/1013320/


All Articles