3

我的片段 onSaveInstanceState 有问题。我在 stackoverflow 和其他网站上搜索,我的问题没有完全相同的问题。

我有一个底部导航视图(如果重要的话,它不是 android 支持库底部导航视图)。底部导航视图有 4 个按钮来代表 4 个不同的片段。主页、搜索、通知、个人资料。

在此处输入图像描述

  • 启动 HomeFragment (添加到 backstack )
  • 转到 NotificationsFragment (添加到后台堆栈)
  • 去 SearchFragment (添加到 backstack )
  • 转到 NotificationsFragment(从后台堆栈弹出):但实例状态未保存

这是我的片段生命周期日志。我登录了 Fragment:onSaveInstanceState() 函数,但它没有被调用,所以保存实例状态不会调用。

HomeFragment: onAttach
HomeFragment: onCreate
HomeFragment: onCreateView
HomeFragment: onViewCreated
HomeFragment: onActivityCreated
HomeFragment: onStart
HomeFragment: onResume
NotificationsFragment: onAttach
NotificationsFragment: onCreate
HomeFragment: onPause
HomeFragment: onStop
HomeFragment: onDestroyView
HomeFragment: onDestroy
HomeFragment: onDetach
NotificationsFragment: onCreateView
NotificationsFragment: onViewCreated
NotificationsFragment: onActivityCreated
NotificationsFragment: onStart
NotificationsFragment: onResume
SearchFragment: onAttach
SearchFragment: onCreate
NotificationsFragment: onPause
NotificationsFragment: onStop
NotificationsFragment: onDestroyView
NotificationsFragment: onDestroy
NotificationsFragment: onDetach
SearchFragment: onCreateView
SearchFragment: onViewCreated
SearchFragment: onActivityCreated
SearchFragment: onStart
SearchFragment: onResume
NotificationsFragment: onAttach
NotificationsFragment: onCreate
SearchFragment: onPause
SearchFragment: onStop
SearchFragment: onDestroyView
SearchFragment: onDestroy
SearchFragment: onDetach
NotificationsFragment: onCreateView
NotificationsFragment: onViewCreated
NotificationsFragment: onActivityCreated
NotificationsFragment: onStart
NotificationsFragment: onResume

MainActivity2.java

public class MainActivity2 extends BaseActivity implements FragmentManager.OnBackStackChangedListener {

    private final String TAG = getClass().getSimpleName();

    private static final String TAG_HOME = "home";
    private static final String TAG_SEARCH = "search";
    private static final String TAG_NOTIFICATIONS = "notifications";
    private static final String TAG_PROFILE = "profile";

    @BindView(R.id.btnHome) ImageView btnHome;
    @BindView(R.id.btnSearch) ImageView btnSearch;
    @BindView(R.id.btnNotifications) ImageView btnNotifications;
    @BindView(R.id.btnProfile) ImageView btnProfile;

    private FragmentManager fragmentManager;
    private ImageView selectedImageButton;

    public MainActivity2() {
        setTAG(TAG);
    }

    @Override
    public void onBackPressed() {
        int entryCount = fragmentManager.getBackStackEntryCount();

        // if first fragment is not on screen, just pop back to the previous fragment.
        if (entryCount > 1) {
            fragmentManager.popBackStack();
            return;
        }

        // if first fragment is showing, then finish the activity.
        finish();
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_activity);

        ButterKnife.bind(this);

        fragmentManager = getSupportFragmentManager();

        onHome();

