我在活动中有一个导航抽屉,用于更新活动中的片段。一切正常,但是当我旋转设备并按其中一个导航抽屉项时,它会崩溃,因为片段中的视图为空。
这里我实现了导航项目的选择。我将数据传递给片段实现的接口方法。
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
// Call interface method that GalleriesFragment implements
UpdateGalleries updateGalleries = (UpdateGalleries) getSupportFragmentManager().getFragments().get(0);
updateGalleries.fetchGalleriesOf(mSelectedCategory, categoryId);
DrawerLayout drawer = findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return false;
}
这是我实现接口方法的片段部分:
@Override
public void fetchGalleriesOf(String category, String categoryId) {
mProgressBar.setVisibility(View.VISIBLE); // progressBar is null
// Listen for firebase values
listenToGalleries();
// Attach listener to reference
if(category.equals("Home")){
category = "Recently added";
References.galleriesRef.orderByChild(Constants.TIMESTAMP).addValueEventListener(mGalleriesListener);
}else {
References.galleriesRef.orderByChild(Constants.CATEGORY_ID).equalTo(categoryId)
.addValueEventListener(mGalleriesListener);
}
mCategoryTV.setText(category);
}// End fetchGalleriesOf
这是activity_main.xml中的片段:
<fragment 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:name="com.thunderbolt.thebolt.ui.fragment.GalleriesFragment"
tools:context=".ui.activity.MainActivity"/>
尽管在片段的onCreateView中初始化它们,片段中的mProgressBar和mCategoryTV仍会返回空指针异常:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_gallery, container, false);
// Reset list
mGalleries = new ArrayList<>();
mGalleriesAdapter = new GalleriesAdapter(mGalleries, this);
mRecyclerView = rootView.findViewById(R.id.rv_galleries);
mRecyclerView.setAdapter(mGalleriesAdapter);
LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.setHasFixedSize(true);
mCategoryTV = rootView.findViewById(R.id.tv_category);
mCategoryTV.setText(mCategory);
mProgressBar = rootView.findViewById(R.id.progress_bar);
mProgressBar.setVisibility(View.VISIBLE);
mNoDataTV = rootView.findViewById(R.id.tv_no_data);
return rootView;
}
编辑:崩溃日志:
E / AndroidRuntime:FATAL EXCEPTION:main进程:com.thunderbolt.thebolt,PID:31441 java.lang.NullPointerException:尝试在com的空对象引用上调用虚方法'void android.widget.ProgressBar.setVisibility(int)' .thunderbolt.thebolt.ui.fragment.GalleriesFragment.fetchGalleriesOf(GalleriesFragment.java:146)位于android.support.design.widget.NavigationView的com.thunderbolt.thebolt.ui.activity.MainActivity.onNavigationItemSelected(MainActivity.java:191)位于android.support.v7.view.menu.SumeMenuBuilder.dispatchMenuItemSelected(SubMenuBuilder.java)的android.support.v7.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:822)$ 1.onMenuItemSelected(NavigationView.java:154): 89)在Android.support.v上的android.support.v7.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:171)android.support.v7.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:973) .internal.NavigationMenuPresenter $ 1.onClick(NavigationMenuPresenter.java:342)在android.view.View.perf ormClick(View.java:5232)at android.view.View $ PerformClick.run(View.java:21289)android.os.Handler.handleCallback(Handler.java:739)android.os.Handler.dispatchMessage(Handler) .java:95)在android.app.Looper.loop(Looper.java:168)的android.app.ActivityThread.main(ActivityThread.java:5885)at java.lang.reflect.Method.invoke(Native Method)at at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:797)at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687)
在Fragment
尝试添加此以保存其数据:
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// Save the fragment's state
setRetainInstance(true);
}
在您的Activity中,不要重新添加片段,否则它们会重叠。来自this:
// However, if we're being restored from a previous state,
// then we don't need to do anything and should return or else
// we could end up with overlapping fragments.
if (savedInstanceState != null) {
return;
}
Android基本设备轮换流程
在正常情况下,当您旋转设备时,您的活动将被销毁并重新创建。
所以在获取片段之前首先检查片段列表的大小。
if(getSupportFragmentManager().getFragments().size() > 0) {
UpdateGalleries updateGalleries = (UpdateGalleries) getSupportFragmentManager().getFragments().get(0);
updateGalleries.fetchGalleriesOf(mSelectedCategory, categoryId);
}
问题是因为xml中的片段声明没有肖像模式的id属性,但是具有横向模式的id。现在我为两者提供了一个id:
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/fragment_galleries"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.thunderbolt.thebolt.ui.fragment.GalleriesFragment"
tools:context=".ui.activity.MainActivity"/>