【问题标题】:Save state of Fragment / View保存片段/视图的状态
【发布时间】:2023-03-08 06:43:01
【问题描述】:

我有一个包含 SearchView 的片段。这个片段包含在我的 HomeActivity 和 SearchResultsActivity 中。

当用户使用 HomeActivity 中的 SearchView 执行搜索时,会在 SearchResultsActivity 中显示结果。

我试图做到这一点,当用户在 HomeActivity 上的 SearchView 中输入查询时,SearchResultsActivity 上的 SearchView 会记住他们的查询字符串。

我已经尝试了this similar issue 的所有建议,但是(与许多其他开发人员一起)似乎唯一可行的解​​决方案似乎并不合适 - 即将查询保存在静态字符串中片段类。

这是我展示这种方法的代码...

`公共类 ProductSearchViewFragment 扩展片段 {

private static final String LOG_TAG = ProductSearchViewFragment.class.getSimpleName();
private static final String KEY_QUERY = "query";

private static String mQuery = null;

public ProductSearchViewFragment() {
    setArguments(new Bundle());
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
    Bundle savedInstanceState) {

    // Inflate the layout for this fragment
    return inflater.inflate(R.layout.fragment_product_search_view, container, false);
}

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

    /*
     * Populate the searchView if there is a previous query
     */
    SearchView searchView = (SearchView)getView().findViewById(R.id.searchView);
    if (mQuery != null) {
        Log.d(LOG_TAG, "######################### Setting searchView query from static String: " + mQuery);
        searchView.setQuery(mQuery, false);
    }
    else {

        Bundle mySavedInstanceState = getArguments();
        String query = mySavedInstanceState.getString(KEY_QUERY);
        if (query != null) {

            // THIS CONDITION IS NEVER MET. I.E., query IS ALWAYS NULL

            Log.d(LOG_TAG, "######################### Setting searchView query from bundle arguments: " + query);
            searchView.setQuery(query, false);
        }
        else {
            Log.d(LOG_TAG, "######################### Not setting searchView query.");
        }
    }
}

/*
 * Unfortunately, onSaveInstanceState(Bundle outState) is not called,
 * so attempt to save the query in our own arguments bundle.
 * 
 */
@Override
public void onPause() {
    super.onPause();

    SearchView searchView = (SearchView)getView().findViewById(R.id.searchView);

    // Save to static field
    mQuery = searchView.getQuery().toString();

    // Save to arguments bundle
    getArguments().putString(KEY_QUERY, mQuery);

    Log.d(LOG_TAG, "#################### saved query: " + mQuery);

}

}`

...我认为肯定有比使用这样的静态字符串更好的方法。请问这是什么?

正如您从代码中看到的那样,我尝试将查询保存在 setArguments() 中,但它从未被检索到。

我也花了一些时间查看 Android 文档,其中建议使用 onSaveInstanceState(),但除非 HomeActivity 被销毁(这不会发生,我也不想强制它),否则不会调用它。

【问题讨论】:

    标签: android android-activity android-fragments view savestate


    【解决方案1】:

    如果我没看错你的问题,听起来你有两个不同的 ProductSearchViewFragment 实例——在“主”屏幕上,一个在“搜索结果”屏幕上。因此,在您的主屏幕上,它会在创建 Activity 时创建片段,并在销毁 Activity 时销毁它。然后在搜索结果活动中创建该片段的新实例(并在活动被销毁时销毁)。因此,在一个实例上设置的参数不会自动传递到另一个实例。

    我的建议是,当用户点击您的主页活动上的“搜索”按钮时,您将搜索查询从片段传递到主页活动。然后,当主活动创建搜索结果活动的实例时,它可以在启动意图中传递一个额外的指定搜索字符串,然后搜索结果活动可以在创建搜索片段时在片段参数中使用它。

    【讨论】:

    • 谢谢。或者,是否有任何方法可以在两个活动中使用相同的片段实例?
    • 我能想到的唯一类似的事情是将“主页”和“搜索结果”屏幕都托管在同一个活动中。然后,您将有一个始终显示在屏幕顶部的“搜索查询”片段。当用户点击搜索时,它会删除“主页”片段,然后在其位置显示“搜索结果”片段,但“搜索查询”片段将始终留在那里。但是根据您的应用中的其他屏幕以及它们之间的导航,这可能会使事情变得更加复杂。
    猜你喜欢
    • 1970-01-01
    • 2019-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-01
    • 1970-01-01
    • 2013-07-22
    • 1970-01-01
    相关资源
    最近更新 更多