Est-il possible d'utiliser un tiroir de navigation dans Android mais au lieu de mettre à jour des fragments, j'aimerais passer d'une activité à une autre comme moyen de navigation dans l'application.
Oui c'est possible - c'est ce que j'ai fait pour mon application. J'avais déjà un certain nombre d'activités configurées et, plutôt que de les convertir toutes en fragments, je souhaitais adapter le tiroir de navigation de manière à pouvoir les traiter toutes. Malheureusement, la solution de contournement n'est pas rapide. Si vous avez l'option d'utiliser des fragments, c'est ce que je ferais. Mais peu importe, voici comment je l'ai fait:
Disons que j'ai 2 activités, pour lesquelles je souhaite avoir le tiroir de navigation. Dans le fichier layout.xml correspondant à chacun, j'ai spécifié un DrawerLayout
avec le ListView
approprié pour contenir mes options de navigation. Essentiellement, le tiroir de navigation est créé chaque fois que je passe d’une activité à l’autre, ce qui donne l’impression qu’il persiste. Pour rendre la vie beaucoup plus facile, j'ai pris les méthodes courantes requises pour configurer le tiroir de navigation et les mettre dans leur propre classe: NavigationDrawerSetup.Java
. Ainsi, mes activités peuvent utiliser le même adaptateur personnalisé, etc.
Dans cette classe NavigationDrawerSetup.Java
, j'ai les éléments suivants:
configureDrawer()
- ceci configure la ActionBar
, ActionBarDrawerToggle
et les écouteurs requisselectOptions()
, qui gère les clics sur les éléments du tiroirLorsque vous configurez le tiroir de navigation dans l'une de vos activités, vous créez simplement un nouvel objet NavigationDrawerSetup
et transmettez les paramètres de présentation requis (tels que DrawerLayout
, ListView
etc.). Ensuite, vous appelez configureDrawer()
:
navigationDrawer = new NavigationDrawerSetup(mDrawerView, mDrawerLayout,
mDrawerList, actionBar, mNavOptions, currentActivity);
navigationDrawer.configureDrawer();
currentActivity
est transmis car le tiroir de navigation est lié à l'activité que vous utilisez. Vous devrez l’utiliser lors de la configuration de ActionBarDrawerToggle
:
mDrawerToggle = new ActionBarDrawerToggle(currentActivity, // 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 */
)
Vous devrez également utiliser currentActivity
lors de la configuration de votre Adapter
:
En ce qui concerne la commutation entre les activités via le tiroir de navigation, vous pouvez simplement configurer de nouvelles intentions dans votre méthode selectItem ():
private void selectItem(int position) {
// Handle Navigation Options
Intent intent;
switch (position) {
case 0:
intent = new Intent(currentActivity, NewActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
currentActivity.startActivity(intent);
break;
case 1:
// etc.
}
Assurez-vous simplement que votre nouveau Activity
dispose également de la configuration du tiroir de navigation et qu'il devrait s'afficher.
Il y a une tonne de choses que vous pouvez faire pour adapter cette méthode à vos propres besoins, mais c'est la structure générale de la façon dont je l'ai faite. J'espère que cela t'aides!
Vous avez besoin d'une BaseDrawerActivity
qui implémente le tiroir de navigation puis étendez-la BaseDrawerActivity
dans chaque activité pour laquelle vous avez besoin du tiroir de navigation.
Créez d'abord BaseDrawerActivity.Java
:
public class BaseDrawerActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener{
DrawerLayout drawerLayout;
Toolbar toolbar;
FrameLayout frameLayout;
NavigationView navigationView;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.activity_base_drawer);;
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
frameLayout = (FrameLayout) findViewById(R.id.content_frame);
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawerLayout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawerLayout.setDrawerListener(toggle);
toggle.syncState();
navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
}
@Override
public void onBackPressed() {
if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
drawerLayout.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
@Override
public boolean onNavigationItemSelected(MenuItem item) {
int id = item.getItemId();
//to prevent current item select over and over
if (item.isChecked()){
drawerLayout.closeDrawer(GravityCompat.START);
return false;
}
if (id == R.id.nav_camera) {
// Handle the camera action
startActivity(new Intent(getApplicationContext(), CameraActivity.class));
} else if (id == R.id.nav_gallery) {
startActivity(new Intent(getApplicationContext(), GalleryActivity.class));
} else if (id == R.id.nav_slideshow) {
startActivity(new Intent(getApplicationContext(), SlideshowActivity.class));
} else if (id == R.id.nav_manage) {
startActivity(new Intent(getApplicationContext(), ManageActivity.class));
} else if (id == R.id.nav_share) {
startActivity(new Intent(getApplicationContext(), ShareActivity.class));
} else if (id == R.id.nav_send) {
startActivity(new Intent(getApplicationContext(), SendActivity.class));
}
drawerLayout.closeDrawer(GravityCompat.START);
return true;
}
}
puis créez activity_base_drawer.xml
dans le dossier res/layout
:
<?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"
tools:openDrawer="start">
<include layout="@layout/app_bar_home"/>
<Android.support.design.widget.NavigationView
Android:id="@+id/nav_view"
Android:layout_width="wrap_content"
Android:layout_height="match_parent"
Android:layout_gravity="start"
app:headerLayout="@layout/nav_header_home"
app:menu="@menu/activity_home_drawer" />
</Android.support.v4.widget.DrawerLayout>
où @layout/app_bar_home
est:
<?xml version="1.0" encoding="utf-8"?>
<Android.support.design.widget.CoordinatorLayout 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: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>
<FrameLayout Android:id="@+id/content_frame"
Android:layout_width="match_parent"
Android:layout_height="match_parent" />
</Android.support.design.widget.CoordinatorLayout>
Ensuite, vous entrez vos activités qui auront un tiroir de navigation tel que CameraActivity.Java
:
public class CameraActivity extends BaseDrawerActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getLayoutInflater().inflate(R.layout.activity_camera, frameLayout);
/**
* Setting title
*/
setTitle("Camera");
}
@Override
protected void onResume() {
super.onResume();
// to check current activity in the navigation drawer
navigationView.getMenu().getItem(0).setChecked(true);
}
}
Où R.layout.activity_camera
est votre mise en page pour CameraActivity.Java
.
Ensuite, créez une autre activité comme GalleryActivity.Java
et ainsi de suite qui aura le tiroir de navigation:
public class GalleryActivity extends BaseDrawerActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getLayoutInflater().inflate(R.layout.activity_gallery, frameLayout);
// Setting title
setTitle("Gallery");
}
@Override
protected void onResume() {
super.onResume();
navigationView.getMenu().getItem(1).setChecked(true);
}
}
En tant que petite amélioration à la solution indiquée par @ David-Crozier, afin d’éviter le chevauchement des deux animations (fermeture de NavigationDrawer et démarrage d’une nouvelle activité), vous pouvez inclure un peu de retard dans votre méthode, comme dans l’application iosched. v2014:
private void onNavDrawerItemClicked(final int itemId) {
if (itemId == getSelfNavDrawerItem()) {
mDrawerLayout.closeDrawer(GravityCompat.START);
return;
}
if (isSpecialItem(itemId)) {
goToNavDrawerItem(itemId);
} else {
// launch the target Activity after a short delay, to allow the close animation to play
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
goToNavDrawerItem(itemId);
}
}, NAVDRAWER_LAUNCH_DELAY);
// change the active item on the list so the user can see the item changed
setSelectedNavDrawerItem(itemId);
// fade out the main content
View mainContent = findViewById(R.id.main_content);
if (mainContent != null) {
mainContent.animate().alpha(0).setDuration(MAIN_CONTENT_FADEOUT_DURATION);
}
}
mDrawerLayout.closeDrawer(GravityCompat.START);
}
Voici le lien de référence: https://github.com/google/iosched/blob/master/Android/src/main/Java/com/google/samples/apps/iosched/ui/BaseActivity.Java
Le gestionnaire de fragments peut être remplacé comme indiqué dans l'article:
https://guides.codepath.com/Android/fragment-navigation-drawer#alternative-to-fragments
Vous pouvez gonfler une mise en page au lieu d'utiliser un gestionnaire de fragments.