简体   繁体   English

使用导航抽屉显示片段

[英]Display fragments with Navigation Drawer

I'm confused how to open my different fragments by clicking on one Item in my navigation drawer. 我很困惑如何通过单击导航抽屉中的一项来打开我的不同片段。

In MainActivity I use the following Code: 在MainActivity中,我使用以下代码:

 @SuppressWarnings("StatementWithEmptyBody") @Override public boolean onNavigationItemSelected(MenuItem item) { Fragment fragment; int id = item.getItemId(); if (id == R.id.nav_listview) { FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); ft.replace(R.id.fragment, new ListFragment()); ft.commit(); } else if (id == R.id.nav_add_data) { } else if (id == R.id.nav_settings) { } else if (id == R.id.nav_legal_information) { } DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); drawer.closeDrawer(GravityCompat.START); return true; } 

First of all I want to try to open my ListFragment: 首先,我想尝试打开我的ListFragment:

 import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; public class ListFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_list, container, false); } } 

In my content main.xml I created the following fragment which should be replaced when clicking on the specific Items in the Navigation Drawer. 在我的内容main.xml中,我创建了以下片段,当单击导航抽屉中的特定项目时,应将其替换。

  <fragment android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/fragment" /> 

But it isnt working... 但这是行不通的...

Can anyone help me? 谁能帮我?

Rastaman 拉斯塔曼

To get what you want try this ,I was also held up with this somewhat complex looking code but its more of a easy way to use 要获得您想要的内容,请尝试使用这个看起来有些复杂的代码,但它更易于使用

Here's detailed explanation and walk through to this issue: (Its seems Long But You can easily relate your work asap) 这里是详细的解释并逐步解决此问题:(似乎很长,但您可以尽快将您的工作关联起来)

When you first create the Navigation Drawer Activity, there are 5 files we'll look at: 首次创建导航抽屉活动时,我们将查看5个文件:

  • MainActivity.java - this is the code behind for everything in our app. MainActivity.java-这是我们应用程序中所有内容的代码。
  • activity_main.xml - this is the layout for the app including the nav drawer and an include for the app_bar_main. activity_main.xml-这是应用程序的布局,包括导航抽屉和app_bar_main的包含。
  • app_bar_main.xml - this is the layout with the toolbar (at the top), a floating action button (at the bottom right), and an include for content_main. app_bar_main.xml-这是带有工具栏(位于顶部),一个浮动操作按钮(位于右下方)以及content_main的包含的布局。
  • content_main.xml - this is the layout for the content of the main page. content_main.xml-这是主页内容的布局。
  • nav_header_main.xml - this is the UI for the top part of the nav drawer. nav_header_main.xml-这是导航抽屉顶部的UI。

Step 1: open up the app_bar_main.xml , comment out the include and add a new FrameLayout: 步骤1:打开app_bar_main.xml ,注释掉include并添加一个新的FrameLayout:

<!--<include layout="@layout/content_main" />-->

<FrameLayout
  android:id="@+id/Fragment_container"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:layout_marginTop="?attr/actionBarSize"/>

This FrameLayout is what we'll use to load our fragments into. 这个FrameLayout是我们用来将片段加载到其中的东西。

Step 2: Next, you'll want to add a few fragments To do so, right click on your project, or go to File –> New and from the Fragment list choose Fragment (Blank) or others 步骤2:接下来,您将要添加一些片段为此,请右键单击您的项目,或转到File –> New,然后从Fragment列表中选择Fragment(空白)或其他。

Step 3: The next step is to load a fragment when the app first launches. 步骤3:下一步是在应用首次启动时加载片段。 Go to the MainActivity ’s onCreate method and put the following in after the call to setSupportActionBar : 转到MainActivity的onCreate方法,然后在调用setSupportActionBar之后添加以下内容

Fragment fragment = null;
Class fragmentClass = null;
fragmentClass = FragmentOne.class;
try {
    fragment = (Fragment) fragmentClass.newInstance();
} catch (Exception e) {
    e.printStackTrace();
}

FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.Fragment_container, fragment).commit();

Step 4: 第四步:

You'll then need to add OnFragmentInteractionListener to the interfaces your MainActivity implements and also implement the onFragmentInteraction method.Like this 然后,您需要向您的MainActivity实现的接口添加OnFragmentInteractionListener并实现onFragmentInteraction方法。

