it-swarm.com.de

Navigation Drawer zum Wechseln von Aktivitäten anstelle von Fragmenten

Ist es möglich, eine Navigationsleiste in Android zu verwenden, aber anstatt Fragmente zu aktualisieren, möchte ich zwischen den Aktivitäten als Navigationsmittel innerhalb der App wechseln.

44
Little Tiny Dev

Ja, es ist möglich - das habe ich für meine App getan. Ich hatte bereits eine Reihe von Aktivitäten eingerichtet, und anstatt sie alle in Fragmente zu konvertieren, wollte ich die Navigationsleiste so anpassen, dass sie für alle Aktivitäten geeignet ist. Leider ist dies keine schnelle Problemumgehung. Wenn Sie also die Möglichkeit haben, Fragmente zu verwenden, würde ich dies tun. Aber egal wie ich es gemacht habe:

Nehmen wir an, ich habe zwei Aktivitäten, von denen ich die Navigationsschublade haben möchte. In der layout.xml habe ich jeweils eine DrawerLayout mit der entsprechenden ListView angegeben, um meine Navigationsoptionen zu speichern. Im Wesentlichen wird die Navigationsleiste jedes Mal erstellt, wenn ich zwischen den Aktivitäten wechsle, was den Eindruck vermittelt, dass sie bestehen bleibt. Um das Leben viel einfacher zu machen, habe ich die üblichen Methoden zum Einrichten der Navigationsleiste verwendet und sie in eine eigene Klasse eingeordnet: NavigationDrawerSetup.Java. Auf diese Weise können meine Aktivitäten denselben benutzerdefinierten Adapter usw. verwenden.

Innerhalb dieser NavigationDrawerSetup.Java-Klasse habe ich Folgendes:

  • configureDrawer() - Damit werden die ActionBar, ActionBarDrawerToggle und die erforderlichen Listener eingerichtet
  • Mein benutzerdefinierter Array-Adapter (zum Auffüllen der Navigationsoptionen in der Liste)
  • Die selectOptions()-Methode, die Klicks der Schubladenelemente verarbeitet

Wenn Sie die Navigationsleiste in einer Ihrer Aktivitäten einrichten, erstellen Sie einfach ein neues NavigationDrawerSetup-Objekt und übergeben die erforderlichen Layout-Parameter (wie DrawerLayout, ListView usw.). Dann rufen Sie configureDrawer() an:

        navigationDrawer = new NavigationDrawerSetup(mDrawerView, mDrawerLayout,
            mDrawerList, actionBar, mNavOptions, currentActivity);

    navigationDrawer.configureDrawer();

currentActivity wird übergeben, da die Navigationsleiste an die Aktivität gebunden ist, in der Sie sich gerade befinden. Sie müssen es verwenden, wenn Sie ActionBarDrawerToggle einrichten:

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 */
        )

Sie müssen auch currentActivity verwenden, wenn Sie Ihr benutzerdefiniertes Adapter einrichten:

Um zwischen den Aktivitäten über die Navigationsleiste zu wechseln, können Sie einfach neue Intents in Ihrer selectItem () -Methode einrichten:

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

Stellen Sie einfach sicher, dass Ihr neues Activity auch die Navigationsschublade eingerichtet hat und angezeigt werden sollte.

Es gibt eine Menge Dinge, die Sie tun können, um diese Methode an Ihre eigenen Bedürfnisse anzupassen. Dies ist jedoch die allgemeine Struktur meiner Vorgehensweise. Hoffe das hilft!

46
David Crozier

Sie benötigen eine BaseDrawerActivity, die die Navigationsablage implementiert und dann die BaseDrawerActivity in jeder Aktivität erweitert, die Sie für die Navigationsablage benötigen.

Erstellen Sie zuerst 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;
    }
}

erstellen Sie dann activity_base_drawer.xml im res/layout-Ordner:

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

wo @layout/app_bar_home ist:

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

Als Nächstes geben Sie Ihre Aktivitäten ein, die über eine Navigationsleiste verfügen, beispielsweise 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);
    }
}

Dabei ist R.layout.activity_camera Ihr Layout für CameraActivity.Java.

Dann erstellen Sie andere Aktivitäten wie GalleryActivity.Java und so weiter, die über die Navigationsleiste verfügen:

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

Als kleine Verbesserung der von @ David-Crozier angegebenen Lösung können Sie, um die Überlappung beider Animationen (Schließen des NavigationDrawer und Starten einer neuen Aktivität) zu vermeiden, Ihrer Methode eine kleine Verzögerung hinzufügen, wie in der iosched-App 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);
}

Hier der Link als Referenz: https://github.com/google/iosched/blob/master/Android/src/main/Java/com/google/samples/apps/iosched/ui/BaseActivity.Java

2
narko

Der Fragmentmanager kann wie im Beitrag erwähnt ersetzt werden:

https://guides.codepath.com/Android/fragment-navigation-drawer#alternative-to-fragments

Sie können ein Layout aufblasen, anstatt einen Fragmentmanager zu verwenden.

0
Logan