web-dev-qa-db-fra.com

Vue par défaut du tiroir de navigation vers ExpandableListView

Dans Android Studio 2.1.2, si je crée une activité de navigation par défaut, j'obtiens cette vue:

enter image description here

Qui utilise le fichier activity_main.xml Suivant:

<?xml version="1.0" encoding="utf-8"?>
<Android.support.v4.widget.DrawerLayout 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/drawer_layout"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:fitsSystemWindows="true"
    tools:openDrawer="start">

    <include
        layout="@layout/app_bar_main"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent" />

    <Android.support.design.widget.NavigationView
        Android:id="@+id/nav_view"
        Android:layout_width="wrap_content"
        Android:layout_height="match_parent"
        Android:layout_gravity="start"
        Android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_main"
        app:menu="@menu/activity_main_drawer" />

</Android.support.v4.widget.DrawerLayout>

Comme vous pouvez le voir, <Android.support.design.widget.NavigationView/> Utilise app:menu="@menu/activity_main_drawer" Pour afficher la liste des menus définis dans le fichier activity_main_drawer.xml Comme suit:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:Android="http://schemas.Android.com/apk/res/Android">

    <group Android:checkableBehavior="single">
        <item
            Android:id="@+id/nav_camera"
            Android:icon="@drawable/ic_menu_camera"
            Android:title="Import" />
        <item
            Android:id="@+id/nav_gallery"
            Android:icon="@drawable/ic_menu_gallery"
            Android:title="Gallery" />
        <item
            Android:id="@+id/nav_slideshow"
            Android:icon="@drawable/ic_menu_slideshow"
            Android:title="Slideshow" />
        <item
            Android:id="@+id/nav_manage"
            Android:icon="@drawable/ic_menu_manage"
            Android:title="Tools" />
    </group>

    <item Android:title="Communicate">
        <menu>
            <item
                Android:id="@+id/nav_share"
                Android:icon="@drawable/ic_menu_share"
                Android:title="Share" />
            <item
                Android:id="@+id/nav_send"
                Android:icon="@drawable/ic_menu_send"
                Android:title="Send" />
        </menu>
    </item>

</menu>

Maintenant, mon plan est de remplacer cette liste de menu définie dans activity_main_drawer.xml Et d'utiliser à la place un ExpandableListView. Parce que je veux que mes éléments de menu aient des sous-catégories, par exemple, l'élément de menu Cars aura une sous-catégorie de Diesel, Petrol et Hybrid etc. J'ai fait des recherches et il semble que personne n'a la solution de travail exacte dont j'ai besoin.

J'ai regardé ici:

  1. Les tutoriels ouverts
  2. Implémentez expandablelistview dans l'activité du tiroir de navigation faite par Android studio
  3. Android: 2 ou plus ExpandableListView dans le tiroir de navigation
  4. Comment créer une liste extensible dans le tiroir de navigation?

et les liens ultérieurs qui y sont mentionnés.

NB: Les liens ci-dessus mentionnent l'utilisation de ListView dans le tiroir de navigation, ce qui n'est plus le cas comme Android Studio y parvient en utilisant menu item en utilisant activity_main_drawer.xml.

Quelqu'un peut-il me fournir un exemple pratique de cela? Pour réitérer, je veux une vue de liste extensible à l'intérieur de l'activité du tiroir de navigation par défaut. J'ai compris que j'aurais besoin de fichiers XML et de codes de classe Java pour me donner les bases dont j'ai besoin pour commencer).

Merci d'avance. :)

EDIT: Maquette du look final (excusez mes compétences Photoshop) enter image description here

Mon approche actuelle consiste à créer une nouvelle mise en page ex_list Comme suit:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:orientation="vertical" Android:layout_width="match_parent"
    Android:layout_height="match_parent">
    <Android.support.v4.widget.DrawerLayout
        Android:id="@+id/drawer_layout"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent">
       <ExpandableListView
            Android:id="@+id/lvExp"
            Android:layout_height="match_parent"
            Android:layout_width="match_parent"/>

    </Android.support.v4.widget.DrawerLayout>
</LinearLayout>

