web-dev-qa-db-fra.com

Comment afficher le tiroir de navigation dans toutes les activités?

J'ai un Navigation Drawer qui devrait apparaître dans toutes mes activités.

J'ai vu beaucoup de questions similaires à celles-ci et trouvé une solution comme Étendre l'activité principale avec les autres activités.

J'ai donc étendu mon activité principale à ma deuxième activité. Mais le tiroir n'est pas visible dans la deuxième activité 

Activité principale

public class MainActivity extends ActionBarActivity
{
    private ListView mDrawerList;
    private DrawerLayout mDrawer;
    private CustomActionBarDrawerToggle mDrawerToggle;
    private String[] menuItems;

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    supportRequestWindowFeature(WindowCompat.FEATURE_ACTION_BAR);
    // getSupportActionBar().hide();
    setContentView(R.layout.activity_main_drawer);

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

    mDrawer = (DrawerLayout) findViewById(R.id.drawer_layout);

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

    _initMenu();
    mDrawerToggle = new CustomActionBarDrawerToggle(this, mDrawer);
    mDrawer.setDrawerListener(mDrawerToggle);

}

private void _initMenu()
{
    NsMenuAdapter mAdapter = new NsMenuAdapter(this);

    // Add Header
    mAdapter.addHeader(R.string.ns_menu_main_header);

    // Add first block

    menuItems = getResources().getStringArray(R.array.ns_menu_items);
    String[] menuItemsIcon = getResources().getStringArray(R.array.ns_menu_items_icon);

    int res = 0;
    for (String item : menuItems)
    {

        int id_title = getResources().getIdentifier(item, "string", this.getPackageName());
        int id_icon = getResources().getIdentifier(menuItemsIcon[res], "drawable", this.getPackageName());

        NsMenuItemModel mItem = new NsMenuItemModel(id_title, id_icon);
        // if (res==1) mItem.counter=12; //it is just an example...
        // if (res==3) mItem.counter=3; //it is just an example...
        mAdapter.addItem(mItem);
        res++;
    }

    mAdapter.addHeader(R.string.ns_menu_main_header2);

    mDrawerList = (ListView) findViewById(R.id.drawer);
    if (mDrawerList != null)
        mDrawerList.setAdapter(mAdapter);

    mDrawerList.setOnItemClickListener(new DrawerItemClickListener());

}

@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);
    mDrawerToggle.onConfigurationChanged(newConfig);
}

@Override
public boolean onCreateOptionsMenu(Menu menu)
{
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.control_menu, menu);
    return super.onCreateOptionsMenu(menu);
}

/* Called whenever we call invalidateOptionsMenu() */
@Override
public boolean onPrepareOptionsMenu(Menu menu)
{
    // If the nav drawer is open, hide action items related to the content
    // view
    boolean drawerOpen = mDrawer.isDrawerOpen(mDrawerList);
    menu.findItem(R.id.action_keyboard).setVisible(!drawerOpen);
    return super.onPrepareOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item)
{
    /*
     * The action bar home/up should open or close the drawer.
     * ActionBarDrawerToggle will take care of this.
     */
    if (mDrawerToggle.onOptionsItemSelected(item))
    {
        return true;
    }

    // Handle your other action bar items...
    return super.onOptionsItemSelected(item);
}

private class CustomActionBarDrawerToggle extends ActionBarDrawerToggle
{

    public CustomActionBarDrawerToggle(Activity mActivity, DrawerLayout mDrawerLayout)
    {
        super(mActivity, mDrawerLayout, R.drawable.ic_drawer, R.string.ns_menu_open, R.string.ns_menu_close);
    }

    @Override
    public void onDrawerClosed(View view)
    {
        getSupportActionBar().setTitle(getString(R.string.ns_menu_close));
        supportInvalidateOptionsMenu(); // creates call to
                                        // onPrepareOptionsMenu()
    }

    @Override
    public void onDrawerOpened(View drawerView)
    {
        getSupportActionBar().setTitle(getString(R.string.ns_menu_open));
        supportInvalidateOptionsMenu(); // creates call to
                                        // onPrepareOptionsMenu()
    }
}

private class DrawerItemClickListener implements ListView.OnItemClickListener
{

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id)
    {
        Intent intent = new Intent(MainActivity.this, Tutorial.class);
        startActivity(intent);

    }

}

 }

SecondActivity

 public class Tutorial extends MainActivity
{
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.help);
    }

}
19
AruLNadhaN

dans onCreate of TutorialActivity, n'appelez pas setContentView à la place, procédez comme suit:

@Override
protected void onCreate(Bundle savedInstanceState)
{
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    LayoutInflater inflater = (LayoutInflater) this
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View contentView = inflater.inflate(R.layout.help, null, false);
    mDrawer.addView(contentView, 0); 
}

mettez mDrawer dans MainActivity protégé. et dans R.layout.activity_main_drawer, conservez simplement l'étiquette du tiroir et l'élément avec gravité à gauche (ou à droite).

25
vipul mittal

Voici ma mise en œuvre .. espérons que cela aide

PREMIER, ce POST est un concept.

