片段中的视图在选择导航项后返回NullPointerException

问题描述 投票:-2回答:3

我在活动中有一个导航抽屉,用于更新活动中的片段。一切正常,但是当我旋转设备并按其中一个导航抽屉项时,它会崩溃,因为片段中的视图为空。

这里我实现了导航项目的选择。我将数据传递给片段实现的接口方法。

    @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)

android android-activity fragment android-navigation-drawer
3个回答
0
投票

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

0
投票

Android基本设备轮换流程

在正常情况下,当您旋转设备时,您的活动将被销毁并重新创建。

所以在获取片段之前首先检查片段列表的大小。

if(getSupportFragmentManager().getFragments().size() > 0) {
    UpdateGalleries updateGalleries =  (UpdateGalleries) getSupportFragmentManager().getFragments().get(0);
    updateGalleries.fetchGalleriesOf(mSelectedCategory, categoryId);
}

0
投票

问题是因为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"/>
© www.soinside.com 2019 - 2024. All rights reserved.