为什么在屏幕旋转后调用fragment的setText()仅在未重新实例化fragment的情况下有效?

时间:2019-07-06 14:54:48

标签: android android-fragments textview screen-rotation onsaveinstancestate

我找到了解决我以前遇到的问题的解决方案。但是,我仍然不完全了解问题所在。

我有一个显示TextView的片段,当我旋转屏幕时,我尝试将数据保留在该TextView中。以前,即使在使用onSaveInstanceState之后,并且看到文本确实已捆绑保存,使用setText()时也不会设置文本。仅在更改MainActivity中的onCreate方法以检查QuoteFragment之前是否已初始化之后,我的文本才会出现。

为什么会这样?如果仍然保留数据,为什么setText现在可以工作?活动销毁后,FragmentManager是否保留片段的副本,并且setText()以某种方式调用了旧片段?我将展示未更改的片段代码,以及为解决该问题而更改的新旧活动代码:

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    quoteDatabaseManager = new QuoteDatabaseManager(getActivity());

    if(checkSavedQuote(savedInstanceState)) {
        int id = savedInstanceState.getInt(KEY_ID);
        String quote = savedInstanceState.getString(KEY_QUOTE);
        boolean viewed = savedInstanceState.getBoolean(KEY_VIEWED);
        boolean favorite = savedInstanceState.getBoolean(KEY_FAVORITE);

        currentQuote = new Quote(id, quote, viewed, favorite);
        currentQuoteIsFavorite = currentQuote.getFavorite();
        currentQuoteText = currentQuote.getQuote();
        Log.d("TEST", "Inside onCreate");
        Log.d("TEST", currentQuoteText);
    } else {
        ContentValues quoteValues = new ContentValues();
        quoteValues.put("VIEWED",false);
        try {
            quoteDatabaseManager.updateAllQuotes(quoteValues);
        } catch (SQLiteException e) {
            Toast.makeText(mActivity, "Database unavailable", Toast.LENGTH_SHORT).show();
        }
    }
}

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_quote, container, false);
    textViewQuote = view.findViewById(R.id.textview_quote);
    btnFindQuote = view.findViewById(R.id.btn_find_quote);

    btnFindQuote.setOnClickListener(this);

    if(currentQuote !=null) {
        Log.d("TEST","inside onCreateView's if statement");
        textViewQuote.setText(currentQuoteText);
    }

    setHasOptionsMenu(true);

    Log.d("TEST", "onCreateView has finished");
    return view;
}

@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putInt(KEY_ID, currentQuoteId);
    outState.putString(KEY_QUOTE, currentQuoteText);
    outState.putBoolean(KEY_VIEWED, currentQuoteIsViewed);
    outState.putBoolean(KEY_FAVORITE, currentQuoteIsFavorite);
    Log.d("TEST", "onSaveInstanceState called");
}

旧MainActivity的onCreate:

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

    Toolbar toolbar = findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    mToolbarTitle = findViewById(R.id.toolbar_title);

    drawer = findViewById(R.id.drawer_layout);
    NavigationView navigationView = findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);

    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar,
            R.string.navigation_drawer_open, R.string.navigation_drawer_close);
    drawer.addDrawerListener(toggle);
    toggle.syncState();

    initQuoteFragment();
}

private void initQuoteFragment() {
    mQuoteFragment = new QuoteFragment();
    doFragmentTransaction(mQuoteFragment, TAG_QUOTE_FRAGMENT, false);
}

private void doFragmentTransaction(Fragment fragment, String tag, boolean addToBackStack) {
    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

    transaction.replace(R.id.fragment_container, fragment, tag);

    if(addToBackStack) {
        transaction.addToBackStack(tag);
    }
    transaction.commit();
}

新MainActivity的onCreate:

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

    Toolbar toolbar = findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    mToolbarTitle = findViewById(R.id.toolbar_title);

    drawer = findViewById(R.id.drawer_layout);
    NavigationView navigationView = findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);

    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar,
            R.string.navigation_drawer_open, R.string.navigation_drawer_close);
    drawer.addDrawerListener(toggle);
    toggle.syncState();

    //new changes that fixed issue and got setText() to work
    FragmentManager fragmentManager = getSupportFragmentManager();
    Fragment fragment = fragmentManager.findFragmentByTag(TAG_QUOTE_FRAGMENT);

    if(fragment == null) {
        initQuoteFragment();
    } else {
        mQuoteFragment = (QuoteFragment) fragment;
    }
}

0 个答案:

没有答案