Fragment的使用
一.首先创建Fragment文件
创建Fragment对象时,可以通过newInstance方法实例化AFragment
其中newInstance在实例化时内部通过setArguments进行传参数
public class AFragment extends Fragment {
public static AFragment newInstance(String title){
AFragment aFragment = new AFragment();
Bundle bundle = new Bundle();
bundle.putString("title", title);
aFragment.setArguments(bundle);
return aFragment;
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
/**
也可以直接用这种方式实现,直接用系统的比较方便
View view = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_temp_1, container, false);
*/
View view = inflater.inflate(R.layout.fragment_temp_1, container, false);
return view;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Log.i(TAG, "onViewCreated:");
if(getArguments() != null){
String title = getArguments().getString("title");
}
}
}
二.显示创建Fragment,有两种方式
1.通过xml创建
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<fragment
android:id="@+id/fragment_show"
android:name="com.org.temp.AFragment"
android:layout_width="match_parent"
android:layout_height="40dp" />
</LinearLayout>
直接在xml文件中通过fragment标签创建
注意点
-
xml中直接使用Fragment,fragment的标签一定要有id,不然编译的时候会报错
报错信息:Must specify unique android:id
-
在androidx中,使用的Activity继承自FragmentActivity,在FragmentActivity类中使用的是getSupportFragmentManager,所以通过getSupportFragmentManager()获取FragmentTransaction
/** * Return the FragmentManager for interacting with fragments associated * with this activity. */ @NonNull public FragmentManager getSupportFragmentManager() { return mFragments.getSupportFragmentManager(); }
-
如果需要获取xml中的fragment对象
Fragment showFragment = getSupportFragmentManager().findFragmentById(R.id.fragment_show);
2.动态创建fragment
- xml中声明要加载Fragment 的容器(R.id.fl_container)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<FrameLayout
android:id="@+id/fl_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
- 通过代码动态添加Fragment
//创建要显示的Fragment
Fragment aFragment = new AFragment();
//获取FragmentTransaction
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
//指定要加载Fragment的id,与创建的Fragment对象
fragmentTransaction.add(R.id.fl_container, aFragment);
//commit提交
fragmentTransaction.commit();
三.获取Fragment对象的方式
- xml中直接创建的Fragment,可以通过findFragmentById()方法获取Fragment的对象
Fragment showFragment = getSupportFragmentManager().findFragmentById(R.id.fragment_show);
- 通过findFragmentByTag()方式获取Fragment对象
Activity中add方法添加Fragment时,通过添加标签Tag的方式获取(“afragment”)进行提交commitAllowingStateLoss();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.add(AFragment.newInstance("titleA"), "afragment").commitAllowingStateLoss();
然后Fragment中通过findFragmentByTag()方法获取Fragment的对象
是否需要getActivity()方法,根据具体情况而定
Fragment cFragment = getActivity().getSupportFragmentManager().findFragmentByTag("afragment");
四.对Fragment进行操作
-
对新的fragment进行添加显示
addToBackStack()方法的调用需要注意之前状态的保存
在commit之前通过addToBackStack方法,把之后的fragment添加到栈中,可以进行返回操作
btn_click.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Fragment bFragment = new BFragment();
//通过addToBackStack方法,把之后的fragment添加到栈中,可以进行返回操作
getSupportFragmentManager().beginTransaction().addToBackStack(null)
.add(R.id.fl_framgent, bFragment).commit();
}
});
- fragment替换操作
btn_click.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Fragment bFragment = new BFragment();
//通过addToBackStack方法,把之后的fragment添加到栈中,可以进行返回操作
getSupportFragmentManager().beginTransaction()
.replace(R.id.fl_framgent, bFragment).commit();
}
});
通过replace方法调用的新的Fragment后,如果将新的Fragment加入栈中(通过调用addToBackStack方法),但是返回以后并不是之前的Fragment,之前的Fragment一些相关状态会丢失
注意
-
replace()与add()的区别在于Fragment调用的生命周期不同,具体用哪个需要根据具体情况判断
-
commit()与commitAllowingStateLoss()的区别:
commit()需要在onSaveInstanceState()之前调用,如果在之后调用就会出现Can not perform this action after onSaveInstanceState异常的提示
commitAllowingStateLoss()则不会进行onSaveInstanceState()保存前后的判断,则不会出现上面的异常提示
if(bFragment == null){ bFragment = new BFragment(); } getSupportFragmentManager().beginTransaction() .replace(R.id.frame_container,bFragment).commitAllowingStateLoss();
五.fragment中获取activity的方式
- 用一下方式去获取activity时,可能会造成内存泄漏
Activity mActivity;
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
mActivity = (Activity)context;
}
-
可以通过onAttach传入的context,强转成的Activity进行一些Activity中的方法回调,具体看情况确定
@Override public void onAttach(Context context) { super.onAttach(context); try { listener = (listenerImpl)context; //实现activity对fragment当中监听的接口 } catch (ClassCastException e) { e.printStackTrace(); } } @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); btn.setOnClickListener(new View.OnClickListener(){ listener.onClick("进行方法的回调"); //在此对onClick方法在Activity中进行回调 }); }
-
尽量通过getActivity()判断是否为空,进行操作
if(getActivity() != null){
}else{
}
六.Fragment与Activity的传值
-
可以通过setArgument(bundle)
AFragment aFragment = new AFragment(); Bundle bundle = new Bundle(); bundle.putString("title", title); aFragment.setArguments(bundle);
-
也可以通过intent进行传值
Intent intent = getActivity().getIntent();
-
通过findFragmentByTag()或findFragmentByTag()获得fragment对象