onResume()使用自定义程序的时候,不叫上ViewPager片段 [英] onResume() not called on ViewPager fragment when using custom Loader
问题描述
短版:
我有一个片段维持 ViewPager
显示其他两个片段,我们姑且称之为 FragmentOne
和 FragmentTwo
。当启动应用程序 FragmentOne
可见和 FragmentTwo
是关闭屏幕,成为可见的不仅是一个挥笔视图到离开了。
通常 ONSTART()
和 onResume()
想要获取该应用程序被启动立即调用的两个片段
我的问题是,当 FragmentOne
启动自定义装载机
然后 onResume()
不会被调用的 FragmentTwo
,直到它变得完全可见。
问题:
这是我的code问题或在Android支持库中的错误? (这个问题并没有与图书馆的修订12发生时,它开始修订13。)
如果它在修订记录13和18中的错误,有没有解决办法?
是不是有什么毛病我的自定义装载机
?
龙版本:
我已经建立了演示该问题的一个示例应用程序。我试图减少code到最低限度,但它仍然是一个很多,所以请大家多多包涵。
我有一个 MainActivity
加载一个 MainFragment
这将创建一个 ViewPager
。这是我的应用程序,该ViewPager是由一个片段,而不是一个活动保持重要的。
MainFragment
创建一个 FragmentPagerAdapter
,反过来创建片段 FragmentOne
和 FragmentTwo
。
让我们先从有趣的一点,这两个片段:
FragmentOne
是 ListFragment
使用自定义装载机
加载内容:
公共类FragmentOne扩展ListFragment实现LoaderCallbacks<列表<字符串>> {
私人ArrayAdapter<字符串>适配器;
@覆盖
公共无效onActivityCreated(包savedInstanceState){
super.onActivityCreated(savedInstanceState);
适配器=新的ArrayAdapter<字符串>(getActivity(),android.R.layout.simple_list_item_1);
setListAdapter(适配器);
setEmptyText(空);
}
@覆盖
公共无效onResume(){
super.onResume();
//初始化加载器似乎导致的问题!
getLoaderManager()initLoader(0,空,这一点)。
}
@覆盖
公共装载机<列表<字符串>> onCreateLoader(INT ID,捆绑参数){
返回新MyLoader(getActivity());
}
@覆盖
公共无效onLoadFinished(装载机<列表<字符串>>装载机,列表和LT;字符串>数据){
adapter.clear();
adapter.addAll(数据);
}
@覆盖
公共无效onLoaderReset(装载机<列表<字符串>>装载机){
adapter.clear();
}
公共静态类MyLoader扩展AsyncTaskLoader<列表<字符串>> {
公共MyLoader(上下文的背景下){
超(上下文);
}
@覆盖
保护无效onStartLoading(){
的forceload();
}
@覆盖
公开名单<字符串> loadInBackground(){
返回Arrays.asList( - - - - - - - - - - - - - - - - - - - foo的,
- - - - - - - - - - - - - - - - - - - 酒吧,
- - - - - - - - - - - - - - - - - - - 巴兹);
}
}
}
这是装载机
似乎引起问题。注释掉的 initLoader 的行使得作为再次预期片段生命周期的工作。
FragmentTwo
的基础上改变其内容是否 onResume()
已被调用与否:
公共类FragmentTwo扩展片段{
私人TextView的文字;
@覆盖
公共查看onCreateView(LayoutInflater充气,容器的ViewGroup,捆绑savedInstanceState){
文=新的TextView(container.getContext());
text.setText(onCreateView()叫做);
返回文本;
}
@覆盖
公共无效onResume(){
super.onResume();
Log.i(Fragment2,onResume()叫做);
text.setText(onResume()叫做);
}
}
这里是的code中的无聊休息。
MainActivity
:
公共类MainActivity扩展FragmentActivity {
@覆盖
保护无效的onCreate(包savedInstanceState){
super.onCreate(savedInstanceState);
的setContentView(R.layout.activity_main);
片段片段=新MainFragment();
。getSupportFragmentManager()的BeginTransaction()加(R.id.container,片段).commit();
}
}
布局 activity_main
:
<的FrameLayout的xmlns:机器人=http://schemas.android.com/apk/res/android
机器人:ID =@ + ID /容器
机器人:layout_width =match_parent
机器人:layout_height =match_parent/>
MainFragment
:
公共类MainFragment扩展片段{
私人ViewPager viewPager;
@覆盖
公共查看onCreateView(LayoutInflater充气,容器的ViewGroup,捆绑savedInstanceState){
查看布局= inflater.inflate(R.layout.frag_master,集装箱,假);
viewPager =(ViewPager)layout.findViewById(R.id.view_pager);
返回布局;
}
@覆盖
公共无效onActivityCreated(包savedInstanceState){
super.onActivityCreated(savedInstanceState);
viewPager.setAdapter(新MyPagerAdapter(getChildFragmentManager()));
}
私有静态final类MyPagerAdapter扩展FragmentPagerAdapter {
公共MyPagerAdapter(FragmentManager fragmentManager){
超(fragmentManager);
}
@覆盖
公众诠释getCount将(){
返回2;
}
@覆盖
公共片段的getItem(INT位置){
如果(位置== 0)
返回新FragmentOne();
其他
返回新FragmentTwo();
}
}
}
布局 frag_master
:
< android.support.v4.view.ViewPager的xmlns:机器人=http://schemas.android.com/apk/res/android
机器人:ID =@ + ID / view_pager
机器人:layout_width =match_parent
机器人:layout_height =match_parent/>
这似乎是在支持库中的错误。下面的改变解决了这个问题。
// FragmentOne.java
@覆盖
公共无效onResume(){
super.onResume();
处理程序的处理程序= getActivity()getWindow()getDecorView()getHandler()。;
handler.post(新的Runnable(){
@覆盖公共无效的run(){
//这里初始化加载器!
getLoaderManager()initLoader(0,空,FragmentOne.this)。
}
});
}
Short version:
I have a fragment that maintains a ViewPager
for displaying two other fragments, let's call them FragmentOne
and FragmentTwo
. When starting the app FragmentOne
is visible and FragmentTwo
is off-screen, becoming visible only as one swipes the view to the left.
Normally onStart()
and onResume()
get invoked immediately for both fragments as soon as the app gets started.
The problem I have is when FragmentOne
starts a custom Loader
then onResume()
does not get called on FragmentTwo
until it becomes fully visible.
Questions:
Is this a problem with my code or a bug in the Android Support Library? (The problem did not occur with revision 12 of the library, it started with revision 13.)
If it's a bug in revisons 13 and 18, is there a workaround?
Is there something wrong with my custom Loader
?
Long version:
I have built a sample application that demonstrates the problem. I have tried to reduce the code to the bare minimum but it's still a lot so please bear with me.
I have a MainActivity
that loads a MainFragment
which creates a ViewPager
. It is important for my app that the ViewPager is maintained by a Fragment instead of an Activity.
MainFragment
creates a FragmentPagerAdapter
that in turn creates the fragments FragmentOne
and FragmentTwo
.
Let's start with the interesting bit, the two fragments:
FragmentOne
is a ListFragment
that uses a custom Loader
to load the content:
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");
}
}
}
It is that Loader
that seems to cause the problem. Commenting out the initLoader line makes the fragment life-cycle work as expected again.
FragmentTwo
changes its content based on whether onResume()
has been invoked or not:
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");
}
}
And here is the boring rest of the code.
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();
}
}
Layout 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();
}
}
}
Layout 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" />
It appears to be a bug in support library. The change below solves the issue.
// 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);
}
});
}
这篇关于onResume()使用自定义程序的时候,不叫上ViewPager片段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!