SECOND, c'est aussi le CL&EACUTE; _.

ENFIN, voici la combinaison de toutes les réponses au même endroit


ACTIVITÉ DE BASE

Ceci est une activité de base pour toutes les autres activités

Vous pouvez étendre Activity ou FragmentActivity ou etc. en fonction de vos besoins.

Navigation Drawer configuration ici pour une fois.

public class BaseActivity extends FragmentActivity {

    protected DrawerLayout mDrawer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.base_layout);

        mDrawer = (DrawerLayout) findViewById(R.id.drawer_layout);

        //This is about creating custom listview for navigate drawer
        //Implementation for NavigateDrawer HERE !
        ArrayList<DrawerListItem> drawerListItems = new ArrayList<DrawerListItem>();
        drawerListItems.add(new DrawerListItem(0,"AIR° DEVICES"));
        drawerListItems.add(new DrawerListItem(1,"A/C Device [1]"));
        drawerListItems.add(new DrawerListItem(1,"A/C Device [2]"));
        drawerListItems.add(new DrawerListItem(1,"A/C Device [3]"));
        drawerListItems.add(new DrawerListItem(0,"AIR° FEATURES"));
        drawerListItems.add(new DrawerListItem(2,"SLEEP MODE"));
        drawerListItems.add(new DrawerListItem(2,"TRACKING MODE"));
        drawerListItems.add(new DrawerListItem(2,"SETTINGS"));
        DrawerAdapter mDrawerAdapter = new DrawerAdapter(this, R.layout.drawer_list_header, drawerListItems);
        ListView mDrawerList = (ListView) findViewById(R.id.left_drawer);
        mDrawerList.setAdapter(mDrawerAdapter);
    }

}

XML D'ACTIVITÉ DE BASE

Cette mise en page XML est pour Navigation Drawer

<?xml version="1.0" encoding="utf-8"?>

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

    <!-- The navigation drawer -->
    <ListView
            Android:id="@+id/left_drawer"
            Android:layout_width="match_parent"
            Android:layout_height="match_parent"
            Android:layout_gravity="left"
            Android:scrollingCache="false"
            Android:background="@drawable/drawer_bg"
            Android:divider="@null"
            Android:choiceMode="singleChoice"/>

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

TOUT AUTRES ACTIVITE

Autre Activity étend simplement BaseActivity et définit le code comme ci-dessous.

Le Navigation Drawer apparaîtra pour une activité particulière.

mDrawer est form BaseActivity. c'est une variable protected.

public class Screen1 extends BaseActivity

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        //inflate your activity layout here!
        View contentView = inflater.inflate(R.layout.screen1, null, false);
        mDrawer.addView(contentView, 0);

        //Do the rest as you want for each activity
    }

SCREEN 1 EXEMPLE XML

Concevez comme vous le souhaitez pour chaque activité. Pas plus de Navigation Drawer Layout!

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

</LinearLayout>

REMARQUE

Dans cette implémentation, le Navigation Drawer ne se lie pas à la barre d'action. Si vous souhaitez le faire, faites-le dans BaseActivity. En outre, ce guide ne couvre pas toutes les exigences. C'est juste un échantillon.

30
Jongz Puangput

J'ai créé une activité BaseActivity qui étend SherlockActivity (ou ActionBarActivity si c'est votre cas)

public class BaseActivity extends SherlockActivity

Ensuite, assurez-vous que toutes vos activités prolongent BaseActivity, par exemple:

public class GlossaryActivity extends BaseActivity

Plus tard, vous devez remplacer la présentation d'activité par celle qui correspond à votre activité. J'ai créé une méthode dans BaseActivity comme celle-ci:

protected void replaceContentLayout(int sourceId, int destinationId) {
    View contentLayout = findViewById(destinationId);

    ViewGroup parent = (ViewGroup) contentLayout.getParent();
    int index = parent.indexOfChild(contentLayout);

    parent.removeView(contentLayout);
    contentLayout = getLayoutInflater().inflate(sourceId, parent, false);
    parent.addView(contentLayout, index);
}

J'ai appelé cette méthode sur la méthode onCreate dans chaque activité:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    super.replaceContentLayout(R.layout.activity_glossary, super.CONTENT_LAYOUT_ID);

}

super.CONTENT_LAYOUT_ID est le FrameLayout de la BaseActivity, et l'autre paramètre est la disposition que vous voulez remplacer par

2
Daniel Siguero

Voici un moyen simple et rapide de le faire dans le studio Android:

  1. Créez une nouvelle activité (activité du tiroir de navigation) à partir de la galerie et nommez-la comme vous le souhaitez. Android Studio créera tout pour vous (la classe et les fichiers xml que vous pourrez personnaliser ultérieurement).

  2. Dans les autres activités, vous devez étendre l'activité de votre tiroir Navigation et vous assurer que ces autres activités ne comportent "aucune barre d'action" dans le fichier fanifests (Android: theme = "@ style/AppTheme.NoActionBar").

  3. Vous devez modifier vos autres activités comme suit: 

    public class Mainactivity extends NavActivity
    {
    super.onCreate(savedInstanceState);
       LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
       //inflate your activity layout here!
       View contentView = inflater.inflate(R.layout.activity_main, null, false);
       drawer.addView(contentView, 0);
    }
    

