web-dev-qa-db-fra.com

Tiroir de navigation: ajouter des en-têtes dans la liste

J'ai créé un projet avec le nouvel objet tiroir de navigation.

Je voudrais personnaliser la mise en page du menu, ajouter un autre objet comme TextView, ImageView ... Et pour commencer, je voudrais modifier la mise en page par défaut qui n'est composée que d'une vue de liste, en ajoutant 2 ou 3 en-têtes dans le listview.

Aujourd'hui, j'ai essayé d'utiliser "addHeaderView" mais je pense qu'il est possible de l'utiliser uniquement pour ajouter un en-tête.

Comment puis-je faire pour ajouter un en-tête et vraiment personnaliser mon menu de mise en page? Car, à partir de l'API développeur, il semble que seuls deux enfants sont autorisés sous un "Android.support.v4.widget.DrawerLayout".

Voici une capture de ma mise en page aujourd'hui:

Navigation Drawer Headers in listview

Et voici une capture que je veux créer:

Navigation Drawer Headers in listview

Voici un morceau de code de ma MainActivity:

public class MainActivity extends Activity {
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
private ActionBarDrawerToggle mDrawerToggle;

private CharSequence mDrawerTitle;
private CharSequence mTitle;
private String[] mPlanetTitles;

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

    mTitle = mDrawerTitle = getTitle();
    mPlanetTitles = getResources().getStringArray(R.array.planets_array);
    mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);

    // Declaration of the 2 listview's 
    mDrawerList = (ListView) findViewById(R.id.dernieres_news);

    LayoutInflater inflater = getLayoutInflater();

    // Add header news title
    ViewGroup header_news = (ViewGroup)inflater.inflate(R.layout.header_dernieres_news, mDrawerList, false);
    mDrawerList.addHeaderView(header_news, null, false);

    // set a custom shadow that overlays the main content when the drawer opens
    mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);

    String[] names=new String[]{"Title 1", "Title 2", "Title 3", "Title 4", "Title 5"};

    /*Array of Images*/
    int[] image = new int[] {R.drawable.ic_action_feed, R.drawable.ic_action_feed, R.drawable.ic_action_feed, R.drawable.ic_action_feed, R.drawable.ic_action_feed};

    List<HashMap<String, String>> listinfo = new ArrayList<HashMap<String, String>>();
    listinfo.clear();
    for(int i=0;i<5;i++){
        HashMap<String, String> hm = new HashMap<String, String>();
        hm.put("name", names[i]);
        hm.put("image", Integer.toString(image[i]));
        listinfo.add(hm);
    }

    // Keys used in Hashmap
    String[] from = { "image", "name" };
    int[] to = { R.id.img, R.id.txt };
    SimpleAdapter adapter = new SimpleAdapter(getBaseContext(), listinfo, R.layout.drawer_list_item, from, to);
    mDrawerList.setAdapter(adapter);

    mDrawerList.setOnItemClickListener(new DrawerItemClickListener());

    // enable ActionBar app icon to behave as action to toggle nav drawer
    getActionBar().setDisplayHomeAsUpEnabled(true);
    getActionBar().setHomeButtonEnabled(true);

    // ActionBarDrawerToggle ties together the the proper interactions
    // between the sliding drawer and the action bar app icon
    mDrawerToggle = new ActionBarDrawerToggle(
            this,                  /* Host Activity */
            mDrawerLayout,         /* DrawerLayout object */
            R.drawable.ic_drawer,  /* nav drawer image to replace 'Up' caret */
            R.string.drawer_open,  /* "open drawer" description for accessibility */
            R.string.drawer_close  /* "close drawer" description for accessibility */
            ) {
        public void onDrawerClosed(View view) {
            getActionBar().setTitle(mTitle);
            invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
        }

        public void onDrawerOpened(View drawerView) {
            getActionBar().setTitle(mDrawerTitle);
            invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
        }
    };
    mDrawerLayout.setDrawerListener(mDrawerToggle);

    if (savedInstanceState == null) {
        selectItem(0);
    }
}

Et le code de activity_main.xml:

<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" />


    <ListView
        Android:id="@+id/dernieres_news"
        Android:layout_width="240dp"
        Android:layout_height="match_parent"
        Android:layout_gravity="start"
        Android:background="#F3F3F4"
        Android:choiceMode="singleChoice"
        Android:divider="#E3E9E3"
        Android:dividerHeight="1dp" />
15
wawanopoulos

Vous feriez cela de la même manière que vous ajouteriez des en-têtes dans tout autre ListView, en apprenant à votre ListAdapter à renvoyer des lignes de titre ainsi que des lignes de détail. Au niveau bas, cela implique de remplacer des méthodes comme getViewTypeCount() et getItemViewType() dans votre ListAdapter, ainsi que getView() connaître la différence entre les types de lignes . Ou, utilisez une implémentation de haut niveau existante telle que https://github.com/emilsjolander/StickyListHeaders ou http://code.google.com/p/Android-amazing-listview / ou l'un des autres trouvés lors de la recherche de Android listview headers.

8
CommonsWare

Les autres réponses sont correctes.

J'ai trouvé un très bon exemple de personnalisation de la vue pour contenir deux types d'éléments: menu section et menu item. Bien sûr, vous pouvez le changer pour en faire ce que vous voulez.

L'exemple contient également une implémentation d'une classe d'activité abstraite dont chaque activité avec un tiroir de navigation hérite.

http://www.michenux.net/Android-navigation-drawer-748.html

8
Michael

Vous devrez sous-classer BaseAdapter et l'utiliser à la place de SimpleAdapter dans le ListView.

Vous fournissez à l'adaptateur des données farcies, où les données supplémentaires sont les titres. Les titres et les éléments de liste eux-mêmes seront membres de la même classe commune. Ensuite, dans l'adaptateur, vous décidez en fonction de l'élément de données si la vue réelle est un titre ou un élément et le gonflez en conséquence.

METTRE À JOUR:

Voici un bon exemple de cela: http://w2davids.wordpress.com/Android-sectioned-headers-in-listviews/

Cela sépare en fait les titres des éléments de données et utilise correctement convertView, contrairement à la solution que j'ai utilisée jusqu'à présent dans mes applications précédentes.

1
Herrbert74