我有一个活动,片段包含listView和片段,每个listView项都有详细信息。我从API获取片段数据。我应该如何正确保存加载日期和listView位置,以便在我返回listView时能够恢复它? 我尝试实现此解决方案Once for all, how to correctly save instance state of Fragments in back stack?,但我无法正确恢复listView。
我的主要活动
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Set the fragment initially
listFragment = new ListFragment();
fragmentTransaction =
getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, listFragment);
fragmentTransaction.commit();
if (savedInstanceState != null) {
//Restore the fragment's instance
listFragment = (ListFragment)getSupportFragmentManager().getFragment(savedInstanceState, "listContent");
}
...
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//Save the fragment's instance
getSupportFragmentManager().putFragment(outState, "listContent", listFragment);
}
和ListFragment
public class ListFragment extends Fragment {
public static final String REQUEST_TAG = "ProjectListFragment";
private int page;
private View view;
private RelativeLayout loading ;
private PagingListView listView;
private PagingProjectListAdapter adapter;
private ArrayList<String> projects = new ArrayList<>();
private ArrayList<String> loadedProjects = new ArrayList<>();
public ListFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_list, container, false);
listView = (PagingListView) view.findViewById(R.id.projectsListView);
loading = (RelativeLayout) view.findViewById(R.id.loading);
//page = 1;
adapter = new PagingProjectListAdapter(getContext(), ListFragment.this);
listView.setAdapter(adapter);
listView.setHasMoreItems(true);
// Inflate the layout for this fragment
return view;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (savedInstanceState != null) {
// FIXME not used
listView.onFinishLoading(true, projects);
//Restore the fragment's state here
} else {
projects.clear();
page = 1;
listView.setPagingableListener(new PagingListView.Pagingable() {
@Override
public void onLoadMoreItems() {
new CustomVolleyAsyncTask().execute();
}
});
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("currentPosition", 0);
//Save the fragment's state here
}
public void itemClickMethod(View detailsView) {
LinearLayout linearLayout = (LinearLayout) detailsView;
String bid = linearLayout.getContentDescription().toString();
Bundle bundle = new Bundle();
String k = "ProjectID";
bundle.putString(k, bid);
DetailsFragment detailsFragment = new DetailsFragment();
detailsFragment.setArguments(bundle);
final FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.fragment_container, detailsFragment, "DetailsFragmentTag");
ft.addToBackStack(null);
ft.commit();
}
private class CustomVolleyAsyncTask extends SafeAsyncTask<List<String>> implements Response.Listener,
Response.ErrorListener {
public List<String> status = null;
private RequestQueue mQueue;
@Override
public List<String> call() throws Exception {
mQueue = CustomVolleyRequestQueue.getInstance(view.getContext())
.getRequestQueue();
String url = "http://www.myapi.com/api/v1/data/" + Integer.toString(page);
final CustomJSONObjectRequest jsonRequest = new CustomJSONObjectRequest(Request.Method
.GET, url,
new JSONObject(), this, this);
jsonRequest.setTag(REQUEST_TAG);
mQueue.add(jsonRequest);
// TODO rm redundant result
return status;
}
@Override
public void onErrorResponse(VolleyError error) {
// FIXME check no response case crash
//mTextView.setText(error.getMessage());
}
@Override
public void onResponse(Object response) {
try {
JSONArray projectsJSON = new JSONArray(((JSONObject) response).getString("projects"));
loadedProjects.clear();
for (int i=0; i < projectsJSON.length(); i++) {
loadedProjects.add(projectsJSON.getJSONObject(i).toString());
}
page++;
listView.onFinishLoading(true, loadedProjects);
if (loading.getVisibility() == View.VISIBLE && !listView.isLoading()){
listView.setVisibility(View.VISIBLE);
loading.setVisibility(View.GONE);
}
} catch (JSONException e) {
e.printStackTrace();
}}}
}
目前,我的savedInstanceState始终为null,我缺少什么?
答案 0 :(得分:0)
我认为,当配置发生变化时,您的片段会创建两次。 Here斯塔凡解释说,为什么会发生这种情况。我通过这种方式解决了类似的问题(在onCreate活动中):
FragmentManager fragmentManager = getSupportFragmentManager();
Fragment fragment = fragmentManager.findFragmentByTag(TAG);
if(fragment==null)
fragmentManager.beginTransaction()
.add(R.id.container, NewsFragment.newInstance(),TAG)
.commit();