本文为自己多年来在Android实战开发过程中总结归纳的一些常见问题,现在分享出来希望对初学者有所帮助。
本文出自门心叼龙的博客,转载请注明出处: https://blog.csdn.net/geduo_83/article/details/86559417
目录
1. 请简述Fragment的意义?
2. 将一个Fragment添加到Activity布局的方式有几种?
3. 简述Fragment生命周期,常用的回调方法有几个?
4.怎么为Fragment绑定UI布局?
5.怎么去管理Fragment?
6.执行Fragment的事务,事务有什么特点?
7.为Activity创建Fragment的事件回调?
8.在Fragment中创建菜单直接复写onCreateOptionMenu方法可以吗?
9.如何实现多个Fragment之间的灵活切换?
10. Activity和Fragment 的 onActivityForResult 回调?
11.Fragment的View重复添加导致的崩溃问题?
12.Fragment的getActivity方法返回null的原因:
13.ViewPager中Fragment的缓存
当Activity的onCreate方法被回调时会导致fragment方法的onAttach()、onCreate()、onCreateView()、onActivityCreate() 被连续回调
复写onCreateView方法
inflate方法有三个参数
注意了:不管参数3是否为true都依附,系统默认已经将Layout插入至ViewGroup上如果为true,将添加一层冗余的视图
每个事务都表示执行一组变化,这些变化包括add()、remove()、replace()、addToBackStack()、setCustomAnimations、setTransition事务要生效必须调用commit,commit并不会立即执行,只能等待UI主线程空闲时才能执行也可以调用executePendingTransactions立即生效提交事务,commit在调用时机是Activity状态保存之前进行,也就是说如果在离开Activity是进行提交事务的操作,系统就会抛出异常
不行,必须在onCreate方法是调用setHasOptionsMenu方法才行onOptionItemSelected进行选择回调
public void switchContent(Fragment from, Fragment to) {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
if (!to.isAdded()) {
transaction.hide(from).add(R.id.frame_content, to).commit();
} else {
transaction.hide(from).show(to).commit();
}
}
public class BaseFragmentActiviy extends FragmentActivity {
private static final String TAG = "BaseActivity";
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
FragmentManager fm = getSupportFragmentManager();
int index = requestCode >> 16;
if (index != 0) {
index--;
if (fm.getFragments() == null || index < 0
|| index >= fm.getFragments().size()) {
Log.w(TAG, "Activity result fragment index out of range: 0x"
+ Integer.toHexString(requestCode));
return;
}
Fragment frag = fm.getFragments().get(index);
if (frag == null) {
Log.w(TAG, "Activity result no fragment exists for index: 0x"
+ Integer.toHexString(requestCode));
} else {
handleResult(frag, requestCode, resultCode, data);
}
return;
}
}
/**
* 递归调用,对所有子Fragement生效
*
* @param frag
* @param requestCode
* @param resultCode
* @param data
*/
private void handleResult(Fragment frag, int requestCode, int resultCode,
Intent data) {
frag.onActivityResult(requestCode & 0xffff, resultCode, data);
List frags = frag.getChildFragmentManager().getFragments();
if (frags != null) {
for (Fragment f : frags) {
if (f != null)
handleResult(f, requestCode, resultCode, data);
}
}
}
/**
* 得到根Fragment
*
* @return
*/
private Fragment getRootFragment() {
Fragment fragment = getParentFragment();
while (fragment.getParentFragment() != null) {
fragment = fragment.getParentFragment();
}
return fragment;
}
/**
* 启动Activity
*/
private void onClickTextViewRemindAdvancetime() {
Intent intent = new Intent();
intent.setClass(getActivity(), YourActivity.class);
intent.putExtra("TAG","TEST");
getRootFragment().startActivityForResult(intent, 1001);
}
如果把该view添加到父view那么也会引起重复添加而导致崩溃
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (view == null) {
view = inflater.inflate(R.layout.dd_fragment_year, container, false);
}
ViewGroup viewGroup = (ViewGroup) view.getParent();
if (viewGroup != null){
viewGroup.removeView(view);
}
return view;
}
如果系统内存不足、或者切换横竖屏、或者app长时间在后台运行,Activity都可能会被系统回收,但是Fragment并不会随着Activity的回收而被回收,从而导致Fragment丢失对应的Activity。这里,假设我们继承于FragmentActivity的类为MainActivity,其中用到的Fragment为FragmentA。
app发生的变化为:某种原因系统回收MainActivity——FragmentA被保存状态未被回收——再次点击app进入——首先加载的是未被回收的FragmentA的页面——由于MainActivity被回收,系统会重启MainActivity,FragmentA也会被再次加载——页面出现混乱,因为一层未回收的FragmentA覆盖在其上面——(假如FragmentA使用到了getActivity()方法)会报NullPointerException:
if(savedInstanceState!= null){
String FRAGMENTS_TAG = "android:support:fragments";
savedInstanceState.remove(FRAGMENTS_TAG);
}
public class MyApplication extends Application {
private static Context context;
@Override
public void onCreate() {
super.onCreate();
context = this;
}
public static Context getContext() {
return context;
}
}
当Fragment在Activity中被取消挂载再次挂载的时候Fragment各个生命周期都会重新执行
public class FragmentFound extends Fragment {
private View view;
@Override
public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
if(view == null){
view = inflater.inflate(R.layout.fragment_found, null);
}
ViewGroup parentView = (ViewGroup)view.getParent();
if(parentView != null){
parentView.removeView(view);
}
return view;
}
}
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if(isVisibleToUser){
//刷新操作
}
}
}