使用自定义Loader时,未在ViewPager片段上调用onResume()

时间:2013-08-18 17:45:38

标签: android android-viewpager android-support-library android-loader

简短版:

我有一个片段维护ViewPager以显示另外两个片段,我们称之为FragmentOneFragmentTwo。启动应用时FragmentOne可见且FragmentTwo在屏幕外,只有在向左滑动视图时才会显示。

一旦应用程序启动,通常会立即为两个片段调用onStart()onResume()

我遇到的问题是当FragmentOne启动自定义Loader时,onResume()无法在FragmentTwo上调用Loader,直到它完全可见。

Screenshot showing the problem

问题:

这是我的代码问题还是Android支持库中的错误? (图书馆的修订版12没有出现问题,它从修订版13开始。)

如果是修订版13和18中的错误,是否有解决方法?

我的自定义MainActivity是否有问题?

长版:

我已经构建了一个演示问题的示例应用程序。我试图将代码减少到最低限度,但它仍然很多,所以请耐心等待。

我有MainFragment加载ViewPager,会创建MainFragment。对于我的应用程序来说,ViewPager由Fragment而不是Activity维护是很重要的。

FragmentPagerAdapter创建FragmentOne,然后创建片段FragmentTwoFragmentOne

让我们从有趣的位开始,两个片段:

ListFragment是使用自定义Loader加载内容的public class FragmentOne extends ListFragment implements LoaderCallbacks<List<String>> { private ArrayAdapter<String> adapter; @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1); setListAdapter(adapter); setEmptyText("Empty"); } @Override public void onResume() { super.onResume(); // initializing the loader seems to cause the problem! getLoaderManager().initLoader(0, null, this); } @Override public Loader<List<String>> onCreateLoader(int id, Bundle args) { return new MyLoader(getActivity()); } @Override public void onLoadFinished(Loader<List<String>> loader, List<String> data) { adapter.clear(); adapter.addAll(data); } @Override public void onLoaderReset(Loader<List<String>> loader) { adapter.clear(); } public static class MyLoader extends AsyncTaskLoader<List<String>> { public MyLoader(Context context) { super(context); } @Override protected void onStartLoading() { forceLoad(); } @Override public List<String> loadInBackground() { return Arrays.asList("- - - - - - - - - - - - - - - - - - - foo", "- - - - - - - - - - - - - - - - - - - bar", "- - - - - - - - - - - - - - - - - - - baz"); } } }

Loader

FragmentTwo似乎导致问题。注释掉 initLoader 行会使片段生命周期再次按预期工作。

onResume()根据是否已调用public class FragmentTwo extends Fragment { private TextView text; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { text = new TextView(container.getContext()); text.setText("onCreateView() called"); return text; } @Override public void onResume() { super.onResume(); Log.i("Fragment2", "onResume() called"); text.setText("onResume() called"); } } 来更改其内容:

MainActivity

以下是无聊的代码。

public class MainActivity extends FragmentActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Fragment fragment = new MainFragment(); getSupportFragmentManager().beginTransaction().add(R.id.container, fragment).commit(); } }

activity_main

布局<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" />

MainFragment

public class MainFragment extends Fragment { private ViewPager viewPager; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View layout = inflater.inflate(R.layout.frag_master, container, false); viewPager = (ViewPager) layout.findViewById(R.id.view_pager); return layout; } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); viewPager.setAdapter(new MyPagerAdapter(getChildFragmentManager())); } private static final class MyPagerAdapter extends FragmentPagerAdapter { public MyPagerAdapter(FragmentManager fragmentManager) { super(fragmentManager); } @Override public int getCount() { return 2; } @Override public Fragment getItem(int position) { if (position == 0) return new FragmentOne(); else return new FragmentTwo(); } } }

frag_master

布局<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/view_pager" android:layout_width="match_parent" android:layout_height="match_parent" />

{{1}}

2 个答案:

答案 0 :(得分:11)

这似乎是支持库中的一个错误。下面的更改解决了这个问题。

// FragmentOne.java

@Override
public void onResume() {
    super.onResume();
    Handler handler = getActivity().getWindow().getDecorView().getHandler();
    handler.post(new Runnable() {
        @Override public void run() {
            // initialize the loader here!
            getLoaderManager().initLoader(0, null, FragmentOne.this);
        }
    });
}

答案 1 :(得分:3)

另一个对我有用的解决方法是使用MainFragment的加载程序管理器:

getParentFragment().getLoaderManager().initLoader(0, null, this);