碎片滑动异步任务消失



我有一个主活动和下面的三个片段,可以通过左右滑动进行切换。没什么特别的。第一个和第三个(最后一个)片段都使用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;
}
}
}

我认为这可能是几个问题。

  1. 多个异步任务不能同时运行,使用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修复的第一个片段。

最新更新