        fragmentManager.addOnBackStackChangedListener(this);
    }

    @Override
    public void onBackStackChanged() {
        Log.v(TAG, "entryCount : " + fragmentManager.getBackStackEntryCount());
        Fragment fragment = fragmentManager.findFragmentById(R.id.container);
        String tag = null;
        if (fragment instanceof HomeFragment) {
            tag = TAG_HOME;
        } else if (fragment instanceof SearchFragment) {
            tag = TAG_SEARCH;
        } else if (fragment instanceof NotificationsFragment) {
            tag = TAG_NOTIFICATIONS;
        } else if (fragment instanceof ProfileFragment) {
            tag = TAG_PROFILE;
        }

        handleTitle(tag);
    }

    private void handleTitle(String tag) {
        switch (tag) {
            case TAG_HOME:
                setTitle("Home");
                break;
            case TAG_SEARCH:
                setTitle("Search");
                break;
            case TAG_NOTIFICATIONS:
                setTitle("Notifications");
                break;
            case TAG_PROFILE:
                setTitle("Profile");
                break;
        }
    }

    private void changeFragment(Fragment fragment, String tag, boolean addBackStack) {
        KeyboardUtils.hideKeyboard(this);

        Fragment existFragment = fragmentManager.findFragmentByTag(tag);

        if (existFragment == null) {
            // fragment not in back stack, create it.
            FragmentTransaction ft = fragmentManager.beginTransaction();
            ft.replace(R.id.container, fragment, tag);
            if (addBackStack)
                ft.addToBackStack(tag);
            ft.commit();
            Log.w(TAG, tag + " added to the backstack");
        } else {
            // fragment in back stack, call it back.
            FragmentTransaction ft = fragmentManager.beginTransaction();
            ft.replace(R.id.container, existFragment, tag);
            ft.commit();
            Log.w(TAG, tag + " fragment returned back from backstack");
        }
    }

    private void onBottomBarViewSelected(Fragment fragment, String tag, ImageView btnSelected, boolean addToBackStack) {
        // this control will avoid re-selected same fragment.
        if (selectedImageButton == btnSelected)
            return;

        changeFragment(fragment, tag, addToBackStack);
        selectedImageButton = btnSelected;
    }

    @OnClick(R.id.btnHome)
    public void onHome() {
        onBottomBarViewSelected(HomeFragment.newInstance(), TAG_HOME, btnHome, true);
    }

    @OnClick(R.id.btnSearch)
    public void onSearch() {
        onBottomBarViewSelected(SearchFragment.newInstance(), TAG_SEARCH, btnSearch, true);
    }

    @OnClick(R.id.btnNotifications)
    public void onNotifications() {
        onBottomBarViewSelected(NotificationsFragment.newInstance(), TAG_NOTIFICATIONS, btnNotifications, true);
    }

    @OnClick(R.id.btnProfile)
    public void onProfile() {
        onBottomBarViewSelected(ProfileFragment.newInstance(), TAG_PROFILE, btnProfile, true);
    }
}

BottomNavigationView 片段的示例片段之一

NotificationsFragment.java

public class NotificationsFragment extends BaseFragment implements NotificationsView,
        NotificationsAdapter.NotificationsListener {

    private final String TAG = getClass().getSimpleName();

    @BindView(R.id.recyclerView) RecyclerView recyclerView;
    @BindView(R.id.swipeRefreshLayout) SwipeRefreshLayout swipeRefreshLayout;
    @BindView(R.id.txtEmpty) TextView txtEmpty;

    private NotificationsPresenter presenter;
    private NotificationsAdapter adapter;

    public static NotificationsFragment newInstance() {
        NotificationsFragment fragment = new NotificationsFragment();
        Bundle args = new Bundle();
        // put args
        fragment.setArguments(args);
        return fragment;
    }

    public NotificationsFragment() {
        setTAG(TAG);
        setHasOptionsMenu(false);
        setRetainInstance(false);
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initArguments();
        initVariables();
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);
        View rootView = inflater.inflate(R.layout.notifications_fragment, container, false);
        ButterKnife.bind(this, rootView);
        initializeLayout();
        presenter.attachView(this);
        return rootView;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        fetchNotifications();
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        Log.wtf(TAG, "onSaveInstanceState");
        super.onSaveInstanceState(outState);
    }

    @Override
    public void onDestroy() {
        presenter.destroy();
        super.onDestroy();
    }

    private void fetchNotifications() {
        presenter.fetchNotifications();
    }

    @Override
    protected void initializeLayout() {
        swipeRefreshLayout.setOnRefreshListener(this::fetchNotifications);
        swipeRefreshLayout.setColorSchemeResources(R.color.colorSwipeProgress);

        recyclerView.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false));

        recyclerView.addItemDecoration(new DividerItemDecoration(getContext()));

        recyclerView.setAdapter(adapter);

        ((SimpleItemAnimator) recyclerView.getItemAnimator()).setSupportsChangeAnimations(false);
    }

    @Override
    protected void initVariables() {
        presenter = new NotificationsPresenter();
        adapter = new NotificationsAdapter(this);
    }

    @Override
    protected void initArguments() {
        // init arguments
    }
}

编辑我刚刚添加了主屏幕图像。

4

0 回答 0