Navigation Drawer to switch activities instead of fragments

前端 未结 4 1816
庸人自扰
庸人自扰 2020-11-29 15:34

Is it possible to use a navigation drawer in android but instead of updating fragments, i would like to switch between activities as my means of navigation within the app.

相关标签:
4条回答
  • 2020-11-29 16:03

    Yes it is possible - it's what I did for my app. I already had a number of activities set up, and rather than convert them all to fragments, I wanted to tailor the navigation drawer to work across all of them. Unfortunately, it's not a quick workaround, so if you have the option of using fragments, I would go with that. But regardless here's how I did it:

    Let's say I have 2 activities, both of which I want to have the Navigation Drawer. In the layout.xml for each, I specified a DrawerLayout with the appropriate ListView to hold my navigation options. Essentially, the Navigation drawer is made every time I switch between activities, giving the appearance that it is persisting. To make life a lot easier, I took the common methods required to set up the navigation drawer and put them in their own class: NavigationDrawerSetup.java. That way my activities can use the same custom adapter, etc.

    Within this NavigationDrawerSetup.java class, I have the following:

    • configureDrawer() - this sets up the ActionBar, ActionBarDrawerToggle, and the required listeners
    • My custom array adapter (to populate the navigation options within the list)
    • The selectOptions() method, which handles drawer item clicks

    When you set up the navigation drawer within one of your activities, you just create a new NavigationDrawerSetup object and pass in the required layout parameters (like the DrawerLayout, ListView etc). Then you'd call configureDrawer():

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

    currentActivity is passed in since the navigation drawer is tied to the activity you are on. You will have to use it when you set up the 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 */
            )
    

    You will also need to use currentActivity when setting up your custom Adapter:

    As for how to switch between activities via the navigation drawer, you can just set up new intents within your selectItem() method:

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

    Just make sure that your new Activity also has the navigation drawer setup and it should display.

    There are a ton of things you can do to customize this method to your own needs, but this is the general structure of how I did it. Hope this helps!

    0 讨论(0)
  • 2020-11-29 16:09

    As a little improvement to the solution pointed by @David-Crozier, in order to avoid the overlap of both animations (closing the NavigationDrawer and starting a new activity), you can include a little delay in your method as was done in the 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);
    }
    

    Here the link for reference: https://github.com/google/iosched/blob/master/android/src/main/java/com/google/samples/apps/iosched/ui/BaseActivity.java

    0 讨论(0)
  • 2020-11-29 16:27

    The Fragment manager can be replaced as mentioned in the post:

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

    You can inflate a layout instead of using a fragment manager.

    0 讨论(0)
  • 2020-11-29 16:28

    You need a BaseDrawerActivity which implement the Navigation Drawer then extend the BaseDrawerActivity in each activity you need Navigation Drawer.

    First create 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;
        }
    }
    

    then create activity_base_drawer.xml in res/layout folder:

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

    where @layout/app_bar_home is:

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

    Next you enter your Activities that will have Navigation Drawer such as 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);
        }
    }
    

    Where R.layout.activity_camera is your layout for CameraActivity.java.

    Then create other Activity like GalleryActivity.java and so on that will have Navigation Drawer:

    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);
        }
    }
    
    0 讨论(0)
提交回复
热议问题