android3.0以后有的
一个Activity可以运行多个fragment
fragment不能脱离Activity而存在
Activity是屏幕主题Fragment是Activity的一个组成元素
静态加载:xml
动态加载:java code
生命周期:
一.当Fragment从创建到运行时回调的生命周期方法有:
1. onAttach():当 Fragment依附到Activity时调用的方法
2. onCreate() :当Fragment创建时调用的方法
3. onCreateView() :给Fragment加载布局时调用的方法
4. onActivityCreated():当该 Fragment依附的Activity创建时调用的方法
5. onStart():当 Fragment启动时调用的方法
6. onResume():当 Fragment正在运行时调用的方法
二.当Fragment不在使用时调用的生命周期方法
onPause();当Fragment不在交互时调用该方法
onStop0;当Fragment不再可见时调用该方法
onDestroyView():销毁Fragment布局时调用的方法
onDestroy() ;当Frament销毁时调用的方法
onDetach() ;当Fragment完全脱离Fragment时调用的方法
静态加载:
定义一个类继承自Fragment重写onCreateView方法加载fragment的布局
public class ListFragment extends Fragment {
//创建视图,主要生命周期
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
//布局文件,当前fragment所在的ViewGroup,是不是要绑定在当前根布局
View view = inflater.inflate(R.layout.fragment_list, container, false);
//TextView textView=view.findViewById(R.id.textView);相关操作
//textView.setText("imooc");
return view;
}
}
布局文件就是fragment的样子
使用fragment
一个Activity的布局文件中写
<fragment android:id="@+id/ListFragment" android:name="com.example.fragementstudy.ListFragment" android:layout_width="300dp" android:layout_height="200dp" />
定义了引用的Fragment的宽高而name是Fragment的java路径这样就成功在布局中引用了Fragment啦
动态加载:
ListFragment 为自定义的继承自Fragment的类这个类已经与布局绑定过了
//1.container容器 2.fragment 3.fragment放进container
ListFragment fragment=new ListFragment();
//管理fragment getSupportFragmentManager()为继承来的MainActivity extends AppCompatActivity extends FragmentActivity//FragmentActivity有这个方法
getSupportFragmentManager()
.beginTransaction()
.add(R.id.listContainer,fragment)
.commit();
add可以多次使用但要隐藏hide()不需要第一次就展现的
红色部分还有remove等其他方法
.remove(fragment)移除
.replace()替换
package com.example.myapplication;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.LinearLayout;
import com.example.myapplication.fragment.FindFragment;
import com.example.myapplication.fragment.MainFragment;
import com.example.myapplication.fragment.MeFragment;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
protected LinearLayout mMenuMain;
protected LinearLayout mMenuMe;
protected LinearLayout mMenuFind;
protected MainFragment mainFragment=new MainFragment();
protected MeFragment meFragment=new MeFragment();
protected FindFragment findFragment=new FindFragment();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
//获取管理类
this.getSupportFragmentManager()
.beginTransaction()
.add(R.id.container_content,mainFragment)
.add(R.id.container_content,findFragment).hide(findFragment)
.add(R.id.container_content,meFragment).hide(meFragment)
//事物添加,默认显示首页其他隐藏
//提交
.commit();
}
/**
* 初始化视图
* */
private void initView() {
mMenuMain =(LinearLayout) this.findViewById(R.id.menu_main);
mMenuMe =(LinearLayout) this.findViewById(R.id.menu_me);
mMenuFind =(LinearLayout) this.findViewById(R.id.menu_find);
mMenuMain.setOnClickListener(this);
mMenuFind.setOnClickListener(this);
mMenuMe.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.menu_main:
//获取管理类
this.getSupportFragmentManager()
.beginTransaction()
.show(mainFragment)
.hide(findFragment)
.hide(meFragment)
//事物添加,默认显示首页其他隐藏
//提交
.commit();
break;
case R.id.menu_find:
this.getSupportFragmentManager()
.beginTransaction()
.hide(mainFragment)
.show(findFragment)
.hide(meFragment)
//事物添加,默认显示首页其他隐藏
//提交
.commit();
break;
case R.id.menu_me:
this.getSupportFragmentManager()
.beginTransaction()
.hide(mainFragment)
.hide(findFragment)
.show(meFragment)
//事物添加,默认显示首页其他隐藏
//提交
.commit();
break;
}
}
}
传值问题
Activity-->Fragment
1.setArguments
在Fragment的具体子类里写一个静态(方便通过类名调用)返回值为该类对象的方法
重载该方法以便传输更多种类的数据
public static ListFragment newInstance(String title){ ListFragment fragment=new ListFragment(); Bundle bundle=new Bundle(); bundle.putString(BUNDLE_TITLE,title); fragment.setArguments(bundle); return fragment; }
这样上面的
getSupportFragmentManager() .beginTransaction() .add(R.id.listContainer,new ListFragment()) .commit();
就变成了
getSupportFragmentManager() .beginTransaction() .add(R.id.listContainer,ListFragment.newInstance("List")) .commit();
将数据放入bundle中
再将bundle放入本类对象的setArguments(bundle);中使用时
getArguments().getString(BUNDLE_TITLE);来取出
2.如要传入不能使用Bundle 的对象
重载上文的ListFragment.newInstance( String str,User user)
定义全局变量和该类为内部类定义全局变量的内部类
public static ListFragment newInstance(String title, User user) { ListFragment fragment = new ListFragment(); Bundle bundle = new Bundle(); bundle.putString(BUNDLE_TITLE, title); fragment.setArguments(bundle); fragment. setmUser(user); return fragment; }
Fragment-->Activity Fragment-->Fragment类似这里就写在一起
在fragment中{
先在类内部写一个接口
//定义接口 public interface onTitleClickListener { void onClick(String title);//会在Activity中实现该接口的方法来获取值 }
定义该接口的实现类对象
private onTitleClickListener mOnTitleClickListener;
设置接口方法
public void setMonTitleClickListener(onTitleClickListener monTitleClickListener) {
this.mOnTitleClickListener = monTitleClickListener;
}
最后在想要传值的监听事件中
if (mOnTitleClickListener != null) { mOnTitleClickListener.onClick("达拉蹦吧"); }
}
Activity中接受数据{
创建Fragment的子类对象后就调用
listFragment.setMonTitleClickListener(this);传入本类对象
最后在实现的接口方法
@Override public void onClick(String title) { setTitle(title); } 中数据就传回来了
}