Múltiples elementos seleccionados RecyclerView in Activity.java

Tengo un RecyclerView con datos de JSON local en CardView . Tengo que implementar en los elementos seleccionados cuando uno o algún elemento pulsado (cambiar el fondo del elemento seleccionado o resaltar) (como editar en la aplicación de línea), pero sin botón o longpress . Pero no quiero usar StateListDrawable o (usando XML) porque tengo algunos datos de JSON que necesitan procesar más adelante.

Necesito un estado en mi actividad como un valor booleano o algo para guardar cada elemento que he hecho clic pero no tengo ninguna solución de nuevo. He leído e intento algunos tutoriales pero no funciona. Esto está debajo de mi Actividad ahora:

 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 }, ............ 

Esta es mi actividad parece

Introduzca aquí la descripción de la imagen

Actualizar

Salida ahora:

Introduzca aquí la descripción de la imagen

Ahora se destacan cuando hago clic en el elemento (Gracias a @Burhanuddin Rashid), pero su todavía la mitad de mi caso. Sólo puedo seleccionar un elemento (no puedo seleccionar varios elementos / más). Necesito desmarcar de nuevo cuando hago clic en el elemento resaltado.

EDITADO: Trato de escribir nuevo objeto y llave en mi JSON (código JSON arriba). En mi lógica, hará que una bandera para cada artículo sea seleccionada o no, pero todavía no trabaja.

EDITADO: este es mi error de registro:

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

Puede aplicar setOnClickListener de esta manera: –

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

Prueba esto:

OnBindViewHolder:

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

Y esto en ViewHolder :

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

Crear lastCheckedPosition como variable global

Seguir a continuación Código:

Ponga este código en su onBindViewHolder() .

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

En su Actividad:

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

Yo totalmente cambiar mi código, pero su trabajo ahora poderosamente, aquí mi código se ve así:

  1. Cambio mi Adapter en el adaptador genérico. No procesa ningún dato, sino su tiro a mi actividad.

     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()); } } } 
  2. Y Mi Activity llega a ser así:

     /*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(); } } 
  3. Ahora el oyente del tecleo excepto cualquier estado y excepto en valor boolean en mi archivo de JSON como abajo:

Multple Selecion

El estado de clic guardado en valor booleano en JSON

Gracias a todos con sugerencia y gran respuesta 🙂

Intente abajo el código

Dentro

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

Poner

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

Y crea esta clase donde quieras

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

He leído antes que hay una mejor manera pero me gusta esta manera es fácil y no complicado.

Todo lo anterior es muy buena respuesta, pero estoy seguro de que va a elegir este que le da más flexibilidad que otros

  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) { } } 
  • Diseño cuadrado en GridLayoutManager para RecyclerView
  • ¿Cómo centrar los elementos de una revista de reciclaje?
  • No se puede escribir un algoritmo para filtrar elementos en un RecyclerView basado en un tiempo guardado con cada elemento
  • Navegación (Siguiente) con EditText en un ListView / RecyclerView
  • TableLayout Vs Recycler Ver?
  • RecyclerView GridLayoutManager con el encabezado de ancho completo
  • ScrollBy no funciona correctamente en recyclerview anidado
  • Cómo abrir un fragmento diferente en recyclerview OnClick
  • RecyclerView ItemTouchHelper borrar eliminar animación
  • Cómo implementar correctamente un adaptador para un ListView
  • Android Cómo reciclar el mapa de bits correctamente cuando se utiliza RecyclerView?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.