Diálogo de alerta personalizado con RecyclerView
Estoy usando RecyclerView
para listar algún texto y ahora quiero hacerlo de manera que cuando el usuario haga clic en el texto, aparezca un cuadro de diálogo de alerta personalizado.
He intentado esto hasta ahora, pero obtener una NullPointerException; ¿Qué podría estar mal aquí?
- ¿Es posible arrastrar el elemento fuera de RecyclerView?
- Recycler View con múltiples filas y columnas - AutoFit como Flow Layout
- La vista en RecyclerView no coincide con el ancho de los padres
- Recycler View Con Gridlayout Manager
- Barra de herramientas que no se muestra con desplazamiento para actualizar
public class CBAdapter extends RecyclerView.Adapter<CBAdapter.ViewHolder> { List<AdapterData> mItems; public CBAdapter() { super(); mItems = new ArrayList<>(); AdapterData data = new AdapterData(); data.setTextOne("Many Bows"); mItems.add(data); data = new AdapterData(); data.setTextOne("Pardon"); mItems.add(data); data = new AdapterData(); data.setTextOne("Fall To Knees & Beg"); mItems.add(data); data = new AdapterData(); data.setTextOne("Backflips"); mItems.add(data); } @Override public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { View v = LayoutInflater.from(viewGroup.getContext()) .inflate(R.layout.test3, viewGroup, false); return new ViewHolder(v); } @Override public void onBindViewHolder(ViewHolder viewHolder, int i) { AdapterData data = mItems.get(i); viewHolder.textOne.setText(data.getTextOne()); } @Override public int getItemCount() { return mItems.size(); } class ViewHolder extends RecyclerView.ViewHolder{ public TextView textOne; private Context context; public ViewHolder(View itemView) { super(itemView); textOne = (TextView)itemView.findViewById(R.id.textView1); itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { final Dialog dialog = new Dialog(context); dialog.setContentView(R.layout.custom_dialog); dialog.setTitle("Title"); TextView text = (TextView) dialog.findViewById(R.id.text); text.setText("hello world"); ImageView image = (ImageView) dialog.findViewById(R.id.image); image.setImageResource(R.drawable.ic_launcher); Button dialogButton = (Button) dialog.findViewById(R.id.dialogButtonOK); dialogButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { dialog.dismiss(); } }); dialog.show(); } }); } } }
- Escaneando con múltiples RecyclerViews en Layout
- Establecer contentInset en RecyclerView
- Color de la barra de desplazamiento en RecyclerView
- ¿Cuál es la mejor manera de hacer el elemento superpuesto en RecyclerView?
- Cómo utilizar Recyclerview dentro de Scrollview
- Cómo (y dónde) fijar android.os.BadParcelableException: ClassNotFoundException cuando unmarshalling: RecyclerView $ SavedState?
- NestedScrollview no comenzará desde arriba
- Utilice ItemTouchHelper para deslizar-a-despedir con otra vista que se muestra detrás del barrido hacia fuera
Esta no es la respuesta para su consulta, pero la mejor manera de manejar este escenario.
Utilice métodos de devolución de llamada.
En su Actividad:
Esto implementará la interfaz que tenemos en nuestro Adapter
. En este ejemplo, se llamará cuando el usuario haga clic en un elemento de la RecyclerView
.
public class MyActivity extends Activity implements AdapterCallback { private MyAdapter mMyAdapter; @Override public void onMethodCallback() { // Show your alert } @Override protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.mMyAdapter = new MyAdapter(this); } }
En su adaptador:
En la actividad, iniciamos nuestro Adapter
y lo pasamos como argumento al constructor. Esto iniciará nuestra interfaz para nuestro método de devolución de llamada. Puede ver que utilizamos nuestro método de devolución de llamada para los clics del usuario.
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> { private AdapterCallback mAdapterCallback; public MyAdapter(Context context) { try { this.mAdapterCallback = ((AdapterCallback) context); } catch (ClassCastException e) { throw new ClassCastException("Activity must implement AdapterCallback."); } } @Override public void onBindViewHolder(final MyAdapter.ViewHolder viewHolder, final int i) { // simple example, call interface here // not complete viewHolder.itemView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { try { mAdapterCallback.onMethodCallback(); } catch (ClassCastException exception) { // do something } } }); } public static interface AdapterCallback { void onMethodCallback(); } }
Cortesía: método Call Activity del adaptador
final Dialog dialog = new Dialog(your_activity_context);
Olvidé la inicialización de mi contexto
Context = itemView.getContext ();
Usted está utilizando el context
que es nulo así pasar el context
en el constructor de ViewHolder
y en el constructor de CBAdapter también como como abajo:
public class CBAdapter extends RecyclerView.Adapter<CBAdapter.ViewHolder> { List<AdapterData> mItems; Context context; public CBAdapter(Context context) { super(); this.context = context; ..... }
Y en la clase ViewHolder
class ViewHolder extends RecyclerView.ViewHolder{ public TextView textOne; private Context mcontext; public ViewHolder(View itemView, Context mcontext) { super(itemView); this.mcontext = mcontext; .... }
No está directamente relacionado con la pregunta, aunque te ruego: NO establezca onClickListener-s dentro del adaptador!
Asi es como debería de hacerse:
private class ItemDataHolder extends RecyclerView.ViewHolder implements View.OnLongClickListener{ private final String TAG = ItemDataHolder.class.getSimpleName(); /** * Define view's elements */ /** * Define object instance */ private Item mData; // Constructor public MessageDataHolder(View itemView) { super(itemView); /** * Init elements */ itemView.setOnLongClickListener(this); } /** * Method to handle long click on the item * @param v View to handle click on * @return */ @Override public boolean onLongClick(View v) { Log.v(TAG, "Long click fired!"); return false; } /** * Function to update view's elements * @param message Good data to be updated to */ public void bindData(Item message) { mData = message; /** * Set values of views here **/ } }
Espero que mis respuestas ayuden a alguien a escribir un código mejor 🙂
Escribe este código:
final Dialog dialog = new Dialog(CBAdapter.this);
en lugar de
final Dialog dialog = new Dialog(context);
(o)
context = CBAdapter.this; // Initialize context
Espero que esto ayude.
Codificación feliz
- ¿Cuál es mejor para redirigir, resolución de pantalla o agente de usuario?
- ¿Necesito mostrar la licencia de apache en mi aplicación cuando utilizo phonegap?