如何通过底部导航更改视图(片段)时存储recyclerview数据?

时间:2020-07-27 16:38:19

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

我正在关注这个问题

how to store recyclerview data on onSaveInstanceState

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

上下文

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

我做了什么

我在第一个链接和代码中使用了代码。但是我无法理解其中使用的第四种代码和平(我没有response.boddy(),Error)。 无论如何,每次更改视图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();
}

1 个答案:

答案 0 :(得分:0)

我认为您要在此处进行的工作是将AsyncTask移至Activity级别,并让Fragment向活动询问List<DataModel>。 / p>

在您片段的onCreateView()方法中,而不是编写

this.data = new ArrayList<>();

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

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

然后,在“活动”中,您将实现此getData()方法:

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

AsyncTask完成后,让它更新活动的data字段,并通知Fragment有新数据可用。在“片段”中,您将具有以下方法:

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

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

由于Activity在您使用底部导航在片段之间切换时仍然有效,因此当您切换标签页时,它将成功地使数据保持活动状态。