1

のフラグメント内に表示する必要があるデータをダウンロードするアプリがありますviewpager。データのダウンロードを行うを呼び出す方法がわかりListFragment adaptername.notifyDataSetChanged()ません。AsyncTask

たとえば、次の 7 日間の気温予報をダウンロードするとします。

私のアプリの構造は次のとおりです。

  • MainActivity:AsyncTaskでデータのダウンロードを開始し、表示する日付をonCreate()ユーザーに選択させます ( button)。ボタンをクリックすると、 (現在のビューを設定するために)が起動SecondActivityし、日のインデックスが渡されます。ViewPager

MainActivity ユーザーの選択

  • SecondActivity:ViewPager同じものを 7 つ含む a が含まれていますListFragments(リストには 5 時間にわたる温度が表示されるため、リストには 5 つのエントリがあります)。

  • MyListFragment: これが読み込まれると、adapter各温度を表示するように設定されます (データがダウンロードされている場合)。それ以外の場合は、温度が"loading..."

今私の問題は、ユーザーがデータがダウンロードされるまで待っている場合、問題なく温度を確認するためににMainActivity進むことができることです。しかし、ダウンロードが完了する前に 1 日クリックしてロードしようとすると、フラグメントは永遠に言うだけですViewPagerListFragment ViewPager "loading..."

ListFragmentのからonPostExecute()内にアダプタをリロードできる方法が必要AsyncTaskですMainActivityListFragmentこれを行うには、表示されているに実際にアクセスできる必要がありますViewPager。アダプターを更新するにはどうすればよいonPostExecute()ですか?


主な活動:

protected void onCreate(Bundle savedInstanceState) {
    ...
    new LoadData().execute();
}

protected class LoadData extends AsyncTask<String, Void, String> {
    protected String doInBackground(String... params) {
        //Download happens here
    }
    protected void onPostExecute(String result) {
        //I need to tell the viewpager in SecondActivity to reload the ListFragment it is currently showing here
    }
}

セカンドアクティビティ

private ViewPager mPager;
private PagerAdapter mPagerAdapter;
private int[] temperatureArray;
public void onCreate(Bundle savedInstanceState) {
    ...
    Intent intent = getIntent();
    int[] defaultTemps = {0, 0, 0, 0, 0};
    temperatureArray = getIntArrayExtra("temps", defaultTemps);
    mPager = (ViewPager) findViewById(R.id.pagerID);
    mPager.setCurrentItem(intent.getIntExtra("page", 0));
    mPagerAdapter = new MyPagerAdapter(getSupportFragmentManager());
    mPager.setAdapter(mPagerAdapter);
}
private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
    ...
    public Fragment getItem(int position) {
        MyListFragment lf = new MyListFragment();
        lf.setTemperatures(temperatureArray);
        return lf;
    }
}

AsyncTask でのダウンロードが終了したときに、現在表示されているフラグメントを更新できるようにする方法が必要です。

4

2 に答える 2

2

これらがベストプラクティスであるかどうかはわかりませんが、2 つのうちのいずれかを実行することをお勧めします。

情報の読み込みが完了したら、AsyncTask に固有のアクションでブロードキャストを送信させることができます。もちろん、これは OnPostExecute から行う必要があります。

@Override
protected void onPostExecute(Void result) {     
        super.onPostExecute(result);
        if (result != null) {
            //_Do whatever action you normally do, like storing result to database.
            //fire up the broadcast
            Intent intent = new Intent(Home.ACTION_FEED_LOADING_FINISHED);
            mContext.sendBroadcast(intent);
        }
}

そして、フラグメントのコードで BroadcastReceiver を介してそれを傍受します。

private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {

    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (action.equals(ACTION_FEED_LOADING_FINISHED)) {
            //The AsyncTask Finished loading data
        }
    }
};

イベントが受信されると、BroadcastReceiver はビューが読み込まれる Fragment にあるため、それに応じて UI を更新できます。

または、

更新するビューを AsyncTask のパラメーターとして渡すことができます。

AsyncTask クラスを次のように想像してください。

private static class getInternetStuffTask extends AsyncTask<String, Void, Void> {

次に、カスタム コンストラクターを作成して、ビューをパラメーターとして受け取ることができます。

public getInternetStuffTask (final Context context, final ListView list) {
        this.mContext = context;
        this.mListView= list;           
    }

次に、onPostExecute 中にデータがロードされるときに、アダプターを AsyncTask から直接 ListView に設定するだけです。

于 2013-09-02T15:50:42.807 に答える
1

あなたは2つの異なる問題に触れています。まず、サービスを使用してダウンロードします。サービスは、アクティビティのライフサイクルの外にある長時間実行される操作 (ダウンロードなど) のために存在します。

次に、アクティビティとフラグメントの間で通信するには、コールバック インターフェイスを使用する必要があります。提供されているリンクは、サンプルの説明と提供に優れた仕事をしているドキュメントへのリンクです。

于 2013-09-02T15:49:55.887 に答える