2

我正在尝试学习 Android 开发,并且仍在尝试围绕框架的工作原理以及如何正确扩展所有这些类。

我的目标是:一个Activity有一个ViewPager循环五个ListFragments 的。绑定到每一个的数据ListFragment来自一个 Web API,该 API 使用AsyncTask.

我的问题是,每当我切换到新片段时,MyListFragment.newInstance()都会再次调用 the ,AsyncTask每次都会调用 the 。我试图AsyncTask在第一次ListFragment加载时调用一次,以减少网络调用并保存页面状态。最终我想做一个“下拉刷新”类型的事情,这意味着当我切换页面时不会重新加载数据。

我一直在关注Android Developers 上的这个指南来尝试实现这一点。我最终得到的是:

public class MainActivity extends FragmentActivity {

    MyPagerAdapter mMyPagerAdapter;
    ViewPager mViewPager;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mMyPagerAdapter = new MyPagerAdapter(getSupportFragmentManager());

        mViewPager = (ViewPager) findViewById(R.id.pager);
        mViewPager.setAdapter(mMyPagerAdapter);
    }


    public class MyPagerAdapter extends FragmentPagerAdapter {
        public static final int NUM_PAGES = 5;

        public MyPagerAdapter(FragmentManager fm) {
            super(fm);
        }   

        @Override
        public Fragment getItem(int i) {
            return MyListFragment.newInstance(getPageTitle(i).toString());
        }

        @Override
        public int getCount() {
            return NUM_PAGES;
        }

        @Override
        public CharSequence getPageTitle(int position) { 
            String[] titles = getResources().getStringArray(R.array.thing_sort_titles);
            return titles[position];
        }

    }


    public static class MyListFragment extends ListFragment {
        public static final String ARG_CATEGORY = "category_title";
        ArrayList<HashMap<String, String>> mylist;

        public MyListFragment() {
            mylist = new ArrayList<HashMap<String, String>>();
        }

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

            Bundle args = getArguments();
            URI url = new URI("http://api.remotesite.com/" + args.getString(ARG_CATEGORY));
            new MyListAsyncTask().execute(url);
        }

        static MyListFragment newInstance(String category) {
            MyListFragment f = new MyListFragment();

            Bundle args = new Bundle();
            args.putString(ARG_CATEGORY, category);
            f.setArguments(args);

            return f;
        }

        private class MyListAsyncTask extends AsyncTask<URI, Integer, ArrayList<HashMap<String, String>>> {

            protected ArrayList<HashMap<String, String>> doInBackground(URI... uris) {
                try {
                    JSONArray json = JSON.getJSONfromURL(uris[0]);
                    for (int i = 0; i < json.length(); i++) {
                        HashMap<String, String> map = new HashMap<String, String>();
                        JSONObject obj = json.getJSONObject(i)
                        map.put("title", obj.getString("title"));
                        map.put("author", obj.getString("author"));
                        map.put("id", obj.getString("id"));
                        mylist.add(map);
                    }
                } catch (Exception ex) {
                }
                return mylist;
            }

            protected void onPostExecute(ArrayList<HashMap<String, String>> list) {
                ListAdapter adapter = new SimpleAdapter(
                    getActivity(), 
                    mylist,
                    R.layout.list_item, 
                    new String[] { "title", "author" }, 
                    new int[] { R.id.text_title, R.id.text_author }
                );
                MyListFragment.this.setListAdapter(adapter);
            }
        }
    }
}

ListFragment我尝试在s 中做一个 s 数组FragmentPagerAdapter,并且仅MyListFragment.newInstance在该索引为空时调用,但它最终并没有改变任何东西。

4

2 回答 2

1

我建议您使用 Loaders ( http://developer.android.com/guide/components/loaders.html ) 来处理您的情况。

加载程序在这方面非常聪明,如果您使用相同的 ID,它会自动将与以前相同的数据返回给调用组件。

例如:

片段位置 0 调用initLoader(0, null, this);,然后片段位置 1 调用initLoader(1, null, this);,依此类推....

这样,每当initLoader(1第二次(第 3 次、第 4 次)调用 << id 时,它都不会执行 Web 调用并直接传递与第一次调用相同的结果。

于 2013-04-09T13:35:04.607 回答
1

请尝试使用setOffscreenPageLimit来解决您的问题。如果您使用它,它将缓存您的片段并且不会再次调用它。

于 2013-04-09T13:37:22.440 回答