导航抽屉中的片段未加载并导致应用程序崩溃。我能做些什么?
Fragment in Navigation Drawer not loading and makes the app crash. What can I do?
因此,我使用以下代码为我的程序构建了一个导航抽屉:
这是主要的xml:
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".HomeScreen">
<include
android:id="@+id/eb_bar"
layout="@layout/eb_bar" />
<FrameLayout
android:id="@+id/main_screen"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/eb_bar"
android:background="@color/frame_layout_bg"/>
</RelativeLayout>
<fragment
android:id="@+id/frag_navigation_drawer"
android:layout_width="@dimen/navigation_drawer_width"
android:layout_height="match_parent"
android:layout_gravity="start"
app:layout="@layout/fragment_navigation_drawer"
android:name="com.myapps.project.NavigationDrawerFragment"
tools:layout="@layout/fragment_navigation_drawer"
/>
</android.support.v4.widget.DrawerLayout>
这是导航抽屉的 xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/navigation_drawer_background"
tools:context="com.myapps.project.NavigationDrawerFragment">
<FrameLayout
android:id="@+id/nav_drawer_frame_logo"
android:layout_width="match_parent"
android:layout_height="160dp"
android:background="@color/splash_screen_bg"
android:elevation="3dp">
<ImageView
android:id="@+id/nav_drawer_logo"
android:layout_width="90dp"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/navigation_drawer_center_logo"
android:layout_marginStart="@dimen/navigation_drawer_center_logo"
android:src="@drawable/logo"
tools:ignore="ContentDescription" />
</FrameLayout>
<ListView
android:id="@+id/nav_drawer_menu_ListView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/nav_drawer_frame_logo"
android:choiceMode="singleChoice"
android:divider="@color/divider_color"
android:dividerHeight="1dp"
/>
</RelativeLayout>
这是我要加载的片段的 xml:
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/Second_screen"
android:tag="Second"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00F"
tools:context="com.myapps.project.Second_Screen"
android:name="com.myapps.project.Second_Screen"
tools:layout="@layout/fragment_second_screen">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_second_screen" />
</FrameLayout>
我也有两个.java。一个用于主屏幕,一个用于导航抽屉。在主屏幕上我有这个代码:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home_screen);
toolBar = (Toolbar) findViewById(R.id.eb_bar);
setSupportActionBar(toolBar);
getSupportActionBar().setTitle(null);
TextView toolbar_home_title = (TextView) findViewById(R.id.home_toolbar_textview);
toolbar_home_title.setText(R.string.home_screen_title);
toolbar_home_title.setTextColor(getResources().getColor(R.color.toolbar_txt_color));
toolBar.setBackgroundColor(getResources().getColor(R.color.toolbar_bg));
NavigationDrawerFragment drawerFragment = (NavigationDrawerFragment)
getSupportFragmentManager().findFragmentById(R.id.frag_navigation_drawer);
navDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
drawerFragment.setUp(R.id.frag_navigation_drawer,
navDrawerLayout, toolBar);
navDrawerMenuItems = getResources().getStringArray(R.array.navigation_drawer_items);
navDrawerListView = (ListView) findViewById(R.id.nav_drawer_menu_ListView);
FragNavigationDrawer = (FrameLayout) findViewById(R.id.frag_navigation_drawer);
navDrawerListView.setAdapter(new ArrayAdapter<String>(
this,
R.layout.navigation_drawer_list_item,
navDrawerMenuItems));
navDrawerListView.setOnItemClickListener(new DrawerItemClickListener());
}
public class DrawerItemClickListener implements ListView.OnItemClickListener {
@Override
public void onItemClick(AdapterView parent, View view, int position, long id) {
selectItem(position);
}
}
public void selectItem(int position) {
String a = navDrawerMenuItems[position];
Fragment navFragment = getSupportFragmentManager().findFragmentByTag(a);
android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.main_screen, navFragment)
.commit();
navDrawerListView.setItemChecked(position,true);
navDrawerLayout.closeDrawer(FragNavigationDrawer);
}
navDrawerMenuItems 数组具有加载到抽屉中作为可点击项目的名称。它们也是我要在屏幕上加载的每个片段的标签。因此,我在 selectItem 中尝试做的是通过其标签加载片段,将其替换到主屏幕上并在最后关闭抽屉。
但是这段代码显示错误:
2449-2449/com.myapps.project E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.myapps.project, PID: 2449
java.lang.NullPointerException: Attempt to write to field 'android.support.v4.app.FragmentManagerImpl android.support.v4.app.Fragment.mFragmentManager' on a null object reference
at android.support.v4.app.BackStackRecord.doAddOp(BackStackRecord.java:416)
at android.support.v4.app.BackStackRecord.replace(BackStackRecord.java:451)
at android.support.v4.app.BackStackRecord.replace(BackStackRecord.java:443)
at com.myapps.project.MainScreen.selectItem(MainScreen.java:106)
at com.myapps.project.MainScreen$DrawerItemClickListener.onItemClick(MainScreen.java:88)
at android.widget.AdapterView.performItemClick(AdapterView.java:300)
at android.widget.AbsListView.performItemClick(AbsListView.java:1143)
at android.widget.AbsListView$PerformClick.run(AbsListView.java:3044)
at android.widget.AbsListView.run(AbsListView.java:3833)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
我做错了什么?
您应该导入 android.support。v4.app.FragmentManager 而不是 android.app.FragmentManager。
然后试试这个
FragmentManager fragmentManager = getSupportFragmentManager();
更新
你能检查一下吗?
<fragment
android:id="@+id/frag_navigation_drawer">
xml 中的上一行是片段的 id。您将其作为框架布局投射到 java 文件中。
FragNavigationDrawer = (FrameLayout) findViewById(R.id.frag_navigation_drawer);
因此,我使用以下代码为我的程序构建了一个导航抽屉:
这是主要的xml:
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".HomeScreen">
<include
android:id="@+id/eb_bar"
layout="@layout/eb_bar" />
<FrameLayout
android:id="@+id/main_screen"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/eb_bar"
android:background="@color/frame_layout_bg"/>
</RelativeLayout>
<fragment
android:id="@+id/frag_navigation_drawer"
android:layout_width="@dimen/navigation_drawer_width"
android:layout_height="match_parent"
android:layout_gravity="start"
app:layout="@layout/fragment_navigation_drawer"
android:name="com.myapps.project.NavigationDrawerFragment"
tools:layout="@layout/fragment_navigation_drawer"
/>
</android.support.v4.widget.DrawerLayout>
这是导航抽屉的 xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/navigation_drawer_background"
tools:context="com.myapps.project.NavigationDrawerFragment">
<FrameLayout
android:id="@+id/nav_drawer_frame_logo"
android:layout_width="match_parent"
android:layout_height="160dp"
android:background="@color/splash_screen_bg"
android:elevation="3dp">
<ImageView
android:id="@+id/nav_drawer_logo"
android:layout_width="90dp"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/navigation_drawer_center_logo"
android:layout_marginStart="@dimen/navigation_drawer_center_logo"
android:src="@drawable/logo"
tools:ignore="ContentDescription" />
</FrameLayout>
<ListView
android:id="@+id/nav_drawer_menu_ListView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/nav_drawer_frame_logo"
android:choiceMode="singleChoice"
android:divider="@color/divider_color"
android:dividerHeight="1dp"
/>
</RelativeLayout>
这是我要加载的片段的 xml:
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/Second_screen"
android:tag="Second"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00F"
tools:context="com.myapps.project.Second_Screen"
android:name="com.myapps.project.Second_Screen"
tools:layout="@layout/fragment_second_screen">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_second_screen" />
</FrameLayout>
我也有两个.java。一个用于主屏幕,一个用于导航抽屉。在主屏幕上我有这个代码:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home_screen);
toolBar = (Toolbar) findViewById(R.id.eb_bar);
setSupportActionBar(toolBar);
getSupportActionBar().setTitle(null);
TextView toolbar_home_title = (TextView) findViewById(R.id.home_toolbar_textview);
toolbar_home_title.setText(R.string.home_screen_title);
toolbar_home_title.setTextColor(getResources().getColor(R.color.toolbar_txt_color));
toolBar.setBackgroundColor(getResources().getColor(R.color.toolbar_bg));
NavigationDrawerFragment drawerFragment = (NavigationDrawerFragment)
getSupportFragmentManager().findFragmentById(R.id.frag_navigation_drawer);
navDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
drawerFragment.setUp(R.id.frag_navigation_drawer,
navDrawerLayout, toolBar);
navDrawerMenuItems = getResources().getStringArray(R.array.navigation_drawer_items);
navDrawerListView = (ListView) findViewById(R.id.nav_drawer_menu_ListView);
FragNavigationDrawer = (FrameLayout) findViewById(R.id.frag_navigation_drawer);
navDrawerListView.setAdapter(new ArrayAdapter<String>(
this,
R.layout.navigation_drawer_list_item,
navDrawerMenuItems));
navDrawerListView.setOnItemClickListener(new DrawerItemClickListener());
}
public class DrawerItemClickListener implements ListView.OnItemClickListener {
@Override
public void onItemClick(AdapterView parent, View view, int position, long id) {
selectItem(position);
}
}
public void selectItem(int position) {
String a = navDrawerMenuItems[position];
Fragment navFragment = getSupportFragmentManager().findFragmentByTag(a);
android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.main_screen, navFragment)
.commit();
navDrawerListView.setItemChecked(position,true);
navDrawerLayout.closeDrawer(FragNavigationDrawer);
}
navDrawerMenuItems 数组具有加载到抽屉中作为可点击项目的名称。它们也是我要在屏幕上加载的每个片段的标签。因此,我在 selectItem 中尝试做的是通过其标签加载片段,将其替换到主屏幕上并在最后关闭抽屉。 但是这段代码显示错误:
2449-2449/com.myapps.project E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.myapps.project, PID: 2449
java.lang.NullPointerException: Attempt to write to field 'android.support.v4.app.FragmentManagerImpl android.support.v4.app.Fragment.mFragmentManager' on a null object reference
at android.support.v4.app.BackStackRecord.doAddOp(BackStackRecord.java:416)
at android.support.v4.app.BackStackRecord.replace(BackStackRecord.java:451)
at android.support.v4.app.BackStackRecord.replace(BackStackRecord.java:443)
at com.myapps.project.MainScreen.selectItem(MainScreen.java:106)
at com.myapps.project.MainScreen$DrawerItemClickListener.onItemClick(MainScreen.java:88)
at android.widget.AdapterView.performItemClick(AdapterView.java:300)
at android.widget.AbsListView.performItemClick(AbsListView.java:1143)
at android.widget.AbsListView$PerformClick.run(AbsListView.java:3044)
at android.widget.AbsListView.run(AbsListView.java:3833)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
我做错了什么?
您应该导入 android.support。v4.app.FragmentManager 而不是 android.app.FragmentManager。 然后试试这个
FragmentManager fragmentManager = getSupportFragmentManager();
更新
你能检查一下吗?
<fragment
android:id="@+id/frag_navigation_drawer">
xml 中的上一行是片段的 id。您将其作为框架布局投射到 java 文件中。
FragNavigationDrawer = (FrameLayout) findViewById(R.id.frag_navigation_drawer);