androidexpandablelistviewcustomdialog

ExpandableListView object null when used inside custom alert dialog


I am creating an sample application in which I am opening a custom alert dialog on click of a button. The custom dialog which contains a custom expandable list.

In activity_main.xml, I added a button.

 <Button
        android:id="@+id/buttonShowCustomDialog"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Show Custom Dialog" />

Created custom.xml for custom dialog and added ExpandableListView in it.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:id="@+id/relativeL">

    <ExpandableListView
        android:id="@+id/lvExp"
        android:layout_height="match_parent"
        android:layout_width="match_parent"/>

</RelativeLayout>

For ExpandableListView, I also created list-group.xml and list-items.xml.

Here is my MainActivity.java-

public class MainActivity extends AppCompatActivity {

    final Context context = this;
    private Button button;

    ExpandableListAdapter listAdapter;
    ExpandableListView expListView;
    List<String> listDataHeader;
    HashMap<String, List<String>> listDataChild;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        expListView = (ExpandableListView) findViewById(R.id.lvExp);
        button = (Button) findViewById(R.id.buttonShowCustomDialog);
        // add button listeners
        button.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View arg0) {
                prepareListData();

                AlertDialog.Builder builder = new AlertDialog.Builder(getApplicationContext());
                builder.setTitle("Select something");

                listAdapter = new ExpandableListAdapter(getApplicationContext(), listDataHeader, listDataChild);
                expListView.setAdapter(listAdapter);

                builder.setView(expListView);
                AlertDialog dialog = builder.create();
                dialog.show();
            }
        });
    }

    private void prepareListData() {
        listDataHeader = new ArrayList<String>();
        listDataChild = new HashMap<String, List<String>>();

        // Adding child data
        listDataHeader.add("Top 250");
        listDataHeader.add("Now Showing");
        listDataHeader.add("Coming Soon..");

        // Adding child data
        List<String> top250 = new ArrayList<String>();
        top250.add("The Shawshank Redemption");


        List<String> nowShowing = new ArrayList<String>();
        nowShowing.add("The Conjuring");

        List<String> comingSoon = new ArrayList<String>();
        comingSoon.add("2 Guns");

        listDataChild.put(listDataHeader.get(0), top250); // Header, Child data
        listDataChild.put(listDataHeader.get(1), nowShowing);
        listDataChild.put(listDataHeader.get(2), comingSoon);
    }
}

On button click expListView comes null always. I am not able to get the expandablelistview object from the custom dialog.

What am I doing wrong here? Please suggest.

Here is ExpandableListAdapter.java

public class ExpandableListAdapter extends BaseExpandableListAdapter {

    private Context _context;
    private List<String> _listDataHeader; // header titles
    // child data in format of header title, child title
    private HashMap<String, List<String>> _listDataChild;

    public ExpandableListAdapter(Context context, List<String> listDataHeader,
                                 HashMap<String, List<String>> listChildData) {
        this._context = context;
        this._listDataHeader = listDataHeader;
        this._listDataChild = listChildData;
    }

    @Override
    public Object getChild(int groupPosition, int childPosititon) {
        return this._listDataChild.get(this._listDataHeader.get(groupPosition))
                .get(childPosititon);
    }

    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return childPosition;
    }

    @Override
    public View getChildView(int groupPosition, final int childPosition,
                             boolean isLastChild, View convertView, ViewGroup parent) {

        final String childText = (String) getChild(groupPosition, childPosition);

        if (convertView == null) {
            LayoutInflater infalInflater = (LayoutInflater) this._context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = infalInflater.inflate(R.layout.list_item, null);
        }

        TextView txtListChild = (TextView) convertView
                .findViewById(R.id.lblListItem);

        txtListChild.setText(childText);
        return convertView;
    }

    @Override
    public int getChildrenCount(int groupPosition) {
        return this._listDataChild.get(this._listDataHeader.get(groupPosition))
                .size();
    }

    @Override
    public Object getGroup(int groupPosition) {
        return this._listDataHeader.get(groupPosition);
    }

    @Override
    public int getGroupCount() {
        return this._listDataHeader.size();
    }

    @Override
    public long getGroupId(int groupPosition) {
        return groupPosition;
    }

    @Override
    public View getGroupView(int groupPosition, boolean isExpanded,
                             View convertView, ViewGroup parent) {
        String headerTitle = (String) getGroup(groupPosition);
        if (convertView == null) {
            LayoutInflater infalInflater = (LayoutInflater) this._context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = infalInflater.inflate(R.layout.list_group, null);
        }

        TextView lblListHeader = (TextView) convertView
                .findViewById(R.id.lblListHeader);
        lblListHeader.setTypeface(null, Typeface.BOLD);
        lblListHeader.setText(headerTitle);

        return convertView;
    }

    @Override
    public boolean hasStableIds() {
        return false;
    }

    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return true;
    }
}

Solution

  • As per your code, you are adding your ExpandableListView in custom.xml file and not using this file reference anywhere in your Activity.

    Also you are inflating your ExpandableListView from activity_main.xml and trying to set that view for AlertDialog.

    If you want to display ExpandableListView inside your Dialog, then you need to inflate your custom.xml file, then find ExpandableListView from your dialog object and then bind adapter with it.

    You can use Dialog as well. Check below code.

    button.setOnClickListener(new View.OnClickListener() {
    
        @Override
        public void onClick(View arg0) {
            prepareListData();
            openDialog();
        }
    });
    

    Below is openDialog() Method.

    public void openDialog() {
    
        AlertDialog.Builder dialog_custom = new AlertDialog.Builder(getApplicationContext());
        dialog_custom.setTitle("Select something");
        View dialogView = this.getLayoutInflater().inflate(R.layout.custom, null);
        dialog_custom.setView(dialogView);
    
        ExpandableListView expListView = dialogView.findViewById(R.id.lvExp);
        expListView.setAdapter(new ExpandableListAdapter(getApplicationContext(), listDataHeader, listDataChild));
    
        AlertDialog alertDialog = dialog_custom.create();
        alertDialog.show();
    }