0

私はAsyncTaskLoaderを使用して、データベースクエリからカーソルをロードしました。 私はAndroidの開発者のサンプルに続く: http://developer.android.com/reference/android/content/AsyncTaskLoader.htmlAsyncTaskLoaderを使用したフラグメントは、他のフラグメントのアクティビティへの影響に影響します。

を何とかこの断片の後にページアダプタに追加された断片は、(ローダーを使用する)の活動に執着せず、​​それが必要なメソッドを使用しようとすると(getString()のような)アクティビティがスローされ、このフラグメントはアクティビティには関連付けられていないと言われます。

  1. ページアダプタにフラグメントを追加:ここで

    はいくつかのコードです。

    mAdapter = new PlaceFragmentPagerAdapter(getSupportFragmentManager()); 
    
    
    NewFragment newFrag = new NewFragment(); 
    mAdapter.addFragment(newShiftFrag); 
    
    ListFragment listFrag = new ListFragment(); 
    mAdapter.addFragment(listFrag); 
    
    SettingsFragment settingsFrag = new SettingsFragment(); 
    mAdapter.addFragment(settingsFrag); 
    
    mPager = (ViewPager)findViewById(R.id.pager); 
    mPager.setAdapter(mAdapter); 
    
  2. AsyncTaskLoader実装:

    抽象パブリッククラスAbstractCursorLoaderがAsyncTaskLoader {

    @Override 
        public void onActivityCreated(Bundle savedInstanceState) { 
        super.onActivityCreated(savedInstanceState); 
    
        // Give some text to display if there is no data. In a real 
        // application this would come from a resource. 
        // TODO change to resource and back 
        setEmptyText("Nothing here.."); 
    
        // Start out with a progress indicator. 
        setListShown(false); 
    
    
    
        // Prepare the loader. Either re-connect with an existing one, 
        // or start a new one. 
        getLoaderManager().initLoader(0, null, this); 
    

    abstract protected Cursor buildCursor(); 
        Cursor lastCursor=null; 
    
        public AbstractCursorLoader(Context context) { 
         super(context); 
        } 
    
        /** 
        * Runs on a worker thread, loading in our data. Delegates 
        * the real work to concrete subclass' buildCursor() method. 
        */ 
        @Override 
        public Cursor loadInBackground() { 
         Cursor cursor=buildCursor(); 
    
         if (cursor!=null) { 
          // Ensure the cursor window is filled 
          cursor.getCount(); 
         } 
    
         return(cursor); 
        } 
    
        /** 
        * Runs on the UI thread, routing the results from the 
        * background thread to whatever is using the Cursor 
        * (e.g., a CursorAdapter). 
        */ 
        @Override 
        public void deliverResult(Cursor cursor) { 
         if (isReset()) { 
          // An async query came in while the loader is stopped 
          if (cursor!=null) { 
           cursor.close(); 
          } 
    
          return; 
         } 
    
         Cursor oldCursor=lastCursor; 
         lastCursor=cursor; 
    
         if (isStarted()) { 
          super.deliverResult(cursor); 
         } 
    
         if (oldCursor!=null && oldCursor!=cursor && !oldCursor.isClosed()) { 
          oldCursor.close(); 
         } 
        } 
    
        /** 
        * Starts an asynchronous load of the list data. 
        * When the result is ready the callbacks will be called 
        * on the UI thread. If a previous load has been completed 
        * and is still valid the result may be passed to the 
        * callbacks immediately. 
        * 
        * Must be called from the UI thread. 
        */ 
        @Override 
        protected void onStartLoading() { 
         if (lastCursor!=null) { 
          deliverResult(lastCursor); 
         } 
         if (takeContentChanged() || lastCursor==null) { 
          forceLoad(); 
         } 
        } 
    
        /** 
        * Must be called from the UI thread, triggered by a 
        * call to stopLoading(). 
        */ 
        @Override 
        protected void onStopLoading() { 
         // Attempt to cancel the current load task if possible. 
         cancelLoad(); 
        } 
    
        /** 
        * Must be called from the UI thread, triggered by a 
        * call to cancel(). Here, we make sure our Cursor 
        * is closed, if it still exists and is not already closed. 
        */ 
        @Override 
        public void onCanceled(Cursor cursor) { 
         if (cursor!=null && !cursor.isClosed()) { 
          cursor.close(); 
         } 
        } 
    
        /** 
        * Must be called from the UI thread, triggered by a 
        * call to reset(). Here, we make sure our Cursor 
        * is closed, if it still exists and is not already closed. 
        */ 
        @Override 
        protected void onReset() { 
         super.onReset(); 
    
         // Ensure the loader is stopped 
         onStopLoading(); 
    
         if (lastCursor!=null && !lastCursor.isClosed()) { 
          lastCursor.close(); 
         } 
    
         lastCursor=null; 
        } 
    } 
    
        private static class ListLoader extends AbstractCursorLoader { 
         private String mName; 
    
         public ShiftsListLoader(Context context, String name) { 
          super(context); 
          mName = name; 
         } 
    
         @Override 
         protected Cursor buildCursor() { 
          PlacesHandler wph = new PlacesHandler(this.getContext()); 
          return wph.GetShifts(mName); 
         } 
        } 
    
  3. Initializngローダを}延び

    @Override 
        public Loader<Cursor> onCreateLoader(int id, Bundle args) { 
         return new ListLoader(getActivity(), mWorkPlaceName); 
        } 
        @Override 
        public void onLoadFinished(Loader<Cursor> loader, Cursor data) { 
         // Create an empty adapter we will use to display the loaded data. 
        mAdapter = new ListCursorAdapter(getActivity(), data, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER); 
        setListAdapter(mAdapter); 
    
        } 
    @Override 
    public void onLoaderReset(Loader<Cursor> loader) { 
        // TODO Auto-generated method stub 
    
    } 
    

