我有一个主活动和下面的三个片段,可以通过左右滑动进行切换。没什么特别的。第一个和第三个(最后一个)片段都使用Asynctask从在线获取一些信息。我在这里试图实现的是三个片段,它们从网上加载信息,稍后,我想添加下拉列表来刷新,但这应该不是问题。
事情是这样的。
- 当你打开应用程序时,它被设置为打开第二个(中间)片段
- 当滑动到第三个片段时,你会看到一切都很好
- 当返回到第二个片段并返回到第三个片段时,它完全消失并以空白页的形式返回
- 现在,如果我滚动两次回到第一个片段,并完成网络操作,它会正常工作
- 再试一次,按钮没有回复
我认为这与异步任务有关。如果有更好的方法来设置我在这里的整个东西,那么请随时这样做。
主
public class Main extends FragmentActivity {
/**
* The {@link android.support.v4.view.PagerAdapter} that will provide
* fragments for each of the sections. We use a
* {@link android.support.v4.app.FragmentPagerAdapter} derivative, which
* will keep every loaded fragment in memory. If this becomes too memory
* intensive, it may be best to switch to a
* {@link android.support.v4.app.FragmentStatePagerAdapter}.
*/
SectionsPagerAdapter mSectionsPagerAdapter;
/**
* The {@link ViewPager} that will host the section contents.
*/
ViewPager mViewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.a_main);
// Create the adapter that will return a fragment for each of the three
// primary sections of the app.
mSectionsPagerAdapter = new SectionsPagerAdapter(
getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setCurrentItem(1, false);
}
/**
* A {@link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
// Return a DummySectionFragment (defined as a static inner class
// below) with the page number as its lone argument.
// Fragment fragment = new DummySectionFragment();
// Bundle args = new Bundle();
// args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, position + 1);
// fragment.setArguments(args);
// return fragment;
switch (position) {
case 0:
// Top Rated fragment activity
return new Post();
case 1:
// Games fragment activity
return new Feed();
case 2:
// Movies fragment activity
return new Explore();
}
return null;
}
@Override
public int getCount() {
// Show 3 total pages.
return 3;
}
@Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
switch (position) {
case 0:
return "Post";
case 1:
return "Feed";
case 2:
return "Explore";
}
return null;
}
}
}
第一个片段
public class Post extends Fragment {
private MyAsyncTask mAuthTask = null;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.f_post, container, false);
Button addGoalButton = (Button) rootView.findViewById(R.id.submit);
addGoalButton.setOnClickListener(new OnClickListener() {
public void onClick(final View v) {
// Pass the fragmentView through to the handler
// so that findViewById can be used to get a handle on
// the fragments own views.
attemptLogin();
}
});
return rootView;
}
public void attemptLogin() {
if (mAuthTask != null) {
return;
}
mAuthTask = new MyAsyncTask();
mAuthTask.execute((Void) null);
}
private class MyAsyncTask extends AsyncTask<Void, Void, Void>
{
@Override
protected void onPostExecute(Void result) {
//mProgressDialog.dismiss();
}
@Override
protected void onPreExecute() {
Toast.makeText(getActivity(),
"dont worry, be happy!", Toast.LENGTH_LONG).show();
}
@Override
protected Void doInBackground(Void... params) {
// my network operation
return null;
}
}
}
第三片段
public class Explore extends Fragment {
private MyAsyncTask mAuthTask = null;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.f_explore, container, false);
attemptLogin();
return rootView;
}
public void attemptLogin() {
if (mAuthTask != null) {
return;
}
mAuthTask = new MyAsyncTask();
mAuthTask.execute((Void) null);
}
private class MyAsyncTask extends AsyncTask<Void, Void, Void>
{
@Override
protected void onPostExecute(Void result) {
//mProgressDialog.dismiss();
}
@Override
protected void onPreExecute() {
Toast.makeText(getActivity(),
"Loading Explore", Toast.LENGTH_LONG).show();
}
@Override
protected Void doInBackground(Void... params) {
// my network operation
return null;
}
}
}
我认为这可能是几个问题。
-
多个异步任务不能同时运行,使用Viewpagers,默认情况下会加载3个视图。我认为您需要调用:(无论何时,您都不希望为所有需要加载的视图运行代码)
if(getUserVisibleHint()) { //logic in here attemptLogin(); }
我相信这将阻止onCreateView()方法被调用3次。这很大程度上是因为视图寻呼机有这样的方法:mPager.setOffscreenPageLimit(1);
,它可以这样做:
Set the number of pages that should be retained to either side of the current page
in the view hierarchy in an idle state.
默认情况下,它为1,这意味着它是否会左右加载片段以使滚动平滑。(您无法将其更改为0)。因此,getUserVisibleHint将检查当前视图是否是suer可以看到的视图,并仅当它可见时调用您放入其中的任何内容。(因为默认情况下,它会调用你的异步任务3次,而且它们不能同时运行
不过我可能错了。
编辑#1:通过在onPostExecute中将asynctask设置回null修复的第一个片段。