Android: 2 or more ExpandableListView inside Navigation Drawer

crc_error picture crc_error · Jan 14, 2014 · Viewed 29.6k times · Source

How could I do something like this?

enter image description here

Two expandable listview inside navigation drawer. I tryed to add it inside my xml but without luck. What I want is a view with only one scrollbar, but I don't' know how to do it..

this is my navigation drawer layout:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:background="@color/Bianco"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:orientation="vertical"
        android:layout_marginLeft="16dp"
        android:layout_marginTop="8dp"
        android:layout_marginBottom="8dp"
        android:layout_marginRight="16dp"
        android:layout_height="wrap_content">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:text="@string/tvHomeActions"
            android:id="@+id/textView" />

        <ExpandableListView
            android:id="@+id/elvHome"
            android:layout_width="match_parent"
            android:layout_marginTop="4dp"
            android:layout_height="300dp" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:text="@string/tvHomeNavigations"
            android:layout_marginTop="16dp"
            android:id="@+id/textView2" />

        <ExpandableListView
            android:id="@+id/elvNavigateTo"
            android:layout_width="match_parent"
            android:layout_height="200dp"
            android:layout_marginTop="4dp"  />

    </LinearLayout>

</ScrollView>

EDIT: I wanna create something like drawer in Gmail app

Answer

crc_error picture crc_error · Jan 16, 2014

enter image description here

Finally i have got it! This is the code I created to get an ExpandableListView with section titles. Now it's I can easily create three xml custom layouts for titles, groups and childrens.

It work for me, but I accept any code improvements to optimize memory usage, speed and so on.

// ---------------------------------------------------------------------------------------------
// NAVIGATION DRAWER SIDE FRAGMENT
// ---------------------------------------------------------------------------------------------

private ExpandableListView mDrawerListView;
private List<Elemento> mainActions = new ArrayList<>();
private HashMap<Integer, List<String>> childActions = new HashMap<>();

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    View v = inflater.inflate(R.layout.frg_navigation_drawer, container, false);

    assert v != null;

    mDrawerListView = (ExpandableListView) v.findViewById(R.id.elvHome);
    mDrawerListView.setGroupIndicator(null);

    // add first title
    mainActions.add(new TitoloGruppo("Good guys"));                     // 0
    mainActions.add(new Azione("Admiral Ackbar", "Dagobah System"));    // 1
    mainActions.add(new Azione("Han Solo", "Millenium Falcon"));        // 2
    mainActions.add(new Azione("Yoda", "Dagobah System"));              // 3
    // add second title
    mainActions.add(new TitoloGruppo("Bad guys"));                      // 4
    mainActions.add(new Azione("Emperor", "Death star 2"));             // 5
    mainActions.add(new Azione("Jabba", "Tatooine"));                   // 6
    mainActions.add(new Azione("Grand Moff Tarkin", "Death star 1"));   // 7

    // Adding child quotes to Ackbar
    List<String> mainSubFive = new ArrayList<>();
    mainSubFive.add("It's a trap!");

    // Adding child quotes to Yoda
    List<String> mainSubThree = new ArrayList<>();
    mainSubThree.add("Do or do not; there is no try.");
    mainSubThree.add("There is … another … Sky … walker.…");
    mainSubThree.add("When 900 years old you reach, look as good you will not ehh.");

    childActions.put(0, new ArrayList<String>());
    childActions.put(1, mainSubFive);
    childActions.put(2, new ArrayList<String>());
    childActions.put(3, mainSubThree);
    childActions.put(4, new ArrayList<String>());
    childActions.put(5, new ArrayList<String>());
    childActions.put(6, new ArrayList<String>());

    mDrawerListView.setAdapter(new ExpandableAdapter(getActivity(), mainActions, childActions));
    mDrawerListView.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
        @Override
        public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
            List<String> list = childActions.get(groupPosition);
            if(list.size() > 0)
                return false;
            else
                Toast.makeText(getActivity(), ""+ ((Azione) mainActions.get(groupPosition)).getSubtitle(), Toast.LENGTH_LONG).show();
            return false;
        }
    });

    mDrawerListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
        @Override
        public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
            List<String> list = childActions.get(groupPosition);

            Toast.makeText(getActivity(), "" + list.get(childPosition).toString(), Toast.LENGTH_LONG).show();
            return false;
        }
    });
    return v;
}


// ---------------------------------------------------------------------------------------------
// INTERNAL CLASS
// ---------------------------------------------------------------------------------------------

protected class ExpandableAdapter extends BaseExpandableListAdapter {

    private Context context;
    private List<Elemento> mainElements;
    private HashMap<Integer, List<String>> childElements;
    private LayoutInflater vi;

    public ExpandableAdapter(Context context, List<Elemento> mainElements, HashMap<Integer, List<String>> childElements) {
        this.context = context;
        this.mainElements = mainElements;
        this.childElements = childElements;
        vi = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

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

    @Override
    public int getChildrenCount(int groupPosition) {
        if(this.childElements.get(groupPosition) == null)
            return 0;
        return this.childElements.get(groupPosition).size();
    }

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

    @Override
    public Object getChild(int groupPosition, int childPosition) {
        return this.childElements.get(groupPosition).get(childPosition);
    }

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

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

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

    @Override
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        View v = convertView;

        final Elemento i = mainElements.get(groupPosition);
        if (i != null) {
            if(i.isGroupSection()){
                final TitoloGruppo si = (TitoloGruppo)i;
                v = vi.inflate(android.R.layout.simple_list_item_1, null);
                v.setOnClickListener(null);
                v.setOnLongClickListener(null);
                v.setLongClickable(false);
                final TextView sectionView = (TextView) v.findViewById(android.R.id.text1);
                sectionView.setTextColor(Color.parseColor("#FFC800"));
                sectionView.setText(si.getTitle());
            }else if(i.isAction()){
                Azione ei = (Azione)i;
                v = vi.inflate(android.R.layout.simple_list_item_2, null);
                final TextView title = (TextView)v.findViewById(android.R.id.text1);
                final TextView subtitle = (TextView)v.findViewById(android.R.id.text2);

                if (title != null)
                    title.setText(ei.title);
                if(subtitle != null)
                    subtitle.setText("count: " + getChildrenCount(groupPosition));
            }
        }
        return v;
    }

    @Override
    public View getChildView(int groupPosition, 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(android.R.layout.simple_list_item_1, null);
        }

        TextView txtListChild = (TextView) convertView.findViewById(android.R.id.text1);
        txtListChild.setText(childText);
        return convertView;
    }

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

    public class TitoloGruppo implements Elemento {

    private final String titolo;

    public TitoloGruppo(String titolo) {
        this.titolo = titolo;
    }

    public String getTitle(){
        return titolo;
    }

    @Override
    public boolean isGroupSection() {
        return true;
    }

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

protected interface Elemento {
    public boolean isGroupSection();
    public boolean isAction();
}

protected class Azione implements Elemento {
    public final String title;
    public final String subtitle;

    public Azione(String title, String subtitle) {
        this.title = title;
        this.subtitle = subtitle;
    }

    public String getTitle() {
        return this.title;
    }

    public String getSubtitle() {
        return this.subtitle;
    }

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

    @Override
    public boolean isAction() {
        return true;
    }
}

Ps. thank you all