2014-07-24 3 views
1

조각이 3 개 있습니다.조각이 표시되면 asynctask를 시작하십시오.

각 조각의 onActivityCreated()에서 비동기 작업을 실행합니다.

doInBackground의 비동기 작업은 SQLite DB에서 데이터를 가져 와서 객체의 ArrayList를 만듭니다. onPostExecute에서 나는 listView에 데이터를 보여주는 메소드를 호출한다.

각 조각에는 고유 한 asynctask가 있습니다.

FragmentActivity를 "시작"하면 조각 1이 표시되고 asynctask가 실행됩니다. 그러나 가장 가까운 단편 (조각 2, 중간 단편)도 AsyncTask를 시작합니다.

사용자가 조각을 볼 때 비동기 작업을 시작할 수 있는지 알고 싶습니다. 진행 대화 상자 (데이터 가져 오기 ...)를 보여주고 싶기 때문에 가능하면 좋겠다. 지금은 데이터베이스에서 얻을 수있는 데이터가 거의 없지만 진행률 대화 상자를 보여주고 싶습니다. 바로 지금 각 asynctask의 onPreExecute에 ProgressDialog를 표시하면 Fragment 1에서 Fragment 2로 변경하면 Fragment 3의 ProgressDialog :/

이 잘못되었을 수 있으며 asynctasks를 사용하는 것이 좋지 않을 수 있습니다.

편집 1 : FragmentActivity

public class FragmentActivityInterestPoints extends FragmentActivity implements 
     ActionBar.TabListener { 
    PagerAdapterInterestPoints mInterestPointsPagerAdapter; 
    ViewPager mViewPager; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     setContentView(R.layout.pager_adapter_fragment); 
     // Set up the action bar. 
     final ActionBar actionBar = getActionBar(); 
     actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); 

     // Create the adapter that will return a fragment for each of the three 
     // primary sections of the app. 
     mInterestPointsPagerAdapter = new PagerAdapterInterestPoints(
       getSupportFragmentManager()); 

     // Set up the ViewPager with the sections adapter. 
     mViewPager = (ViewPager) findViewById(R.id.pager); 
     mViewPager.setAdapter(mInterestPointsPagerAdapter); 

     // When swiping between different sections, select the corresponding 
     // tab. We can also use ActionBar.Tab#select() to do this if we have 
     // a reference to the Tab. 
     mViewPager 
       .setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { 
        @Override 
        public void onPageSelected(int position) { 
         actionBar.setSelectedNavigationItem(position); 
        } 
       }); 

     // For each of the sections in the app, add a tab to the action bar. 
     for (int i = 0; i < mInterestPointsPagerAdapter.getCount(); i++) { 
      // Create a tab with text corresponding to the page title defined by 
      // the adapter. Also specify this Activity object, which implements 
      // the TabListener interface, as the callback (listener) for when 
      // this tab is selected. 
      actionBar.addTab(actionBar.newTab() 
        .setText(mInterestPointsPagerAdapter.getPageTitle(i)) 
        .setTabListener(this)); 
     } 

    } 


    @Override 
    public void onTabSelected(ActionBar.Tab tab, 
      FragmentTransaction fragmentTransaction) { 
     mViewPager.setCurrentItem(tab.getPosition()); 
    } 

    @Override 
    public void onTabUnselected(ActionBar.Tab tab, 
      FragmentTransaction fragmentTransaction) { 
    } 

    @Override 
    public void onTabReselected(ActionBar.Tab tab, 
      FragmentTransaction fragmentTransaction) { 
    } 

} 


public class PagerAdapterInterestPoints extends FragmentPagerAdapter { 

    private static final int PAGES = 3; 

    private ArrayList<Fragment> pages = new ArrayList<Fragment>(PAGES); 

    public PagerAdapterInterestPoints(FragmentManager fm) { 
     super(fm); 

     pages.add(new FragmentShowPoints()); 
     pages.add(new FragmentCategoryPoints()); 
     pages.add(new FragmentFavouritePoints()); 
    } 

    @Override 
    public int getCount() { 
     // Show total pages. 
     return PAGES; 
    } 

    @Override 
    public Fragment getItem(int position) { 
     return pages.get(position); 
    } 

    @Override 
    public CharSequence getPageTitle(int position) { 
     switch (position) { 
     case 0: 
      return "Fragment 1"; 
     case 1: 
      return "Fragment 2"; 
     case 2: 
      return "Fragment 3"; 
     default: 
      return "Undefined"; 
     } 
    } 

} 


public class FragmentShowPoints extends ListFragment { 
    private MyDatabase myDB; 

    private ArrayList<PointInterest> listPoints = null; 
    // UI 
    private ListView lv; 
    View rootView; 
    ListAdapterShowPoints adapter; 

    AsyncTaskGetPoints mTaskGetPoints; 
    ProgressDialog progressDialog; 
    private Activity act; 

    public FragmentShowPoints() { 

    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
      Bundle savedInstanceState) { 
     rootView = inflater.inflate(R.layout.activity_show_points, container, 
       false); 

     this.act = getActivity(); 

     return rootView; 
    } 

    @Override 
    public void onResume() { 
     super.onResume(); 

     // Load UI 
     lv = getListView(); 
    } 

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

