2

我正在尝试学习Android开发,并且仍然试图围绕框架如何工作以及如何正确地扩展所有这些类。只通过AsyncTask加载ListFragment

我的目标是:Activity有一个ViewPager周期通过五个ListFragment s。绑定到每个ListFragment的数据来自Web API,该API使用AsyncTask进行调用。

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

我一直在关注Android上的this指南开发人员试图做到这一点。我结束了与这:

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

我试图在FragmentPagerAdapter做的ListFragment秒的数组,只能调用MyListFragment.newInstance如果指数为空,但最终没有改变任何东西。

回答

1

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

+0

谢谢,这解决了我的问题。我使用了'mViewPager.setOffscreenPageLimit(NUM_PAGES)'。该应用程序一开始就加载了所有5个页面,之后并未加载它们。现在刷新一个'Fragment' ... – tedski 2013-04-09 13:47:49

+0

使用(NUM_PAGES-1) – 2013-04-09 13:52:02

+0

请记住,尽管它对于您的方案来说是一个有效的解决方案,但是如果NUM_PAGES是一个更大的数字,您可能会遇到内存和启动时间问题。 – Budius 2013-04-09 13:57:27

1

我建议你使用装载机(http://developer.android.com/guide/components/loaders.html)你的情况。

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

例如:

片段位置0呼叫initLoader(0, null, this);然后片段位置1个通话initLoader(1, null, this);等....

这样每当initLoader(1 < < ID被称为第二(第三,第四)时间,它将不会执行网络通话并直接传送第一次通话中传送的相同结果。

+0

感谢您的回答。我会研究装载机,看看它们是否合适。 – tedski 2013-04-09 13:49:35