Question

I have created a navigation drawer with an expandable listview inside it. I want the expandable listview to expand one of its groups and select one of its child by default when the activity opens up. The user may change the selection according to his requirement.

Whatever I have created is not satisfying my requirement. The expandable list is allowing the user to select multiple options.

The MainActivity:

public class MainActivity extends Activity {
    DrawerLayout mDrawerLayout;
    ExpandableListView mDrawerList;
    ExpandableListAdapter listAdapter;
    List<String> listDataHeader;
    HashMap<String, List<String>> listDataChild;
    private ActionBar mActionBar;

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

        // Action bar with collapse icon for drawer menu===================
        mActionBar = getActionBar();
        mActionBar.setHomeButtonEnabled(true);
        mActionBar.setDisplayHomeAsUpEnabled(false);
        // Action bar with collapse icon for drawer menu===================

        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerList = (ExpandableListView) findViewById(R.id.left_drawer);

        // preparing list data
        prepareListData();

        listAdapter = new ExpandableListAdapter(this, listDataHeader,
                listDataChild);

        // setting list adapter
        mDrawerList.setAdapter(listAdapter);

        // Listview Group click listener
        mDrawerList.setOnGroupClickListener(new OnGroupClickListener() {

            @Override
            public boolean onGroupClick(ExpandableListView parent, View v,
                    int groupPosition, long id) {
                // Toast.makeText(getApplicationContext(),
                // "Group Clicked " + listDataHeader.get(groupPosition),
                // Toast.LENGTH_SHORT).show();
                return false;
            }
        });

        // // Listview Group expanded listener
        // mDrawerList.setOnGroupExpandListener(new OnGroupExpandListener() {
        //
        // @Override
        // public void onGroupExpand(int groupPosition) {
        // Toast.makeText(getApplicationContext(),
        // listDataHeader.get(groupPosition) + " Expanded",
        // Toast.LENGTH_SHORT).show();
        // }
        // });
        //
        // // Listview Group collasped listener
        // mDrawerList.setOnGroupCollapseListener(new OnGroupCollapseListener()
        // {
        //
        // @Override
        // public void onGroupCollapse(int groupPosition) {
        // Toast.makeText(getApplicationContext(),
        // listDataHeader.get(groupPosition) + " Collapsed",
        // Toast.LENGTH_SHORT).show();
        //
        // }
        // });

        // mDrawerList.expandGroup(2);
        // mDrawerList.expandGroup(2, true);

        // Listview on child click listener
        mDrawerList.setOnChildClickListener(new OnChildClickListener() {

            @Override
            public boolean onChildClick(ExpandableListView parent, View v,
                    int groupPosition, int childPosition, long id) {

                mDrawerLayout.closeDrawer(mDrawerList);
                // TODO Auto-generated method stub
                // Toast.makeText(
                // getApplicationContext(),
                // listDataHeader.get(groupPosition)
                // + " : "
                // + listDataChild.get(
                // listDataHeader.get(groupPosition)).get(
                // childPosition), Toast.LENGTH_SHORT)
                // .show();
                 v.setBackgroundColor(Color.BLUE);

                makeAToast("Group: " + groupPosition + " Child: "
                        + childPosition);
                return false;
            }
        });

        // To collapse previously opened group===========
        mDrawerList.setOnGroupExpandListener(new OnGroupExpandListener() {
            int previousItem = -1;

            @Override
            public void onGroupExpand(int groupPosition) {
                if (groupPosition != previousItem)
                    mDrawerList.collapseGroup(previousItem);
                previousItem = groupPosition;
            }
        });
        // To collapse previously opened group===========
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case android.R.id.home:
            if (mDrawerLayout.isDrawerOpen(mDrawerList)) {
                mDrawerLayout.closeDrawer(mDrawerList);
            } else {
                mDrawerLayout.openDrawer(mDrawerList);
            }
            break;

