2

저는 Android 개발을 배우려고하고 있으며 프레임 워크가 작동하는 방식과 이러한 모든 클래스를 올바르게 확장하는 방법을 고민하고 있습니다.AsyncTask를 통해 ListFragment를 한 번만로드하십시오.

목표는 Activity이고 ViewPager은 5를 반복합니다. ListFragment 초입니다. 각 ListFragment에 바인딩되는 데이터는 AsyncTask을 사용하여 호출되는 웹 API에서 가져옵니다.

내 문제는 새로운 조각으로 전환 할 때마다 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); 
      } 
     } 
    } 
} 

나는 FragmentPagerAdapterListFragment의 배열을하고 시도하고, 그 인덱스가 null의 경우에만 MyListFragment.newInstance 전화,하지만 아무것도 변경 끝나지 않았다.

답변

1

setOffscreenPageLimit을 사용해 문제를 해결해보십시오. 조각을 사용하면 조각을 캐시하므로 다시 호출되지 않습니다.

+0

감사합니다.이게 내 문제를 해결했습니다. 나는'mViewPager.setOffscreenPageLimit (NUM_PAGES)'을 사용했습니다. 앱은 처음 5 번 모두 5 페이지를로드했으며 이후에는로드하지 않았습니다. ... – tedski

+0

(NUM_PAGES-1) –

+0

을 사용하십시오. 시나리오에 유효한 해결책이지만 NUM_PAGES가 더 큰 숫자라면 메모리와 시작 시간 문제가 발생할 수 있습니다. – Budius

1

사례에 로더 (http://developer.android.com/guide/components/loaders.html)를 사용할 것을 제안합니다.

로더는 동일한 ID를 사용하는 경우 이전과 동일한 데이터를 자동으로 호출 구성 요소에 전달한다는 점에서 상당히 똑똑합니다. 예

:

조각 위치 0 호출 initLoader(0, null, this); 다음 조각의 위치 1 개 통화 initLoader(1, null, this); 등 ....

initLoader(1 < < ID 번째 호출 될 때마다 방법 (3을 4 차) 시간 웹 호출을 실행하지 않고 첫 번째 호출에서 전달 된 것과 동일한 결과를 직접 전달합니다.

+0

답장을 보내 주셔서 감사합니다. 로더를 살펴보고 잘 맞는지 살펴 봅니다. – tedski