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);
}
}
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).
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.
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
Voici un moyen simple et rapide de le faire dans le studio Android:
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).
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").
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
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>
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
.
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());
}
}