如何在ViewPager中访问ListFragment适配器

时间:2013-09-02 15:00:03

标签: android android-fragments android-asynctask android-viewpager

我有一个应用程序可以下载必须在viewpager的片段中显示的数据。我不知道如何拨打执行数据下载的ListFragment中的adaptername.notifyDataSetChanged() AsyncTask

例如说我正在下载未来七天的温度预测:

我的应用具有以下结构:

  • MainActivity:开始AsyncTask下载onCreate()中的数据,并让用户选择(button)查看哪一天。单击该按钮将启动SecondActivity并将日期索引传递给ViewPager(以设置当前视图)。

MainActivity User Selection

  • SecondActivity:包含ViewPager,其中包含7个相同的ListFragments(该列表显示5小时内的温度,因此列表中有5个条目)

  • MyListFragment:加载时设置adapter以显示每个温度(如果数据已下载),否则将温度设置为"loading..."

    < / LI>

现在我的问题是,如果用户在数据下载之前等待MainActivity,那么他们就可以继续ViewPager查看ListFragment温度而不会出现问题。 但是,如果他们尝试点击一天并在下载完成之前加载 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 } }


MainActivity:

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

SecondActivity

{{1}}

当我在AsyncTask中完成下载时,我需要一种能够刷新当前显示片段的方法。

2 个答案:

答案 0 :(得分: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);
        }
}

然后通过Fragment代码上的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位于加载视图的片段中,因此您可以相应地刷新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期间,当加载数据时,您可以直接将适配器设置为ListView直接形成AsyncTask。

答案 1 :(得分:1)

你正在触及两个不同的问题。首先,use a Service进行下载。服务存在于Activity的生命周期之外的长时间运行(如下载)。

其次,要communicate between Activities and Fragments,您需要使用回调接口。提供的链接是那些在解释和提供样本方面做得很好的文档。