Close Dialog opened inside the Recyclerview Adapter

Asked

Viewed 88 times

1

I made a headline for my RecyclerView which, when clicked, opens a dialog. Some time later, started to give this error:

Activity com.mypkg.myP has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@44c46ff0 that was originally added here
05-17 18:24:57.069: ERROR/WindowManager(18850): android.view.WindowLeaked: Activity ccom.mypkg.myP has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@44c46ff0 that was originally added here
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.view.ViewRoot.<init>(ViewRoot.java:231)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)

Vi in this publication that this would be solved by closing Dialog at onPause or onDestroy.

How I do from inside the adapter?

Code that creates the Dialog in the Adapter:

  public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    if (holder instanceof VHHeader) {
        final VHHeader VHheader = (VHHeader) holder;

VHheader.enviardica.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                Dialog dpartilha = new Dialog(ctx);
                dpartilha.requestWindowFeature(Window.FEATURE_NO_TITLE);

                dpartilha.setContentView(R.layout.partilha);

                LinearLayout laydicas = (LinearLayout) dpartilha.findViewById(R.id.laydicas);
                LinearLayout layeventos = (LinearLayout) dpartilha.findViewById(R.id.layeventos);

                dpartilha.show();
            }
        });

1 answer

3


Do not create dialogues within others Views (such as the RecyclerView). Let the Activity take care to display this dialogue and dispense it when the time comes, while the RecyclerView just passes the message asking for dialogue to be created.

The standard way to do this without increasing the coupling is to create an interface to the Activity implement. An example:

Interface:

public interface ExibidorDeDialogoDePartilha {
    public void exibirDialogoDePartilha();
}

Activity:

public class MinhaActivity extends Activity implements ExibidorDeDialogoDePartilha {

    private AdapterDoMeuRecyclerView adapter;
    private Dialog dialogoDePartilha;

    @Override
    public void exibirDialogoDePartilha() {
       // Insira aqui o código de mostrar o diálogo
    }

    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        this.adapter = new AdapterDoMeuRecyclerView(this);
    }

    @Override
    protected void onDestroy() {
        // Exemplo de código que dispensa o diálogo. Adapte às suas necessidades.
        if (dialogoDePartilha != null && dialogoDePartilha.isShowing()) {
            dialogoDePartilha.dismiss();
        }
    }
}

Recyclerview:

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

    private ExibidorDeDialogoDePartilha exibidorDeDialogoDePartilha;

    public AdapterDoMeuRecyclerView(Context contexto) {
        try {
            this.exibidorDeDialogoDePartilha = (ExibidorDeDialogoDePartilha) contexto;
        } catch (ClassCastException e) {
            throw new ClassCastException("Activity ou Fragment que contém esse RecyclerView deve implementar ExibidorDeDialogoDePartilha.");
        }
    }

// .....

public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    if (holder instanceof VHHeader) {
        final VHHeader VHheader = (VHHeader) holder;

        VHheader.enviardica.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                exibidorDeDialogoDePartilha.exibirDialogoDePartilha();
            }
        });
  • Hi Pablo. Thank you so much. I tried to but I was left with a question - where to put the interface code? In Activity or below? Thank you!

  • The way I did, it would be separate, in a new Java file, but you can put it inside the file in which the Adapter is and take the "public" (that’s what I usually do).

  • You’ve seen Pablo, and one more thing. I’m doing pretty much everything on this adapter of mine. It’s from Recycler View of Mainactivity. This is for opening Intents too or this is fine?

  • From the point of view of the separation of responsibilities, maybe not ideal, but from the point of view of bugs, no problem, no.

  • Vi. Pablo tells me but one thing, as I’m starting Activity giving click on the viewholdrer of the adapter. Is there any way to give the Finish ?

  • Do you really need this Finish? Generally, it is not a good idea to end an activity by starting another one. If you think you really need it, do something similar to what you did to display the dialog (create an interface, implement the method in Activity etc.).

Show 1 more comment

Browser other questions tagged

You are not signed in. Login or sign up in order to post.