Remarque: l’activité principale étend la barre d’action de NavActivity; celui-ci est doté d’une barre d’action fonctionnelle qui appelle le tiroir de navigation.

J'espère que ça marchera avec toi

0

Ok, voici une façon hacky de le faire, je l’utilise seulement pour un type spécial de construction de débogage pour définir les propriétés des vues en temps réel (outil de conception).

Cela présente l'avantage que vous pouvez utiliser vos activités enfants comme d'habitude sans comportement spécial requis dans différentes réponses.

donc, dans BaseActvity, vous pouvez ajouter:

@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);

// WARNING: Hacky, use carefully!!!
ViewGroup androidBaseView = (ViewGroup) findViewById(Android.R.id.content);
//this one in what child activity has just set in setContentView()
ViewGroup childContent = (ViewGroup) androidBaseView.getChildAt(0);

View drawerView = LayoutInflater.from(this)
    .inflate(R.layout.base_activity_drawer, androidBaseView, false);
FrameLayout frameLayout = (FrameLayout) drawerView.findViewById(R.id.content);
androidBaseView.removeView(childContent);
frameLayout.addView(childContent);
androidBaseView.addView(drawerView);
}

et XML pour le tiroir est juste:

  <Android.support.v4.widget.DrawerLayout
  xmlns:Android="http://schemas.Android.com/apk/res/Android"
  Android:id="@+id/nav_drawer"
  Android:layout_width="match_parent"
  Android:layout_height="match_parent"
  Android:fitsSystemWindows="true">
  <FrameLayout
    Android:id="@+id/content"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"/>
  <LinearLayout
    Android:id="@+id/drawer_for_components"
    Android:layout_width="240dp"
    Android:layout_height="match_parent"
    Android:layout_gravity="end"
    Android:orientation="vertical"
    Android:fitsSystemWindows="true"
    />
</Android.support.v4.widget.DrawerLayout>
0

Vous avez omis le @Override de votre classe dérivée onCreate.

UPDATE: Je ne suis pas sûr des effets de l'appel de setContentView deux fois, mais cela pourrait être le problème Séparez le code qui configure le tiroir et appelez-le à partir des deux méthodes onCreate

0
Greg Ennis

J'ai eu ce problème également. Ceci est ma mise en œuvre:

activity_main.xml - l'enfant à l'index 1 dans CoordinatorLayout est le content_main.xml , je peux le modifier en code.

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

    <Android.support.design.widget.CoordinatorLayout
        Android:id="@+id/coordinator"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:fitsSystemWindows="true">

        <Android.support.design.widget.AppBarLayout
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:theme="@style/AppTheme.AppBarOverlay">

            <Android.support.v7.widget.Toolbar
                Android:id="@+id/toolbar"
                Android:layout_width="match_parent"
                Android:layout_height="?attr/actionBarSize"
                Android:background="?attr/colorPrimary"
                app:popupTheme="@style/AppTheme.PopupOverlay" />

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

        **<include layout="@layout/content_main" />**

        <Android.support.design.widget.FloatingActionButton
            Android:id="@+id/fab"
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:layout_gravity="bottom|end"
            Android:layout_margin="@dimen/fab_margin"
            Android:src="@Android:drawable/ic_dialog_email" />

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

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

J'ai créé une classe qui utilise l'interface utilisateur des autres activités:

public class MyLayoutInflater {

    public void inflate(Activity activity, int LayoutResource, Android.app.ActionBar getSupportActionBar, Intent getIntent){
        CoordinatorLayout coordinatorLayout = (CoordinatorLayout) activity.findViewById(R.id.coordinator);
        Android.view.LayoutInflater inflater = (Android.view.LayoutInflater) activity
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View contentView = inflater.inflate(LayoutResource, null, false);

        //change i so that it suits the child number in you coordinator layout
        int i = 1;
        coordinatorLayout.removeViewAt(i);
        coordinatorLayout.addView(contentView, i);
        getSupportActionBar.setTitle(actionBarTitle);
    }

    public void inflate(Activity activity, int LayoutResource, Android.support.v7.app.ActionBar getActionBar, String actionBarTitle){
        CoordinatorLayout coordinatorLayout = (CoordinatorLayout) activity.findViewById(R.id.coordinator);
        Android.view.LayoutInflater inflater = (Android.view.LayoutInflater) activity
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View contentView = inflater.inflate(LayoutResource, null, false);

        //change i so that it suits the child number in you coordinator layout
        int i = 1;
        coordinatorLayout.removeViewAt(i);
        coordinatorLayout.addView(contentView, i);
        getActionBar.setTitle(actionBarTitle);
    }

}

Maintenant, pour les autres activités, tout ce que vous avez à faire est d’étendre MainActivity, d’appeler cette méthode et de lui donner les paramètres nécessaires:

public class AnotherActivity extends MainActivity {

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        new MyLayoutInflater().inflate(this,R.layout.content_activity_another, getSupportActionBar(), getIntent());

    }
}
0