Fragment特点:
-
Fragment有自己的生命周期、
-
Fragment依赖于Activity、
-
Fragment通过getActivity()可以获取所在的Activity;Activity通过FragmentManger的findFragementById()或者findFragmentByTag()获取Fragment;
-
Fragement和Activity是多对多的关系
Fragment的执行过程:
创建Fragment文件
类继承extend Fragment,函数体常用的包括onCreateView和onViewCreated两个主要函数
onCreateView函数:加载xml文件,绑定视图,显示布局
onViewCreated函数:调用控件,对事件的处理方法
把Fragment添加到Activity中
添加:getFragmentManager().beginTransaction().add(位置,目标,)
替换:getFragmentManager().beginTransaction().replace(位置,目标,)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_container);
mTvTitle = (TextView) findViewById(R.id.tv_title);
//实例化AFragment
aFragment = new AFragment();
//把AFragment添加到Activity中,记得调用commit
getFragmentManager().beginTransaction().add(R.id.fl_container,aFragment,"a").commitAllowingStateLoss();
}
向Fragment中传递参数
Activity code:
private AFragment aFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_container);
//实例化AFragment
aFragment = AFragment.newInstance("我是参数");
//把AFragment添加到Activity中,记得调用commit
getFragmentManager().beginTransaction().add(R.id.fl_container,aFragment,"a").commitAllowingStateLoss();
}
AFragment code:
// 传参方法,顺便也实例化了,通过bundle,核心是fragment.setArguments(bundle);
public static AFragment newInstance(String title){
AFragment fragment = new AFragment();
Bundle bundle = new Bundle();
bundle.putString("title",title);
fragment.setArguments(bundle);
return fragment;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// 绑定控件
mTvTitle = (TextView) view.findViewById(R.id.tv_title);
// 接收传参,修改textview的值
if(getArguments() != null){
mTvTitle.setText(getArguments().getString("title"));
}
}
Fragment回退栈操作
使用方法:.addToBackStack(null)
意思是在commit之前,先把将要原来的Fragment给压入回退栈中,这样返回的时候是返回到上一个Fragment,而不是上一个activity。
getFragmentManager().beginTransaction().replace(R.id.fl_container,bFragment).addToBackStack(null).commitAllowingStateLoss();
代码注解:在设置fragement跳转按钮的点击事件时,我们的代码如下所示:
mBtnChange.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(bFragment == null){
bFragment = new BFragment();
}
//创建一个对象去接getFragmentManger中找到的fragment
Fragment fragment = getFragmentManager().findFragmentByTag("a");
if(fragment != null){
//大部分情况下我们fragement都不为空,这么执行的目的是隐藏aFragment,再添加bFragment,避免了replace把先前的a删除,返回时重新执行onCreateView导致的参数丢失的问题
getFragmentManager().beginTransaction().hide(fragment).add(R.id.fl_container,bFragment).addToBackStack(null).commitAllowingStateLoss();
}else{
getFragmentManager().beginTransaction().replace(R.id.fl_container,bFragment).addToBackStack(null).commitAllowingStateLoss();
}
}
});
Fragment和Activity之间的通信
这部分又涉及到接口,我们从流程上感受一下
首先,我们在Fragment里面声明一个接口
// 定义OnMessageClick接口
public interface IOnMessageClick{
void onClick(String text);
}
然后,Activity里面实现这个接口
public class ContainerActivity extends AppCompatActivity implements AFragment.IOnMessageClick{
private AFragment aFragment;
private TextView mTvTitle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_container);
mTvTitle = (TextView) findViewById(R.id.tv_title);
//实例化AFragment
aFragment = AFragment.newInstance("我是参数");
//把AFragment添加到Activity中,记得调用commit
getFragmentManager().beginTransaction().add(R.id.fl_container,aFragment,"a").commitAllowingStateLoss();
}
public void setData(String text){
mTvTitle.setText(text);
}
@Override
public void onClick(String text) {
mTvTitle.setText(text);
}
}
然后在,onAttach方法里面赋值listener,内容就是强制转化为IOnMessageClick接口的activity,成功后我们就可以使用listener为我们向activity传递数据了
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
listener = (IOnMessageClick) activity;
}catch (ClassCastException e){
throw new ClassCastException("Activity 必须实现 IOnMessageClick接口");
}
}
在mBtnMessage的监听事件中调用接口的onclick方法,传送字符串text给activity
mBtnMessage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// ((ContainerActivity)getActivity()).setData("你好");
listener.onClick("你好呀");
}
});
(需要注意的是:由于Fragment自身的Bug,当SDK API<23时,onAttach(Context)不执行,需要使用onAttach(Activity)。v4的没有此问题)