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:
- ¿Cómo manejar los contadores de cuenta regresiva múltiples en RecyclerView?
- Cómo refundir elementos en un RecyclerView con el StaggeredGridLayoutManager
- RecyclerView refresca los elementos sólo cuando se desplaza hacia abajo y hacia arriba
- Quitar todos los artículos de RecyclerView
- Cómo importar RecyclerView para Android L-preview
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
Actualizar
Salida ahora:
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)
- Agregue RecyclerView (RecyclerFragment) a un cuadro de diálogo
- RecyclerView: Inconsistencia detectada. Posición de artículo no válida
- Datos de SQLite a un RecyclerView
- RecyclerView: obtenga todas las vistas / presentaciones existentes
- v7 RecyclerView NullPointerException AccessibilityDelegateCompat.getBridge ()
- La transición de elementos compartidos no tiene el comportamiento esperado
- RecyclerView: ¿Cómo simular el selector de dibujo de ListView en la parte superior?
- Deslizar un elemento a la vez
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í:
-
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()); } } }
-
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(); } }
-
Ahora el oyente del tecleo excepto cualquier estado y excepto en valor boolean en mi archivo de JSON como abajo:
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) { } }
- Tener problemas de Android con jarras javax de Sun
- Cómo obtener distancia entre dos puntos en Android?