【问题标题】:Display fragments with Navigation Drawer使用导航抽屉显示片段
【发布时间】:2015-10-16 09:44:43
【问题描述】:

我很困惑如何通过单击导航抽屉中的一个项目来打开我的不同片段。

在 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;
}

首先我想尝试打开我的 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);
    }
}

在我的内容 main.xml 中,我创建了以下片段,当单击导航抽屉中的特定项目时应将其替换。

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

但它不起作用......

谁能帮帮我?

拉斯塔曼

【问题讨论】:

  • 有什么错误吗?还是片段没有替换?
  • 不,我使用设计工具手动添加我的 fragment_list 片段。现在我在屏幕上看到了它,但是如果我点击导航抽屉中的“列表”项,我会在片段中间看到加载圈,没有任何反应。
  • 您是否尝试过添加或实现其他片段?
  • 啊。情况正在好转。我添加了 AddDataFragment,现在我可以在 Fragment 之间切换。但是 ListFragment 总是在后台。我认为列表片段没有替换......(加载圈似乎是 ListFragment 中的 ListView 没有得到任何数据)
  • 现在我可以在我的 2 个片段之间切换。但我认为我的 listfragment xml 有问题。只有装载圈。第二个问题是我必须使用“PlaceholderFragment”来防止片段相互重叠。但是现在我的第一个屏幕只是白色的......

标签: java android xml fragment


【解决方案1】:

为了得到你想要的,试试这个,我也被这个看起来有点复杂的代码所困扰,但它更容易使用

这里有详细的解释和解决这个问题: (看起来很长,但您可以轻松地尽快关联您的工作)

当您第一次创建 Navigation Drawer Activity 时,我们将查看 5 个文件:

  • MainActivity.java - 这是我们应用中所有内容的代码。
  • activity_main.xml - 这是应用的布局,包括导航抽屉和 app_bar_main 的包含。
  • app_bar_main.xml - 这是带有工具栏(在顶部)、浮动操作按钮(在右下角)和 content_main 的包含的布局。
  • content_main.xml - 这是主页内容的布局。
  • nav_header_main.xml - 这是导航抽屉顶部的 UI。

第 1 步: 打开 app_bar_main.xml,注释掉包含并添加一个新的 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"/>

这个 FrameLayout 是我们用来加载片段的地方。

第 2 步: 接下来,您需要添加一些片段 为此,请右键单击您的项目,或转到 File -> New,然后从 Fragment 列表中选择 Fragment (Blank) 或其他

第 3 步: 下一步是在应用首次启动时加载片段。转到 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();

第 4 步:

然后您需要将 OnFragmentInteractionListener 添加到您的 MainActivity 实现的接口中,并实现 onFragmentInteraction 方法。像这样

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

第 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;
}

这里我只是加载我添加到我的应用程序的两个片段之一。请注意,因为我有两个不同的片段,所以我必须同时实现 FragmentOne.OnFragmentInteractionListener 和 FragmentTwo.OnFragmentInteractionListener 的接口。

这就是在导航抽屉中实现片段加载所需要做的一切。 用户点击菜单项,抽屉将顺利滑回,新片段已经开始/完成加载。这还可以防止您在启动新活动时看到的任何可能的卡顿。

额外 最后要注意的是,如果您切换到不同的片段,然后旋转设备或重新创建活动,上面的代码将导致第一个片段被重新加载。一种简单的处理方法是将片段块包装在 onCreate 方法中,以检查 savedInstanceState 是否不为 null,如下所示:

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

【讨论】:

    【解决方案2】:

    试试这个代码

    @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" />

    【讨论】:

    • 错误:(116, 37) 错误:变量片段可能尚未初始化
    • 我添加了:public boolean onNavigationItemSelected(MenuItem item) { Fragment fragment; FragmentTransaction ft = getSupportFragmentManager().beginTransaction();片段 = 新的 ListFragment();将标准片段初始化为 ListFragment。但它没有用..但一般的代码似乎是正确的。我可以通过这种方式打开我的 AddDataFragment。但我没有弄错 ListFragment...
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      嗯,我找到了答案。但我很困惑。 如果我使用:

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

      它有效。但是如果我想打开我的 ListFragment,我只需要使用包名。为什么?

      【讨论】:

      • 官方有一个类叫“ListFragment”。重命名后工作正常。
      【解决方案5】:

      我建议创建更动态的代码

      首先,如果您有自定义类来创建导航抽屉,请使用侦听器从您的活动中调用方法 有类调用 HomeFragment extends Fragment,所以我们有:

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

      【讨论】:

        【解决方案6】:
        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();
        
        }
        
        
        
        // ...
        

        }

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-04-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多