11
votes

Tiroir de navigation avec des en-têtes / sections

J'aimerais savoir s'il y a une façon de pouvoir ajouter des en-têtes / sections au tiroir de navigation. J'ai réussi à ajouter quelque chose comme ça, mais il est affiché uniquement en haut de la liste, car AddaDeView doit être appelé avant SetAdapter et si j'essaie d'ajouter plus d'éléments après que SetAdapter, ils réécrivent les premiers éléments.

Merci. p>

EDIT: P>

import java.util.ArrayList;

import android.content.Context;
import android.content.res.Configuration;
import android.os.Bundle;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;

import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;
import com.androidbegin.item.EntryAdapter;
import com.androidbegin.item.EntryItem;
import com.androidbegin.item.Item;
import com.androidbegin.item.SectionItem;

public class MainActivity extends SherlockFragmentActivity {

    // Declare Variable
    DrawerLayout mDrawerLayout;
    ListView mDrawerList;
    ActionBarDrawerToggle mDrawerToggle;
    MenuListAdapter mMenuAdapter;
    String[] title;
    String[] subtitle;
    int[] icon;
    Fragment fragment1 = new Fragment1();
    Fragment fragment2 = new Fragment2();
    Fragment fragment3 = new Fragment3();
    Context context;

    ArrayList<Item> items = new ArrayList<Item>();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.drawer_main);
        this.context = this;
        // Generate title
        title = new String[] { "Title Fragment 1", "Title Fragment 2",
                "Title Fragment 3" };

        // Generate subtitle
        subtitle = new String[] { "Subtitle Fragment 1", "Subtitle Fragment 2",
                "Subtitle Fragment 3" };

        // Generate icon
        icon = new int[] { R.drawable.action_about, R.drawable.action_settings,
                R.drawable.collections_cloud };

        // Locate DrawerLayout in drawer_main.xml
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);

        // Locate ListView in drawer_main.xml
        mDrawerList = (ListView) findViewById(R.id.left_drawer);

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

        // Pass results to MenuListAdapter Class
//      mMenuAdapter = new MenuListAdapter(this, title, subtitle, icon);

        // Set the MenuListAdapter to the ListView
//      mDrawerList.setAdapter(mMenuAdapter);

        items.add(new SectionItem("Category 1"));
        items.add(new EntryItem("Item 1", "This is item 1.1"));
        items.add(new EntryItem("Item 2", "This is item 1.2"));
        items.add(new EntryItem("Item 3", "This is item 1.3"));


        items.add(new SectionItem("Category 2"));
        items.add(new EntryItem("Item 4", "This is item 2.1"));
        items.add(new EntryItem("Item 5", "This is item 2.2"));
        items.add(new EntryItem("Item 6", "This is item 2.3"));
        items.add(new EntryItem("Item 7", "This is item 2.4"));

        items.add(new SectionItem("Category 3"));
        items.add(new EntryItem("Item 8", "This is item 3.1"));
        items.add(new EntryItem("Item 9", "This is item 3.2"));
        items.add(new EntryItem("Item 10", "This is item 3.3"));
        items.add(new EntryItem("Item 11", "This is item 3.4"));
        items.add(new EntryItem("Item 12", "This is item 3.5"));

        EntryAdapter adapter = new EntryAdapter(this, items);

        mDrawerList.setAdapter(adapter);

        // Capture button clicks on side menu
        mDrawerList.setOnItemClickListener(new DrawerItemClickListener());

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

        // ActionBarDrawerToggle ties together the the proper interactions
        // between the sliding drawer and the action bar app icon
        mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
                R.drawable.ic_drawer, R.string.drawer_open,
                R.string.drawer_close) {

            public void onDrawerClosed(View view) {
                // TODO Auto-generated method stub
                super.onDrawerClosed(view);
            }

            public void onDrawerOpened(View drawerView) {
                // TODO Auto-generated method stub
                super.onDrawerOpened(drawerView);
            }
        };

        mDrawerLayout.setDrawerListener(mDrawerToggle);

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

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getSupportMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        if (item.getItemId() == android.R.id.home) {

            if (mDrawerLayout.isDrawerOpen(mDrawerList)) {
                mDrawerLayout.closeDrawer(mDrawerList);
            } else {
                mDrawerLayout.openDrawer(mDrawerList);
            }
        }

        return super.onOptionsItemSelected(item);
    }

    // The click listener for ListView in the navigation drawer
    private class DrawerItemClickListener implements
            ListView.OnItemClickListener {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position,
                long id) {
            Log.i("LIST", "item position = " + Integer.toString(position)
                    + "\nitem id = " + String.valueOf(id));
            if (!items.get(position).isSection()) {
                EntryItem item = (EntryItem)items.get(position);

                Toast.makeText(context, "You clicked " + item.title , Toast.LENGTH_SHORT).show();

                selectItem(position);
            }
//          selectItem(position);
        }
    }

    private void selectItem(int position) {

        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        // Locate Position
        switch (position) {
            case 0:
                ft.replace(R.id.content_frame, fragment1);
                break;
            case 1:
                ft.replace(R.id.content_frame, fragment2);
                break;
            case 2:
                ft.replace(R.id.content_frame, fragment3);
                break;
        }
        ft.commit();
        mDrawerList.setItemChecked(position, true);
        // Close drawer
        mDrawerLayout.closeDrawer(mDrawerList);
    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        // Sync the toggle state after onRestoreInstanceState has occurred.
        mDrawerToggle.syncState();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        // Pass any configuration change to the drawer toggles
        mDrawerToggle.onConfigurationChanged(newConfig);
    }
}


