web-dev-qa-db-fra.com

Tiroir de navigation pour changer d'activités au lieu de fragments

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.

44
Little Tiny Dev

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 requis
  • Mon adaptateur de baie personnalisé (pour renseigner les options de navigation dans la liste)
  • La méthode selectOptions(), qui gère les clics sur les éléments du tiroir

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

46
David Crozier

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>

@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);
    }
}

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);
    }
}
12
kazi.munshimun

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

2
narko

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.

0
Logan