如何在片段中保存加载的listView状态?

时间:2016-09-19 21:34:09

标签: android listview android-fragments android-savedstate

我有一个活动,片段包含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,我缺少什么?

1 个答案:

答案 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();