        default:
            break;
        }
        return super.onOptionsItemSelected(item);
    }

    /*
     * Preparing the list data
     */
    private void prepareListData() {
        listDataHeader = new ArrayList<String>();
        listDataChild = new HashMap<String, List<String>>();

        // Adding header data
        listDataHeader.add("Today");

        // Adding child data
        List<String> today = new ArrayList<String>();
        today.add("Tanushree Guha");
        today.add("Prasenjit Roy");
        today.add("Pan Singh Tomar");
        today.add("Milka Singh");
        today.add("Rohit Ramanujan");
        today.add("Ramesh Bhatt");
        today.add("Debjani Brahma");

        listDataHeader.add("Tomorrow");
        List<String> tomorrow = new ArrayList<String>();
        tomorrow.add("Dipanjan Bhowmik");
        tomorrow.add("Sarmistha Sinha");
        tomorrow.add("Pranay Lalwani");
        tomorrow.add("Mohit Shaw");
        tomorrow.add("Lovelace Agarwal");
        tomorrow.add("Tanmay Banerjee");

        listDataHeader.add("Later");
        List<String> later = new ArrayList<String>();
        later.add("Yusuf Khan");
        later.add("Jitendar Sharma");
        later.add("Debashree Roy");
        later.add("Mainak Ghosh");
        later.add("Olivia Gomes");

        listDataChild.put(listDataHeader.get(0), today); // Header, Child data
        listDataChild.put(listDataHeader.get(1), tomorrow);
        listDataChild.put(listDataHeader.get(2), later);
    }

    // method to show toast message
    public void makeAToast(String str) {
        Toast toast = Toast.makeText(this, str, Toast.LENGTH_LONG);
        toast.setGravity(Gravity.CENTER, 0, 0);
        toast.show();
    }
}

The activity_main.xml layout:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >

<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >


<FrameLayout
    android:id="@+id/content_frame"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
</FrameLayout>

 <!-- android:layout_gravity="start" tells DrawerLayout to treat
     this as a sliding drawer on the left side for left-to-right
     languages and on the right side for right-to-left languages.
     The drawer is given a fixed width in dp and extends the full height of
     the container. A solid background is used for contrast
     with the content view. -->
<ExpandableListView
    android:id="@+id/left_drawer"
    android:layout_width="240dp"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:choiceMode="singleChoice"
    android:divider="#999999"
    android:dividerHeight="1dp"
    android:background="#ffffff"/>
</android.support.v4.widget.DrawerLayout>

</RelativeLayout>

The ExpandableListAdapter class:

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

}

If anymore source code is required, I will provide it. What should I do to satisfy my requirement?

Était-ce utile?

La solution

For the first part of the question:

I want the expandable listview to expand one of its groups and select one of its child by default when the activity opens up

mExpandableListView.setSelectedChild(groupPosition, childPosition, shouldExpandGroup);

where :

  1. groupPosition is the position of the group that should be expanded first
  2. position of the child that should be selected by default *More info below
  3. shouldExpandGroup is a boolean that should be set to true to expand the group

Info for 2 above.

  1. Maintain a hashmap containing the group postion and the child position selected by the user like:

    HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
    map.put(groupPosition, childPosition);
    
  2. For every child selection simply put it into the hashmap, it would overwrite the value if present

  3. Store this hashmap either in a file or somewhere where you can access it again (may be shared preference but it does not allow storage of objects)

  4. When the activity starts get the value from the hashmap, and set the selection, you could set the selection for all the groups but with shouldExpand to false for all except the first. If the map is empty set default selection to 0.

Autres conseils

I would recomment using SlideExpandableListView for Android:

Screenshot
(Well that screenshot is crap but you can guess the animation)

This is the official description of that library:

Not happy with the Android ExpandableListView android offers? Want something like the Spotify app. This library allows you to have custom listview in wich each list item has an area that will slide-out once the users clicks on a certain button.

Features

  • Provides a better ExpandableListView usable for normal ListView's
  • Animates by default
  • Easy to use

Check that repository at GitHub: https://github.com/tjerkw/Android-SlideExpandableListView/.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top