0 commentaires

7 Réponses :


1
votes

Dans le tiroir de navigation La liste des éléments peut être affichée à l'aide d'une liste de lecture afin que vous puissiez avoir un adaptateur de classe et implémenter votre logique. Afin que vous puissiez ajouter des sections, des en-têtes et ainsi de suite.


3 commentaires

Et comment puis-je y parvenir? J'ai déjà une base de base qui remplit la liste (parce que j'ai ajouté une image et un sous-titre pour la liste)? J'ai ajouté l'adaptateur dans le poteau principal.


Il suffit de mettre en place un adaptateur personnalisé et remplacez les méthodes telles que GeveView, etc.


Comme vous pouvez le voir, je le fais déjà, mais comment recommandez-vous d'ajouter des en-têtes à la liste du tiroir de navigation?



6
votes

Vous ajoutez des en-têtes / sections à un listview pour une utilisation dans un DrawerLayout de la même manière que vous ajoutez des en-têtes / sections à un listview pour Utilisez n'importe où ailleurs à l'intérieur de Android.

Au niveau bas, cela implique un listAdapter que:

  • remplace geveviewtypeCount () Pour indiquer le nombre de types distincts de lignes (par exemple, 2, une pour les en-têtes et une pour des lignes régulières)

  • remplace getItemViewTtype () Pour indiquer quel type de ligne à utiliser pour une position donnée

  • garantit que greveView () (ou NewView () / Bindview () d'un Cursoradapter ) est conscient des types de lignes multiples et les traite en conséquence

    À un niveau supérieur, vous pouvez essayer d'utiliser des objets comme mon mergeadapter , ou diverses autres bibliothèques tiers, pour aider à simplifier cela.


2 commentaires

Merci, je vais essayer votre bibliothèque, même si cela semble beaucoup de travail pour quelque chose qui l'estime devrait être aussi défaillante. Si vous connaissez d'autres tutoriels de la manière dont cela peut être atteint, je serai beaucoup reconnaissant.


@IonUtNegru: Une recherche simple sur Android ListView Section des en-têtes Dans votre moteur de recherche préféré augmentera de nombreuses pages, y compris des bibliothèques (telles que code.google.com/p/android-amazing-listview ), Stackoverflow Questions (telles que Stackoverflow.com/questions/7943802/... ), tutoriels / recettes (telles que AndroidCookbook.com/Recipe.Seam?RecpeId=992 ) et plus.



0
votes

Si vos éléments de liste sont corrigés (non-modifications), un «piratage» rapide serait d'inclure un étui de commutation pour «position» dans la méthode GeveView () de votre adaptateur et gonflez une tête de tête.xml à ces positions fixes. Votre inflation régulière entrera dans la partie par défaut du boîtier de commutation. C'est sale et non recommandé mais efficace.


1 commentaires

Je voudrais éviter ce type de piratage car il sera difficile d'être modifié à l'avenir (si cela sera nécessaire). Mais merci pour la pointe.



0
votes

Je suggérerais d'étendre EntryItem en ajoutant un élément de balise qui vous indique quel type de fragment à créer. Ensuite, vérifiez simplement la balise dans votre OnItemClick pour créer le type de fragment correct. De cette façon, vous n'êtes pas dépendant de la position, qui peut changer lorsque vous ajoutez / supprimez des éléments dans les sections.


0 commentaires

0
votes

Vous devez ajouter ceci à la classe d'entréeAdAdapter: xxx

avec cela, et: xxx

sections ne devrait pas prendre position sur la liste de liste.


0 commentaires

0
votes

Une bonne solution que j'ai lue était de placer une en-tête TextView à l'intérieur de votre fichier de mise en page et définir sa visibilité sur parti .

puis dans votre adaptateur greveView , avez-vous une logique qui dit: Est-ce le tout premier élément de la liste (position 0) ou est le type de cet élément différent de celui de type une position de type ci-dessus ce? Si tel est le cas, tournez la visibilité de l'en-tête TextView sur visible .

De cette façon est préféré car lorsque vous souhaitez utiliser getItematPosition , vous n'avez pas à comprendre comment esquiver les en-têtes de votre section car ils prendraient une position entière si vous les avez implémentées le façon dont l'op et les autres ont suggéré.


0 commentaires

1
votes

Ici, vous avez un Exemple complet de tiroir de navigation utilisant des en-têtes / sections

C'est le résultat

Entrez la description de l'image ici


0 commentaires