public class MainActivity extends AppCompatActivity
        implements NavigationView.OnNavigationItemSelectedListener, FragmentOne.OnFragmentInteractionListener ,FragmentTwo.OnFragmentInteractionListener,FragmentThree.OnFragmentInteractionListener {

Step 5: Finally, in the onNavigationItemSelected method, you can add the ability to load different fragments when menu items are tapped: 步骤5:最后,在onNavigationItemSelected方法中,您可以添加点击菜单项时加载不同片段的功能:

public boolean onNavigationItemSelected(MenuItem item) {
    // Handle navigation view item clicks here.
    int id = item.getItemId();
    Fragment fragment = null;
    Class fragmentClass = null;
    if (id == R.id.nav_camera) {
        fragmentClass = FragmentOne.class;
    } else if (id == R.id.nav_gallery) {
        fragmentClass = FragmentTwo.class;
    } else if (id == R.id.nav_slideshow) {
        fragmentClass = FragmentThree.class;
    } else if (id == R.id.nav_manage) {

    } else if (id == R.id.nav_share) {

    } else if (id == R.id.nav_send) {

    }
    try {
        fragment = (Fragment) fragmentClass.newInstance();
    } catch (Exception e) {
        e.printStackTrace();
    }
    FragmentManager fragmentManager = getSupportFragmentManager();
    fragmentManager.beginTransaction().replace(R.id.flContent, fragment).commit();

    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    drawer.closeDrawer(GravityCompat.START);
    return true;
}

Here I'm just loading one of the two fragments I've added to my app. 在这里,我只是加载我添加到我的应用程序的两个片段之一。 Note that because I have two different fragments, I had to implement the interfaces for both FragmentOne.OnFragmentInteractionListener and FragmentTwo.OnFragmentInteractionListener. 请注意,因为我有两个不同的片段,所以必须为FragmentOne.OnFragmentInteractionListener和FragmentTwo.OnFragmentInteractionListener都实现接口。

That's all you need to do to implement fragment loading in your Navigation Drawer. 这是在导航抽屉中实现片段加载所需要做的全部工作。 What the user taps a menu item, the drawer will slide back in smoothly and the new fragment will have already started / finished loading. 用户点击菜单项后,抽屉将顺利滑入,新片段将已经开始/完成加载。 This also prevents any possible jankiness that you could see when launching a new activity. 这还可以防止您在启动新活动时看到的任何可能的混乱。

EXTRA One last thing to note is that if you switch to a different fragment and then rotate the device or cause another recreation of the activity, the code above will cause the first fragment to be reloaded. 额外要注意的最后一件事是,如果您切换到另一个片段,然后旋转设备或导致重新进行该活动,则上面的代码将导致重新加载第一个片段。 One easy way to deal with that is to wrap the fragment block in the onCreate method in a check to see if the savedInstanceState is not null like this: 一种简单的处理方法是,将片段块包装在onCreate方法中,以检查一下saveInstanceState是否不为null,如下所示:

protected void onCreate(Bundle savedInstanceState) {
    ...
    if (savedInstanceState == null) {
        //Fragment load code
    }
    ...
}

Try this Code 试试这个代码

 @SuppressWarnings("StatementWithEmptyBody") @Override public boolean onNavigationItemSelected(MenuItem item) { Fragment fragment=null; FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); int id = item.getItemId(); if (id == R.id.nav_listview) { fragment= new ListFragment(); } else if (id == R.id.nav_add_data) { } else if (id == R.id.nav_settings) { } else if (id == R.id.nav_legal_information) { } ft.replace(R.id.container, fragment); ft.addToBackStack(null); ft.commit(); DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); drawer.closeDrawer(GravityCompat.START); return true; } 

  <FrameLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/container" /> 

Mhmm I found an answer. 嗯,我找到了答案。 But I am confused. 但是我很困惑。 If I use: 如果我使用:

  if (id == R.id.nav_listview) { fragment= new com.thomas.testapp.ListFragment(); 

It works. 有用。 But I only have to use the package name if I want to open my ListFragment. 但是,如果我要打开ListFragment,则只需使用包名。 Why? 为什么?

请更改您的片段类ListFragment的名称,因为ListFragment已经是android.app android OS中的Fragments的子类

I suggest to Create codes More Dynamic 我建议创建更动态的代码

first of all, if you have custom class to create Navigation Drawer, use listener to call methods from your activity there is class call HomeFragment extends Fragment, so we have : 首先,如果您有用于创建Navigation Drawer的自定义类,请使用侦听器从您的活动中调用方法,其中有类调用HomeFragment扩展Fragment,所以我们有:

if(condition){
    fragment = new HomeFragment();
    // if there is Listener
    if(mListener != null){
        mListener.someMethod
    }
    // Other Settings And Codes
}
public class MainActivity extends AppCompatActivity {



// ...



@Override

protected void onCreate(Bundle savedInstanceState) {

    // ...From section above...

    // Find our drawer view

    nvDrawer = (NavigationView) findViewById(R.id.nvView);

    // Setup drawer view

    setupDrawerContent(nvDrawer);

}



private void setupDrawerContent(NavigationView navigationView) {

    navigationView.setNavigationItemSelectedListener(

            new NavigationView.OnNavigationItemSelectedListener() {

                @Override

                public boolean onNavigationItemSelected(MenuItem menuItem) {

                    selectDrawerItem(menuItem);

                    return true;

                }

            });

}



public void selectDrawerItem(MenuItem menuItem) {

    // Create a new fragment and specify the fragment to show based on nav item clicked

    Fragment fragment = null;

    Class fragmentClass;

    switch(menuItem.getItemId()) {

        case R.id.nav_first_fragment:

            fragmentClass = FirstFragment.class;

            break;

        case R.id.nav_second_fragment:

            fragmentClass = SecondFragment.class;

            break;

        case R.id.nav_third_fragment:

            fragmentClass = ThirdFragment.class;

            break;

        default:

            fragmentClass = FirstFragment.class;

    }



    try {

        fragment = (Fragment) fragmentClass.newInstance();

    } catch (Exception e) {

        e.printStackTrace();

    }



    // Insert the fragment by replacing any existing fragment

    FragmentManager fragmentManager = getSupportFragmentManager();

    fragmentManager.beginTransaction().replace(R.id.flContent, fragment).commit();



    // Highlight the selected item has been done by NavigationView

    menuItem.setChecked(true);

    // Set action bar title

    setTitle(menuItem.getTitle());

    // Close the navigation drawer

    mDrawer.closeDrawers();

}



// ...

} }

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

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