私は実際にそれが起こっている理由を持っていません。

P.S.私はコメントにコードブロックを作るいくつかの問題を抱えていました。

ありがとうございました、Elad。

答えて

2

簡単な答えは、適切なライフサイクルコールバックを受信して​​それを通知するまで、フラグメントが特定の状態にあるとは決して考えないでください。

あなたが見ているのは、ViewPagerが利用するICSで追加された最適化です。 FragmentPagerAdapterは、オフスクリーンフラグメントをユーザが見ることができないものとして特別にマークします。setUserVisibleHintを呼び出します。 FragmentManagerはこれを使用して、ローダの実行方法の優先順位付けを行い、ユーザが完全に表示されている可視ページを最初に見て、読み込み側のページが可視ページの読み込みプロセスを遅くしないようにします。具体的には、フラグメントを「開始済み」状態に移すのを遅らせます。これは、ローダーが実行を開始するときも同じです。

この処理中にユーザーが別のページにスクロールすると、FragmentManagerはフラグメントを開始状態に移動し、FragmentPagerAdapter#setPrimaryItem()の一部としてローダーをすぐに実行します。今はユーザーが見ることができます。

+0

私はあなたを理解しています。私は自分の問題を理解していると思います。私のアプリのすべてのフラグメントは、私が使用しているTitlePageIndicator(sherlockアクションバーの作成者からの非常に素晴らしいライブラリ)のリソースからその名前を返します.3つのフラグメントがある場合、3つ目はアクティビティにまだ添付されていませんアクティビティのresorcesを使用するgetString()を使用しないでください。ありがとう、私は他の方法でそれをやります! – Elad92

+0

代わりに、サポートライブラリのPagerTitleStripに興味があるかもしれません。 PagerAdapterからタイトル文字列を取得します。ここでは、これらの文字列を取得するために使用できるアクティビティ参照があると考えられます。 – adamp

関連する問題