Как сохранить загруженное состояние listView во фрагменте?

У меня есть одно действие, фрагмент с listView и фрагмент с деталями для каждого элемента listView. Я получаю данные фрагментов из API. Как мне правильно сохранить загруженную дату и позицию списка, чтобы иметь возможность восстановить ее, когда я вернусь обратно в список? Я попытался реализовать это решение Раз и навсегда, как правильно сохранить состояние экземпляра фрагментов в заднем стеке? но я не могу правильно восстановить свой 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);
    }

и Фрагмент списка

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();
            }}}
}

в настоящее время мой saveInstanceState всегда равен нулю, что мне не хватает?


person user1835337    schedule 19.09.2016    source источник
comment
Вызывается onSaveInstanceState()?   -  person Matthew Shearer    schedule 20.09.2016


Ответы (1)


Я думаю, что ваш фрагмент создавался дважды, когда конфигурация менялась. Здесь Стаффан объясняет, почему это произошло. Я решаю аналогичную проблему таким образом (в действии onCreate):

        FragmentManager fragmentManager = getSupportFragmentManager();
        Fragment fragment = fragmentManager.findFragmentByTag(TAG);
        if(fragment==null)
            fragmentManager.beginTransaction()
                    .add(R.id.container, NewsFragment.newInstance(),TAG)
                    .commit();
person Gogi Bobina    schedule 20.09.2016