【问题标题】:How to store recyclerview data , while changing view (Fragments) via Bottom Navigation?如何存储 recyclerview 数据,同时通过底部导航更改视图(片段)?
【发布时间】:2020-11-17 00:56:58
【问题描述】:

我正在关注这个问题

how to store recyclerview data on onSaveInstanceState

我还发现 How to save state of view class?Fragment save view state

上下文

我在我的一个片段中以 DataModel(实现 Parcelable) 的形式将数据提供给 recyclerview。 使用底部导航和ROOM DB(获取和保存数据)。

我已经做了什么

我在第一个链接和我的代码中使用了代码。但是我无法理解其中使用的第四个代码和平(我没有response.boddy(),错误)。 无论如何每次都更改视图savedInstanceState = null,所以代码正在重做。

我想要什么或问题

我不想每次通过底部导航更改视图时都重做工作?

我做错了什么,数据没有保存在savedInstanceState

我的片段视图

    private ArrayList<DataModel> data;

    public View onCreateView(@NonNull LayoutInflater inflater,
                         ViewGroup container, Bundle savedInstanceState) {
    
    root = inflater.inflate(R.layout.fragment_home, container, false);
    currentContext = getContext();
    
    
    recyclerView = (RecyclerView) root.findViewById(R.id.recyclerViewHome);
    recyclerView.setHasFixedSize(true);


    RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getContext());
    recyclerView.setLayoutManager(layoutManager);
    recyclerView.setItemAnimator(new DefaultItemAnimator());
    this.data = new ArrayList<>();
    
    adapter = new CustomAdapter(data, currentContext, 1);
    recyclerView.setAdapter(adapter);

    
    if (savedInstanceState != null) {
        
        // Retrieve the data you saved
        data = savedInstanceState.getParcelableArrayList("saved_data");

        //Call method to reload adapter record
        recyclerViewsaveInstance(data);
    } 
     else {
        
        //No data to retrieve

        dataAsynTask; //deleted, Basicly I get the data from DB, convert it to DataModel and give them to recyclerview.
    }

    return root;
}

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

    Log.i("savedInstanceState", "loading");
    
    savedInstanceState.putParcelableArrayList("saved_data", this.data);
    
    super.onSaveInstanceState(savedInstanceState);

}


public void recyclerViewsaveInstance(ArrayList<DataModel> dataset)
{
    this.data = dataset;
    adapter = new CustomAdapter(dataset, getContext(), 1);
    recyclerView.setAdapter(adapter);//notify adapter about the new record
    adapter.notifyDataSetChanged();
}

【问题讨论】:

  • 听起来你在说savedInstanceState 捆绑包每次都是null;这可能意味着您的Activity 中存在问题(或者您创建FragmentTransaction 以显示您的Fragment 的任何地方)。您可以将该代码添加到您的问题中吗?
  • 另外,也许对保存实例状态的概念存在误解。 onSaveInstanceState() 在片段被销毁并通过配置更改重新创建时调用(例如当您旋转手机时)。如果您使用底部导航切换到不同的视图然后切换回来,则不会使用onSaveInstanceState()。如果您希望在执行此操作时缓存您的 recyclerview 数据,则必须将其保存在其他地方(可能在托管底部导航和片段的 Activity 中)。
  • 我想我正在做你所说的(在视图之间切换)。你的意思是要以某种方式保存hole recyclerview吗?
  • 我添加了我在 MainActivity 中的内容。

标签: android android-fragments android-recyclerview savestate onsaveinstancestate


【解决方案1】:

我认为您在这里要做的是将您的AsyncTask 移出Activity 级别,并让您的Fragment 向活动询问List&lt;DataModel&gt;

在你的 Fragment 的 onCreateView() 方法中,而不是写

this.data = new ArrayList<>();

然后检查savedInstanceState 并有条件地执行一个AsyncTask,你可以这样写:

this.data = ((MyActivity) getActivity()).getData();

然后,在您的 Activity 中,您将实现这个 getData() 方法:

public List<DataModel> getData() {
    if (data != null) {
        return data;
    } else {
        // kick off AsyncTask here
        return Collections.emptyList();
    }
}

当 AsyncTask 完成时,让它更新 Activity 的 data 字段,并让它通知 Fragment 有新数据可用。在 Fragment 中,你会有这样的方法:

public void onDataFetched(List<DataModel> data) {
    this.data = data;
    adapter.notifyDataSetChanged();
}

以上所有的最终结果是Activity 现在负责加载数据并保存它。 Fragment 对数据库或缓存一无所知;它只知道在显示数据时向Activity 询问数据。

由于Activity 在您使用底部导航在 Fragments 之间切换时保持活动状态,因此当您切换选项卡时它将成功保持数据活动。

【讨论】:

  • 反馈:这是完美的。但是我无法从 Asyntask 获取数据(这是 Asyntask 调用的接口方法,完成后)。我尝试等待 Asyntask 的结果,但它没有发生,模拟器也挂了。我想我的界面有问题。除了我的“活动”中的getter和setter方法之外,我以任何方式做了我之前所做的事情,所以如果活动中没有数据(这只是第一次),那么我将从数据库中获取数据并将其保存在“活动”。之后数据始终保存在“活动”中。
  • AsyncTask 在 2020 年使用?
猜你喜欢
  • 1970-01-01
  • 2017-08-04
  • 2020-11-13
  • 2021-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-19
相关资源
最近更新 更多