et modifiez activity_main.xml pour

<?xml version="1.0" encoding="utf-8"?>
<Android.support.v4.widget.DrawerLayout 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/drawer_layout"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:fitsSystemWindows="true"
    tools:openDrawer="start">

    <include
        layout="@layout/app_bar_main"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent" />

    <Android.support.design.widget.NavigationView
        Android:id="@+id/nav_view"
        Android:layout_width="240dp"
        Android:layout_gravity = "start"
        Android:layout_height="match_parent"

        Android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_main">
        <include
            layout="@layout/ex_list"
            Android:layout_height="wrap_content"
            Android:layout_width="match_parent"/>

    </Android.support.design.widget.NavigationView>


</Android.support.v4.widget.DrawerLayout>

Ce qui se traduit par la mise en page suivante:

enter image description here

et message d'erreur de

                                                                      Java.lang.IllegalArgumentException: DrawerLayout must be measured with MeasureSpec.EXACTLY.
                                                                          at Android.support.v4.widget.DrawerLayout.onMeasure(DrawerLayout.Java:1036)
                                                                          at Android.view.View.measure(View.Java:18788)
                                                                          at Android.view.ViewGroup.measureChildWithMargins(ViewGroup.Java:5951)
                                                                          at Android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.Java:1465)
                                                                          at Android.widget.LinearLayout.measureVertical(LinearLayout.Java:748)
                                                                          at Android.widget.LinearLayout.onMeasure(LinearLayout.Java:630)
                                                                          at Android.view.View.measure(View.Java:18788)
                                                                          at Android.view.ViewGroup.measureChildWithMargins(ViewGroup.Java:5951)
                                                                          at Android.widget.FrameLayout.onMeasure(FrameLayout.Java:194)
                                                                          at Android.support.design.widget.NavigationView.onMeasure(NavigationView.Java:223)
                                                                          at Android.view.View.measure(View.Java:18788)
                                                                          at Android.support.v4.widget.DrawerLayout.onMeasure(DrawerLayout.Java:1104)
                                                                          at Android.view.View.measure(View.Java:18788)
                                                                          at Android.view.ViewGroup.measureChildWithMargins(ViewGroup.Java:5951)
                                                                          at Android.widget.FrameLayout.onMeasure(FrameLayout.Java:194)
                                                                          at Android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.Java:135)
                                                                          at Android.view.View.measure(View.Java:18788)
                                                                          at Android.view.ViewGroup.measureChildWithMargins(ViewGroup.Java:5951)
                                                                          at Android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.Java:1465)
                                                                          at Android.widget.LinearLayout.measureVertical(LinearLayout.Java:748)
                                                                          at Android.widget.LinearLayout.onMeasure(LinearLayout.Java:630)
                                                                          at Android.view.View.measure(View.Java:18788)
                                                                          at Android.view.ViewGroup.measureChildWithMargins(ViewGroup.Java:5951)
                                                                          at Android.widget.FrameLayout.onMeasure(FrameLayout.Java:194)
                                                                          at Android.view.View.measure(View.Java:18788)
                                                                          at Android.view.ViewGroup.measureChildWithMargins(ViewGroup.Java:5951)
                                                                          at Android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.Java:1465)
                                                                          at Android.widget.LinearLayout.measureVertical(LinearLayout.Java:748)
                                                                          at Android.widget.LinearLayout.onMeasure(LinearLayout.Java:630)
                                                                          at Android.view.View.measure(View.Java:18788)
                                                                          at Android.view.ViewGroup.measureChildWithMargins(ViewGroup.Java:5951)
                                                                          at Android.widget.FrameLayout.onMeasure(FrameLayout.Java:194)
                                                                          at com.Android.internal.policy.PhoneWindow$DecorView.onMeasure(PhoneWindow.Java:2643)
                                                                          at Android.view.View.measure(View.Java:18788)
                                                                          at Android.view.ViewRootImpl.performMeasure(ViewRootImpl.Java:2100)
                                                                          at Android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.Java:1216)
                                                                          at Android.view.ViewRootImpl.performTraversals(ViewRootImpl.Java:1452)
                                                                          at Android.view.ViewRootImpl.doTraversal(ViewRootImpl.Java:1107)
                                                                          at Android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.Java:6013)
                                                                          at Android.view.Choreographer$CallbackRecord.run(Choreographer.Java:858)
                                                                          at Android.view.Choreographer.doCallbacks(Choreographer.Java:670)
                                                                          at Android.view.Choreographer.doFrame(Choreographer.Java:606)
                                                                          at Android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.Java:844)
                                                                          at Android.os.Handler.handleCallback(Handler.Java:739)
                                                                          at Android.os.Handler.dispatchMessage(Handler.Java:95)
                                                                          at Android.os.Looper.loop(Looper.Java:148)
                                                                          at Android.app.ActivityThread.main(ActivityThread.Java:5417)
                                                                          at Java.lang.reflect.Method.invoke(Native Method)
                                                                          at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:726)
                                                                          at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:616)

