03 Android基础--fragment
什么是fragment?
碎片
,一个activity中可以使用多个fragment,可以把activity看成碎片
的容器。fragment也有自己的生命周期
fragment生命周期?
需要知道的是:
创建和重建
过程: Activity生命周期优先于Fragment
暂停和销毁
过程: Fragment生命周期优先于Activity
动态的fragment与静态的fragment
一个xml写,一个用Java代码写。
// 静态的fragment
// 第一步:编写fragment所需要的XML文件
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".BlankFragment1">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
android:textSize="30dp"/>
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="100dp"
android:text="Button" />
</FrameLayout>
// 第二步:编写activity所需要的XML文件,把fragment的XML定位到activity所需的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">
<!-- name为确定 这个fragment绑定的哪个,id必须设置,因为资源管理会使用。一个avtivity可以包含多个fragment-->
<fragment
android:id="@+id/fragment1"
android:name="com.example.fifthdemo_framgent_01.BlankFragment1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"/>
</LinearLayout>
// 第三步:编写fragment本身的代码
public class BlankFragment1 extends Fragment {
private View root;
private TextView textView;
private Button button;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (root == null) {
root = inflater.inflate(R.layout.fragment_blank1, container, false);
}
textView = root.findViewById(R.id.textView);
button = root.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
textView.setText("button setOnClickListener");
}
});
return root;
}
}
// 第四步:编写activity。这个时候,fragment就会被渲染到activity中了。
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
// 动态的fragment:一般都用这个
// 第一步:编写fragment所需要的XML文件
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".BlankFragment1">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
android:textSize="30dp"/>
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="100dp"
android:text="Button" />
</FrameLayout>
// 第二步:编写fragment本身的代码
public class BlankFragment1 extends Fragment {
private View root;
private TextView textView;
private Button button;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (root == null) {
root = inflater.inflate(R.layout.fragment_blank1, container, false);
}
textView = root.findViewById(R.id.textView);
button = root.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
textView.setText("button setOnClickListener");
}
});
return root;
}
}
// 第三步:编写activity所需要的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">
<Button
android:id="@+id/bt1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="add fragment" />
<Button
android:id="@+id/bt2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="repalce" />
<!-- fragment的容器,将来动态创建的fragment直接放这里面-->
<FrameLayout
android:id="@+id/framelayout_1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#A68EA3"/>
</LinearLayout>
// 第四步:编写activity,动态的创建fragment
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button1 = findViewById(R.id.bt1);
button1.setOnClickListener(this);
Button button2 = findViewById(R.id.bt2);
button2.setOnClickListener(this);
}
@Override
public void onClick(View view) { //点击事件
switch (view.getId()) {
case R.id.bt1: replaceFragment(new BlankFragment1());
break;
case R.id.bt2: replaceFragment(new ItemFragment2());
break;
}
}
private void replaceFragment(Fragment fragment) {
//获取Fragment的管理器类 FragmentManager
FragmentManager fragmentManager = getSupportFragmentManager();
//获取 FragmentManager中用于 Fragment 替换之类的类 FragmentTransaction
FragmentTransaction transaction = fragmentManager.beginTransaction();
//创建一个替换Fragment的事件
transaction.replace(R.id.framelayout_1,fragment); // 替换的是framelayout_1中的fragment
//将新的Fragment对象压入一个栈内,点击back会进行回退,而非退出app
transaction.addToBackStack(null);
//提交事件
transaction.commit();
}
}
补充:FragmentManager支持链式调用:
// FragmentManager支持链式调用:
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.fragment_container, ExampleFragment.class, null)
.setReorderingAllowed(true)
.addToBackStack("name") // name can be null
.commit();
fragment常用的两个类与API
常用的类
- FragmentManager :顾名思义是负责管理Fragment的管理类,可以对Fragment进行添加、移除、替换等操作。在activity中操作。
- FragmentTransaction :通过FragmentManager获得,保证了fragment操作的原子性。
常用的API
- FragmentTransaction transaction = fm.benginTransatcion();//开启一个事务
- transaction.add();//让Activity中添加一个Fragment
- transaction.remove();//从Activity移除一个Fragment,如果被移除的
Fragment没有添加到回退栈,这个Fragment事例将会被销毁。 - transaction.replace();//使用另一个Fragment替换当前到,就相当于remove()以后,再add()
- transaction.hide();//隐藏当前的Fragment。
- Transaction.show();//显示之前隐藏的Fragment
- detach();//将view从UI中移除和remove()不同,此时Fragment的状态依然由FragmentManager维护。
- attach();重建view视图,附加到UI上并显示。
- transaction.commit();//提交一个事务。
Fragment与Activity通信
有很多种,接下来说一些常用的
- 通过构造器
- 通过ViewModel
- 通过EventBus
- 通过接口回调
- 通过Handler
- 通过广播
接下来介绍两种最常用的:
// 通过构造器,在activity中。
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
Fragment fragTop = new FrameTop();
fragmentTransaction.replace(R.id.frame1,fragTop);
Bundle bundle = new Bundle();
fragTop.setArguments(bundle);
bundle.putString("name","fragTop");
fragmentTransaction.commit();
// 在fragment中获取
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
Bundle arguments = getArguments();
String name = arguments.getString("name");
}
// 通过viewModel,将来这个最常用
// 官方文档代码示例:
public class SharedViewModel extends ViewModel {
private final MutableLiveData<Item> selected = new MutableLiveData<Item>();
public void select(Item item) {
selected.setValue(item);
}
public LiveData<Item> getSelected() {
return selected;
}
}
public class ListFragment extends Fragment {
private SharedViewModel model;
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
model = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
itemSelector.setOnClickListener(item -> {
model.select(item);
});
}
}
public class DetailFragment extends Fragment {
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
SharedViewModel model = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
model.getSelected().observe(getViewLifecycleOwner(), item -> {
// Update the UI.
});
}
}