Search code examples
javaandroidandroid-recyclerviewandroid-alertdialog

Custom AlertDialog with RecyclerView - list is always empty


First, I created activity with RecyclerView, it works fine. My original code:

activity_agreements.xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
                                             xmlns:app="http://schemas.android.com/apk/res-auto"
                                             xmlns:tools="http://schemas.android.com/tools"
                                             android:id="@+id/linearLayout"
                                             android:layout_width="match_parent"
                                             android:layout_height="match_parent">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/list"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginBottom="8dp"
        android:paddingTop="8dp"
        android:scrollbars="vertical"
        app:layout_constraintBottom_toTopOf="@+id/editText"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

    <TextView
        android:id="@+id/editText"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginLeft="8dp"
        android:ems="10"
        android:gravity="left"
        android:inputType="none|text|textPersonName"
        android:text="* required fields"
        android:textStyle="bold"
        app:layout_constraintBottom_toTopOf="@+id/btnGetSelected"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"/>

    <Button
        android:id="@+id/btnGetSelected"
        android:layout_width="0dp"
        android:layout_height="40dp"
        android:layout_marginBottom="4dp"
        android:text="I agree"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"/>


</android.support.constraint.ConstraintLayout>

Agreements list passed to ActivityAgreements and adapter setup:

@Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_agreements);

        btnGetSelected = findViewById(R.id.btnGetSelected);
        list = findViewById(R.id.list);
        list.setLayoutManager(new LinearLayoutManager(this));
        list.setHasFixedSize(true);


        agreements = getIntent().getParcelableArrayListExtra("agreements");



        AgreementsAdapter adapter = new AgreementsAdapter(this.agreements);
        list.setAdapter(adapter);

My adapter code:

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

    ArrayList<Agreement> agreements;

    public AgreementsAdapter(List<Agreement> agreements)
    {
        this.agreements = new ArrayList<>(agreements);
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
    {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.agreement_list_item, parent, false);
        return new ViewHolder(v);
    }

    @Override
    public void onBindViewHolder(final ViewHolder holder, int position)
    {
        holder.bindData(agreements.get(position));
        holder.checkbox.setOnCheckedChangeListener(null);
        holder.checkbox.setChecked(agreements.get(position).getAccepted());
        //holder.checkbox.setFloorUnCheckedColor(agreements.get(position).getRequired()? Color.rgb(255,0,0):Color.rgb(0,255,0) );
        holder.checkbox.setOnCheckedChangeListener((buttonView, isChecked) -> agreements.get(holder.getAdapterPosition()).setAccepted(isChecked));
    }

    @Override
    public int getItemCount()
    {
        return agreements.size();
    }

    public static class ViewHolder extends RecyclerView.ViewHolder
    {
        private TextView textAgreementName;
        private AppCompatCheckBox checkbox;

        public ViewHolder(View v)
        {
            super(v);
            //textAgreementName = v.findViewById(R.id.text_agreement_name);
            checkbox = v.findViewById(R.id.checkbox_agreement_accepted);
        }

        public void bindData(Agreement agreement)
        {
            //checkbox.setFloorUnCheckedColor(agreement.getRequired()? Color.rgb(255,0,0):Color.rgb(0,0,255) );
            /*if(agreement.getRequired())
            {
                textAgreementName.setTypeface(null, Typeface.BOLD);
                textAgreementName.setText(agreement.getName() + " *");
            }
            else
                textAgreementName.setText(agreement.getName());*/


            if(agreement.getRequired())
            {
                checkbox.setText(agreement.getName() + " *");
                checkbox.setTypeface(null, Typeface.BOLD);
            }
            else
            {
                checkbox.setText(agreement.getName());
            }




        }
    }
}

All is fine, activity with list shows itself without any problems. Now, I want to use AlertDialog, not activity to display agreements list. I'm trying to create AlertDialog this way (in main activity):

AlertDialog.Builder alertDialog = new AlertDialog.Builder(MainActivity.this);
            LayoutInflater inflater = getLayoutInflater();
            View convertView = inflater.inflate(R.layout.activity_agreements, null);
            alertDialog.setView(convertView);


            RecyclerView list = convertView.findViewById(R.id.list);
            list.setLayoutManager(new LinearLayoutManager(this));
            list.setHasFixedSize(true);

            AgreementsAdapter adapter = new AgreementsAdapter(agreements);
            list.setAdapter(adapter);



           alertDialog.show();

agreements variable contains agreements list (the same as previously passed to AgrrementsActivity). But it does not work - dialog is shown with custom layout, but list is always empty.

Can anybody point me what am I missing?

New code with fixed size and other suggestions:

AlertDialog.Builder alertDialog = new AlertDialog.Builder(MainActivity.this);
            LayoutInflater inflater = getLayoutInflater();
            View convertView = inflater.inflate(R.layout.activity_agreements, null);



            RecyclerView list = convertView.findViewById(R.id.list);
            list.setLayoutManager(new LinearLayoutManager(this));
            list.setHasFixedSize(true);

            AgreementsAdapter adapter = new AgreementsAdapter(agreements);
            list.setAdapter(adapter);
            alertDialog.setView(convertView);

            AlertDialog dialog = alertDialog.create();
            dialog.getWindow().setLayout(600, 400);



           dialog.show();
           adapter.notifyDataSetChanged();

Solution

  • Your RecyclerView is probably showing the list, but it has a height of 0 so it looks empty.

    Dialog size is kind of tricky, check this answer and try to give it a fixed height (maybe a percent of your screen height).