     mTaskGetPoints = new AsyncTaskGetPoints(); 
     mTaskGetPoints.execute(); 
    } 

    @Override 
    public void onPause() { 
     if (mTaskGetPoints != null) { 
      mTaskGetPoints.cancel(true); 
     } 
     super.onPause(); 
    } 

    @Override 
    public void onDestroy() { 
     if (mTaskGetPoints != null) { 
      mTaskGetPoints.cancel(true); 
     } 
     super.onDestroy(); 
    } 


    @Override 
    public void onStop() { 
     super.onStop(); 
    } 

    private void showPoints() { 
      adapter = new ListAdapterShowPoints(act, listPoints, act); 
      setListAdapter(adapter); 
     } 
    } 

    private class AsyncTaskGetPoints extends 
      AsyncTask<Void, Void, ArrayList<PointInterest>> { 
     @Override 
     protected void onPreExecute() { 
      super.onPreExecute(); 

      progressDialog = new ProgressDialog(act); 
      progressDialog.setMessage("Loading..."); 
      progressDialog.show(); 
     } 

     @Override 
     protected ArrayList<PointInterest> doInBackground(Void... params) { 
      myDB = new MyDatabase(act); 
      Cursor c = myDB.getPoints(); 
      //loop with data 
      c.close(); 
      myDB.close(); 
      return listPoints; 
     } 

     @Override 
     protected void onPostExecute(ArrayList<PointInterest> result) { 
      progressDialog.dismiss(); 
      showPoints(); 
     } 

    } 
} 



<?xml version="1.0" encoding="utf-8"?> 
<android.support.v4.view.ViewPager 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:id="@+id/pager" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    tools:context=".MainActivity" > 
</android.support.v4.view.ViewPager> 

편집 2 (내 솔루션) : 좀 더 간단하게 뭔가를 사용했다.

각 프래그먼트의 레이아웃에서 진행 막대와 텍스트보기가있는 다른 레이아웃을 추가했습니다. onResume에서 listView를 숨기고 진행 막대 및 텍스트보기로 레이아웃을 표시합니다. 또한 asynctask의 onPreexecute에서 동일한 작업을 수행합니다. onResume에서 asynctask를 시작하기 때문에 (이 경우에만 haha를 테스트 했으므로이 시점에서만 확인해야합니다). postExecute에서 표시 할 데이터가있는 경우 진행률 막대 및 textview를 숨기고 목록보기를 표시합니다. . "는 의견을 만질 수있는 뷰 계층 구조를 생성 만 원래 스레드"

getActivity().runOnUiThread(new Runnable() { 
       @Override 
       public void run() { 
        // lv.setVisibility(View.VISIBLE); 
        if (listPointsSearch == null) { 
         adapter = new ListAdapterShowPoints(act, listPoints, 
           act); 
        } else { 
         adapter = new ListAdapterShowPoints(act, 
           listPointsSearch, act); 
        } 
        adapter.setActivity(act); 

        setListAdapter(adapter); 

        lv.setVisibility(View.VISIBLE); 
        pRelativeLayout.setVisibility(View.GONE); 
       } 
      }); 

그러나 단지 내가 문제에 있습니다 중요한 것은 내가 다음 오류가 발생하지 않을 경우, UI 스레드에서이에 할 것입니다 onPostExecute(). 프래그먼트가 다시 시작되었지만 볼 수 없으면 제대로 작동합니다. 왜냐하면 onPreExecute에서 충돌이 발생해야하기 때문입니다.

편집 3 : asynctasks 대신 loader로 테스트해야합니다.

+0

사용자가 조각을 보지 못하는 이유는 무엇입니까? 파편은 어떻게 구조화되어 있습니까? ViewPager입니까? 탭? 어떻게 그들 사이에 추가/전환하고 있습니까? Fragment 대 DialogFragment에서 로딩 뷰를 추천합니다. AsyncTask 대신 Loader를 사용하여 데이터를로드하는 것. (이것은 오리엔테이션 변경을 올바르게 처리 할 것입니다.) – kcoppock

+0

@kcoppock 제 코드를 편집했습니다. 그리고 로더 덕분에, 나는 몰랐다. – Adrian

답변

0

문제는 조각을 바꾸는 데 사용하는 내용에 따라 (내가 말하는 것에서는 ViewPager을 사용하고 있다고 생각합니까?), 조각을 사용자에게 표시하기 전에 캐시합니다 따라서 UI를로드하는 데 시간이 오래 걸리지 않습니다.

조각 변경시 콜백을 사용하여 AsyncTask을 시작하는 것이 좋습니다. 당신은 Fragments에 의해 구현 된 인터페이스를 가질 수 있으며, 하나의 프래그먼트에서 새로운 프래그먼트로 변경할 때 호출됩니다.

편집 : 코드

첫 번째에서 더 많은 정보를 원하시면, 당신의 AsyncTask를 시작할 것이다 당신의 조각에 의해 구현 간단한 콜백 인터페이스를 만들 수 있습니다. 당신의 SimpleOnPageChangeListener#onPageSelected에 그런

public interface OnFragmentShownListener { 
    void onFragmentShown(); 
} 

, 표시된 조각을 검색하기 위해 mInterestPointsPagerAdapter.getItem(position)를 호출합니다.

그런 다음 onPageSelected에서 여전히 ((OnFragmentShownListener) fragment).onFragmentShown()으로 전화하여 AsyncTask를 시작해야합니다.

희망이 있습니다.

+0

내 코드로 업데이트했습니다. 예 ViewPager를 사용하고 있습니다. 콜백 및 다른 애플 리케이션에서 인터페이스를 사용하지만, 내 문제를 해결하지, 안돼? 문제는 조각이 표시 될 때 비동기 작업을 시작하는 것입니다. 조각이로드되었지만 "숨겨져있는"경우가 아닙니다. 시간 내 주셔서 감사합니다. – Adrian

+0

@Adrian 코드에서 답변을 업데이트했습니다. 나는 그것을 시도하지 않았지만 이것이 효과가 있다고 생각한다. – MagicMicky

+0

Ok 고마워요 !!! 나는 그것을 시도 할게요 – Adrian