简体   繁体   English

导航抽屉切换活动而不是片段

[英]Navigation Drawer to switch activities instead of fragments

是否可以在Android中使用导航抽屉,但不是更新片段,我想在应用程序中切换活动作为我的导航方式。

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. 假设我有2个活动,我想拥有导航抽屉。 In the layout.xml for each, I specified a DrawerLayout with the appropriate ListView to hold my navigation options. 在每个的layout.xml中,我使用适当的ListView指定了一个DrawerLayout来保存我的导航选项。 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 . 为了让生活更轻松,我采用了设置导航抽屉所需的常用方法并将它们放在自己的类中: NavigationDrawerSetup.java That way my activities can use the same custom adapter, etc. 这样我的活动可以使用相同的自定义适配器等。

Within this NavigationDrawerSetup.java class, I have the following: 在这个NavigationDrawerSetup.java类中,我有以下内容:

  • configureDrawer() - this sets up the ActionBar , ActionBarDrawerToggle , and the required listeners configureDrawer() - 这将设置ActionBarActionBarDrawerToggle和必需的侦听器
  • My custom array adapter (to populate the navigation options within the list) 我的自定义数组适配器(用于填充列表中的导航选项)
  • The selectOptions() method, which handles drawer item clicks selectOptions()方法,用于处理抽屉项目点击

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). 在其中一个活动中设置导航抽屉时,只需创建一个新的NavigationDrawerSetup对象并传入所需的布局参数(如DrawerLayoutListView等)。 Then you'd call configureDrawer() : 然后你调用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. 由于导航抽屉与您所在的活动相关联,因此传递了currentActivity You will have to use it when you set up the ActionBarDrawerToggle : 设置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 : 设置自定义Adapter时,还需要使用currentActivity

As for how to switch between activities via the navigation drawer, you can just set up new intents within your selectItem() method: 至于如何通过导航抽屉切换活动,您可以在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.
    }

Just make sure that your new Activity also has the navigation drawer setup and it should display. 只需确保您的新Activity也有导航抽屉设置,它应该显示。

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! 希望这可以帮助!

You need a BaseDrawerActivity which implement the Navigation Drawer then extend the BaseDrawerActivity in each activity you need Navigation Drawer. 您需要BaseDrawerActivity来实现Navigation Drawer,然后在您需要导航抽屉的每个活动中扩展BaseDrawerActivity

First create BaseDrawerActivity.java : 首先创建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: 然后在res/layout文件夹中创建activity_base_drawer.xml

<?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: 其中@layout/app_bar_home是:

<?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 : 接下来,您将输入具有导航抽屉的活动,例如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 . R.layout.activity_cameraCameraActivity.java的布局。

Then create other Activity like GalleryActivity.java and so on that will have Navigation Drawer: 然后创建像GalleryActivity.java这样的其他Activity,它将具有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);
    }
}

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: 作为@David-Crozier指出的解决方案的一点改进,为了避免两个动画的重叠(关闭NavigationDrawer并开始一个新的活动),你可以像在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 这里有参考链接: https//github.com/google/iosched/blob/master/android/src/main/java/com/google/samples/apps/iosched/ui/BaseActivity.java

The Fragment manager can be replaced as mentioned in the post: 片段管理器可以替换为帖子中提到的:

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

You can inflate a layout instead of using a fragment manager. 您可以膨胀布局而不是使用片段管理器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM