Android中setArguments调用后,Fragment的onCreateView何时执行?
关于Fragment的setArguments与onCreateView执行时机的问题
嘿,我来帮你理清这两个问题:
1. 是的,onCreateView必须在setArguments之后执行,不过你的代码写法完全没问题
你理解的没错——如果onCreateView在setArguments之前执行,那getArguments()拿到的就是null,肯定会出问题。但看你在PagerAdapter的getItem方法里的写法:先创建DrinkFragment实例,接着设置Bundle参数,最后返回这个Fragment。这个流程是完全正确的,因为系统只会在你把Fragment实例返回给它之后,才会去触发Fragment的生命周期方法(包括onCreateView),所以你完全不用担心顺序问题,setArguments一定是在onCreateView之前执行的。
2. onCreateView的具体执行时机
Fragment的onCreateView是在Fragment的视图被首次创建时调用的,结合ViewPager的工作机制,它的执行时机有这些特点:
- 它会在Fragment的
onCreate方法之后,onActivityCreated方法之前执行; - ViewPager默认会预加载当前页面左右各一个Fragment(可以通过
setOffscreenPageLimit修改这个数量),也就是说,哪怕你还没滑动到某个页面,只要它是当前页面的相邻页面,系统就会提前创建它的视图,触发onCreateView; - 但无论预加载与否,
onCreateView的执行时机一定晚于你在getItem中调用setArguments的时间——因为系统必须先通过getItem拿到Fragment实例,才会去初始化它的视图。
额外建议:用newInstance模式创建Fragment更规范
虽然你的代码没问题,但推荐给DrinkFragment写一个静态的newInstance方法来创建实例并传递参数,这样可以避免忘记设置参数的情况,代码也更简洁:
public class DrinkFragment extends Fragment { private static final String TAG = "DrinkFragment"; int fragmentType; // 静态创建方法 public static DrinkFragment newInstance(int type) { DrinkFragment fragment = new DrinkFragment(); Bundle args = new Bundle(); args.putInt("type", type); fragment.setArguments(args); return fragment; } @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { Log.d(TAG, "onCreateView: Created"); Bundle bundle = this.getArguments(); fragmentType = bundle.getInt("type",0); Log.d(TAG, "Got the bundle type : "+fragmentType); View view = inflater.inflate(R.layout.fragment_drink,container,false); ImageView image = (ImageView) view.findViewById(R.id.image); switch(fragmentType){ case 0 : image.setImageResource(R.drawable.fragment_soju); return view; case 1: image.setImageResource(R.drawable.fragment_makgeoli); return view; case 2: image.setImageResource(R.drawable.fragment_cheongju); return view; default: return view; } } }
然后在PagerAdapter的getItem里就可以这样写:
@Override public Fragment getItem(int i) { switch(i){ case 0: Log.d(TAG, "getItem: 0 "); return DrinkFragment.newInstance(0); case 1: Log.d(TAG, "getItem: 1"); return DrinkFragment.newInstance(1); case 2: Log.d(TAG, "getItem: 2"); return DrinkFragment.newInstance(2); default: return null; } }
这样代码更清晰,也更符合Android开发的最佳实践~
内容的提问来源于stack exchange,提问作者JoyfulJoyce
相关产品推荐
相关产品推荐

