2015-11-06 11 views
8

Sto usando RecyclerView per elencare del testo e ora voglio farlo in modo che quando l'utente fa clic sul testo, viene visualizzata una finestra di dialogo di avviso personalizzata.Finestra di dialogo Avviso personalizzato con RecyclerView

Ho provato questo fino ad ora ma ottenere un NullPointerException; Cosa potrebbe essere sbagliato qui?

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


    } 
} 
} 
+0

Verificare se 'custom_dialog' di ID,' Text', 'image' e' dialogButtonOK' sono stati scritti correttamente –

+0

Sì, è esso mostra nullpointer e punta a questo come problema: finestra di Dialogo finale = nuova finestra di dialogo (contesto); –

+0

dov'è l'inizializzazione 'context'? – Emil

risposta

4

Nevermind ho dimenticato il mio contesto di inizializzazione

context = itemView.getContext();

3

Questa non è la risposta per la query, ma il modo migliore per gestire questo scenario.

Utilizzare metodi di richiamata.

nella vostra attività:

Ciò implementare l'interfaccia che abbiamo nel nostro Adapter. In questo esempio, verrà chiamato quando l'utente fa clic su un articolo nello 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); 
    } 
} 

l'adattatore:

In Attività, abbiamo avviato il nostro Adapter e superato questo come un argomento al costruttore. Questo avvierà la nostra interfaccia per il nostro metodo di callback. Puoi vedere che usiamo il nostro metodo di callback per i clic dell'utente.

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

cortesia:Call Activity method from adapter

2
final Dialog dialog = new Dialog(your_activity_context); 
0

Si utilizza context che è nullo così passare la context in ViewHolder costruttore e in CBAdapter costruttore similari come qui sotto:

public class CBAdapter extends RecyclerView.Adapter<CBAdapter.ViewHolder> { 

List<AdapterData> mItems; 
Context context; 

public CBAdapter(Context context) { 
    super(); 
    this.context = context; 
    ..... 
    } 

E in classe ViewHolder

class ViewHolder extends RecyclerView.ViewHolder{ 

    public TextView textOne; 
    private Context mcontext; 


    public ViewHolder(View itemView, Context mcontext) { 
     super(itemView); 
     this.mcontext = mcontext; 
     .... 
    } 
-2

Scrivi questo codice:

final Dialog dialog = new Dialog(CBAdapter.this); 

invece di

final Dialog dialog = new Dialog(context); 

(o)

context = CBAdapter.this; // Initialize context 

Spero che questo aiuti.

Felice Coding :)

+0

questo non fornisce una risposta alla domanda e la classe Adapter non può avere Contesto disponibile eccetto l'attività –

0

Non direttamente correlato alla domanda, sebbene ti prego: NON impostare onClickListener-s all'interno dell'adattatore!

questo è come dovrebbe essere fatto:

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 
     **/ 
    } 
} 

Speranza mie risposte aiuta qualcuno a scrivere un codice migliore :)

+0

Se sei così specifico su non impostare onClickListeners all'interno dell'adattatore, ti dispiacerebbe dirci perché è così, quindi possiamo tutti imparano dalle tue conoscenze? Inoltre, come avremmo due pulsanti che fanno cose diverse? – Timmiej93

Problemi correlati