仅通过AsyncTask加载ListFragment一次

时间:2013-04-09 13:26:27

标签: android android-asynctask android-fragments android-listfragment

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

我的目标是:Activity ViewPager,其ListFragment周期为五ListFragment秒。绑定到每个AsyncTask的数据来自Web API,使用MyListFragment.newInstance()调用。

我的问题是,无论何时切换到新片段,都会再次调用AsyncTask,每次调用AsyncTask。我试图在第一次加载ListFragment时调用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); } } } } 一次,以减少Web调用并保存页面状态。最终我想做一个“下拉刷新”类型的东西,这意味着当我切换页面时不会重新加载数据。

我一直关注Android开发者的this指南,试图让这种情况发生。我最终得到的是:

ListFragment

我尝试在FragmentPagerAdapter中执行MyListFragment.newInstance个数组,如果该索引为空,则只调用{{1}},但它最终没有更改任何内容。

2 个答案:

答案 0 :(得分:1)

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

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

例如:

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

每当initLoader(1&lt;&lt; id被称为第二(第3,第4)时间,它不会执行Web调用并直接传递第一次调用时传递的相同结果。

答案 1 :(得分:1)

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