Fragment中集成Navigation Drawer添加Drawer Toggle后应用崩溃如何解决?
问题修复方案
核心崩溃原因
崩溃主要来自以下几个常见错误点:
- 承载Fragment的Activity使用了自带ActionBar的主题,与Fragment中动态设置的Toolbar冲突
- 在
onCreateView中直接操作宿主Activity,没有做空指针判断,Fragment未完全绑定到Activity时触发空指针异常 - 导包错误,混用了androidx和旧版support包的DrawerLayout、ActionBarDrawerToggle类
- 未在
strings.xml中定义nav_open_drawer、nav_close_drawer对应的字符串资源,触发资源找不到异常
修复步骤
- 修改Activity主题
确保承载该Fragment的Activity在AndroidManifest.xml中配置的主题为不带ActionBar的类型,示例:
<activity android:name=".YourHostActivity" android:theme="@style/Theme.MaterialComponents.DayNight.NoActionBar" />
- 调整Fragment代码逻辑
将Drawer相关初始化逻辑移到onViewCreated中执行,增加非空判断,补充生命周期回调处理状态同步和资源释放,修改后的代码如下:
// 导包请确保全为androidx版本 import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; import androidx.drawerlayout.widget.DrawerLayout; import androidx.appcompat.app.ActionBarDrawerToggle; import androidx.fragment.app.Fragment; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import android.content.res.Configuration; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.annotation.Nullable; public class TestListFragment extends Fragment { private RecyclerView testRecycler; private String[] names; private DrawerLayout drawer; private ActionBarDrawerToggle toggle; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 允许Fragment参与菜单创建 setHasOptionsMenu(true); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_test_list, container, false); } @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); // 先校验宿主Activity有效性 AppCompatActivity activity = (AppCompatActivity) getActivity(); if (activity == null || activity.isFinishing() || activity.isDestroyed()) { return; } Toolbar toolbar = view.findViewById(R.id.toolbar); activity.setSupportActionBar(toolbar); drawer = view.findViewById(R.id.drawer_layout); toggle = new ActionBarDrawerToggle(activity, drawer, toolbar, R.string.nav_open_drawer, R.string.nav_close_drawer); drawer.addDrawerListener(toggle); toggle.syncState(); testRecycler = view.findViewById(R.id.test_recycler); LinearLayoutManager layoutManager = new LinearLayoutManager(activity); testRecycler.setLayoutManager(layoutManager); names = new String[Test.testData.length]; for(int i = 0; i < names.length; i++) { names[i] = Test.testData[i].getTitle(); } TestAdapter adapter = new TestAdapter(names); testRecycler.setAdapter(adapter); } @Override public void onConfigurationChanged(@NonNull Configuration newConfig) { super.onConfigurationChanged(newConfig); if (toggle != null) { toggle.onConfigurationChanged(newConfig); } } @Override public void onDestroyView() { // 移除监听器避免内存泄漏 if (drawer != null && toggle != null) { drawer.removeDrawerListener(toggle); } super.onDestroyView(); } }
- 校验字符串资源
打开res/values/strings.xml,确认存在以下两个字符串定义:
<string name="nav_open_drawer">打开侧滑菜单</string> <string name="nav_close_drawer">关闭侧滑菜单</string>
完成以上修改后即可解决崩溃问题。
内容的提问来源于stack exchange,提问作者fl4me
相关产品推荐
相关产品推荐