Qu'est-ce que je fais mal?

RÉPONDRE:

enter image description here

Merci @Moulesh !!!

10
envyM6

Voici le code de l'adaptateur de liste extensible:

public class ExpandListAdapter 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 ExpandListAdapter(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;
}}

Dans votre activité:

     private void enableExpandableList() {
      listDataHeader = new ArrayList<String>();
      listDataChild = new HashMap<String, List<String>>();
    expListView = (ExpandableListView) findViewById(R.id.left_drawer);

    prepareListData(listDataHeader, listDataChild);
    listAdapter = new ExpandListAdapter(this, listDataHeader, listDataChild);
    // setting list adapter
    expListView.setAdapter(listAdapter);

    expListView.setOnGroupClickListener(new ExpandableListView.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
    expListView.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {

        @Override
        public void onGroupExpand(int groupPosition) {
            Toast.makeText(getApplicationContext(),
                    listDataHeader.get(groupPosition) + " Expanded",
                    Toast.LENGTH_SHORT).show();
        }
    });

    // Listview Group collasped listener
    expListView.setOnGroupCollapseListener(new ExpandableListView.OnGroupCollapseListener() {

        @Override
        public void onGroupCollapse(int groupPosition) {
            Toast.makeText(getApplicationContext(),
                    listDataHeader.get(groupPosition) + " Collapsed",
                    Toast.LENGTH_SHORT).show();

        }
    });

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

        @Override
        public boolean onChildClick(ExpandableListView parent, View v,
                                    int groupPosition, int childPosition, long id) {
            // TODO Auto-generated method stub
            // Temporary code:

            // till here
            Toast.makeText(
                    getApplicationContext(),
                    listDataHeader.get(groupPosition)
                            + " : "
                            + listDataChild.get(
                            listDataHeader.get(groupPosition)).get(
                            childPosition), Toast.LENGTH_SHORT)
                    .show();
            return false;
        }
    });}

Méthode pour créer une liste avec des données:

   private void prepareListData(List<String> listDataHeader, Map<String,
  List<String>> listDataChild) {


    // Adding child data
    listDataHeader.add("Product1");
    listDataHeader.add("product2");
    listDataHeader.add("Product3");

    // Adding child data
    List<String> top = new ArrayList<String>();
    top.add("x1");
    top.add("x2");
    top.add("x3");
    top.add("x4");
    top.add("x5");


    List<String> mid = new ArrayList<String>();
    mid.add("y1");
    mid.add("y2");
    mid.add("y3");

    List<String> bottom = new ArrayList<String>();
    bottom.add("z1");
    bottom.add("z2");
    bottom.add("z3");



    listDataChild.put(listDataHeader.get(0), top); // Header, Child data
    listDataChild.put(listDataHeader.get(1), mid);
    listDataChild.put(listDataHeader.get(2), bottom);
}

ce code dans la mise en page xml

<?xml version="1.0" encoding="utf-8"?>
    <Android.support.v4.widget.DrawerLayout 
     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/drawer_layout"
     Android:layout_width="match_parent"
     Android:layout_height="match_parent"
     Android:fitsSystemWindows="true"
     tools:openDrawer="start">

<include
    Android:id="@+id/act_bar"
    layout="@layout/app_bar_main"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent" />

