我有一个应用程序可以下载必须在viewpager
的片段中显示的数据。我不知道如何拨打执行数据下载的ListFragment
中的adaptername.notifyDataSetChanged()
AsyncTask
。
例如说我正在下载未来七天的温度预测:
我的应用具有以下结构:
MainActivity
:开始AsyncTask
下载onCreate()
中的数据,并让用户选择(button
)查看哪一天。单击该按钮将启动SecondActivity
并将日期索引传递给ViewPager
(以设置当前视图)。
SecondActivity
:包含ViewPager
,其中包含7个相同的ListFragments
(该列表显示5小时内的温度,因此列表中有5个条目)
MyListFragment
:加载时设置adapter
以显示每个温度(如果数据已下载),否则将温度设置为"loading..."
现在我的问题是,如果用户在数据下载之前等待MainActivity
,那么他们就可以继续ViewPager
查看ListFragment
温度而不会出现问题。 但是,如果他们尝试点击一天并在下载完成之前加载 ViewPager
,则片段将永远只是说 "loading..."
我需要一种方法可以在ListFragment
onPostExecute()
AsyncTask
MainActivity
内ListFragment
重新加载适配器。要做到这一点,虽然我需要能够实际访问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中完成下载时,我需要一种能够刷新当前显示片段的方法。
答案 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,您需要使用回调接口。提供的链接是那些在解释和提供样本方面做得很好的文档。