<Android.support.design.widget.NavigationView
    Android:id="@+id/nav_view"
    Android:layout_width="wrap_content"
    Android:layout_height="match_parent"
    Android:layout_gravity="start"
    Android:fitsSystemWindows="true"
    app:headerLayout="@layout/nav_header_main">
    <!--app:menu="@menu/activity_main_drawer"-->

    <ExpandableListView
        Android:id="@+id/left_drawer"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:layout_marginTop="@dimen/nav_header_height"
        Android:background="@color/Background"
        Android:dividerHeight="0dp" />

</Android.support.design.widget.NavigationView>
</Android.support.v4.widget.DrawerLayout>

xml pour ExplistHeader list_group.xml

    <?xml version="1.0" encoding="utf-8"?>
        <LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
        Android:layout_width="fill_parent"
        Android:layout_height="wrap_content"
        Android:orientation="vertical"
        Android:paddingTop="10dp"
        Android:padding="30dp"
        Android:background="@color/Background">

        <TextView
            Android:id="@+id/lblListHeader"
            Android:layout_width="fill_parent"
            Android:layout_height="wrap_content"
            Android:paddingLeft="?
            Android:attr/expandableListPreferredItemPaddingLeft"
            Android:textSize="17dp"
            Android:textColor="@color/colorTextPrimary" />    
        </LinearLayout>

xml pour Explistchild list_item.xml

    <?xml version="1.0" encoding="utf-8"?>
        <LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
        Android:layout_width="match_parent"
        Android:layout_height="55dip"
        Android:background="@color/Background"
        Android:orientation="vertical" >

        <TextView
            Android:id="@+id/lblListItem"
            Android:layout_width="fill_parent"
            Android:layout_height="wrap_content"
            Android:textSize="17dip"
            Android:paddingTop="5dp"
            Android:paddingBottom="5dp"
            Android:paddingLeft="?
            Android:attr/expandableListPreferredChildPaddingLeft" />
        </LinearLayout>
25
Moulesh

Téléchargez le code source d'ici ( tiroir de navigation avec expandablelistview dans Android )

 import Android.content.Context;
import Android.view.LayoutInflater;
import Android.view.View;
import Android.view.ViewGroup;
import Android.widget.BaseExpandableListAdapter;
import Android.widget.TextView;

import Java.util.ArrayList;


public class CountryAdapter extends BaseExpandableListAdapter {
    Context context;
    ArrayList<Model_country> al_country;

    public CountryAdapter(Context context, ArrayList<Model_country> al_country) {
        this.context = context;
        this.al_country = al_country;
    }

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

    @Override
    public int getChildrenCount(int i) {
        return al_country.get(i).getAl_state().size();
    }

    @Override
    public Object getGroup(int i) {
        return al_country.get(i);
    }

    @Override
    public Object getChild(int i, int i1) {
        return al_country.get(i).getAl_state().get(i1);
    }

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

    @Override
    public long getChildId(int i, int i1) {
        return i1;
    }

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

    @Override
    public View getGroupView(int i, boolean b, View view, ViewGroup viewGroup) {
        if (view==null){

            LayoutInflater layoutInflater = (LayoutInflater) this.context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = layoutInflater.inflate(R.layout.adapter_header, null);
        }
        TextView tv_state = (TextView)view.findViewById(R.id.tv_name);
        tv_state.setText(al_country.get(i).getStr_country());
        return view;
    }

    @Override
    public View getChildView(final int i, final int i1, boolean b, View view, ViewGroup viewGroup) {
        if (view==null){

            LayoutInflater layoutInflater = (LayoutInflater) this.context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = layoutInflater.inflate(R.layout.adapter_childview, null);
        }

        TextView tv_state = (TextView)view.findViewById(R.id.tv_name);

        tv_state.setText(al_country.get(i).getAl_state().get(i1).getStr_name());
        tv_state.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                ((MainActivity)context).fn_selectedPosition(i,i1);
            }
        });
        return view;
    }

    @Override
    public boolean isChildSelectable(int i, int i1) {
        return false;
    }


}

Merci!

0
Deepshikha Puri