Fragment-android基础控件
Fragment简述
Fragment意为碎片,它具有和Activity类似的性质和类似的生命周期,它无法独立存在,必须依赖于Activity,一个Activit中可以嵌入多个Fragment,Fragment的存在带来的好处有:
1.模块化(Modularity):我们不必把所有代码全部写在Activity中,而是把代码写在各自的Fragment中。
2.可复用(Reusability):多个Activity可以重用一个Fragment。
3.可适配(Adaptability):根据硬件的屏幕尺寸、屏幕方向,能够方便地实现不同的布局,这样用户体验更好。
Fragment生命周期
Fragment的生命周期和Activity很相似,需要注意的是Fragment的需要通过onAttach()来绑定到Activity,这也就对应了有onDetach()来解除绑定,其次对于onCreateView()这个方法,与之类似的有一个onViewCreate()方法,这个方法会在事务提交后,在分线程中执行,因此如果直接在transaction.add(fragment).commit();后操作fragment中的view组件,可能会出现NullPointerException
因此,如果要在添加完fragment后立即操作fragment的view组件,应将操作写在fragment类的onViewCreated()方法中,或者在提交时使用transaction.commitAllowingStateLoss();来提交事务,这两者都可以避免异常,此处可以参考:https://www.cnblogs.com/linghu-java/p/12176933.html
Fragment的添加方式
fragment的添加方式有两种,也就是静态添加和动态添加,静态添加的劣势就是无法复用,呆板,动态则刚好相反。
Fragment管理类
java版
package myStudy;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
public class myFragmentUtils {
private static final String TAG = myFragmentUtils.class.getSimpleName();
//当没有oldFragment时
public static void startFragment(FragmentManager fragmentManager, int rsd, Fragment fragment) {
startFragment(fragmentManager, rsd, fragment, null);
}
private static void startFragment(FragmentManager fragmentManager, int rsd, Fragment newFragment, Fragment oldFragment) {
FragmentTransaction transaction = fragmentManager.beginTransaction();
//将旧的移出
if (null != oldFragment) {
transaction.remove(oldFragment);
}
//将新的添加
if (!newFragment.isAdded()) {
//没有添加就添加
transaction.add(rsd, newFragment, newFragment.getClass().getSimpleName());
transaction.addToBackStack(newFragment.getClass().getSimpleName());
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
transaction.commitAllowingStateLoss();
} else if (!newFragment.isVisible()) {
//如果新的看不见就show
transaction.show(newFragment);
}
}
public static void startFragmentWithoutBackStack(FragmentManager fragmentManager, int rsd, Fragment fragment) {
FragmentTransaction transaction = fragmentManager.beginTransaction();
//将新的添加
if (!fragment.isAdded()) {
//没有添加就添加
transaction.add(rsd, fragment, fragment.getClass().getSimpleName());
transaction.addToBackStack(fragment.getClass().getSimpleName());
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
transaction.commitAllowingStateLoss();
} else if (!fragment.isVisible()) {
//如果新的看不见就show
transaction.show(fragment);
}
}
public static void exitFragment(FragmentManager fragmentManager) {
if (null != fragmentManager) {
fragmentManager.popBackStack();
}
}
public static void exitFragment(FragmentManager fragmentManager, Fragment fragment) {
if (null != fragmentManager && null != fragment) {
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.remove(fragment);
transaction.commitAllowingStateLoss();
}
}
public static void hideFragment(FragmentManager fragmentManager, Fragment fragment) {
if (null != fragmentManager && null != fragment) {
if (fragment.isHidden()) {
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.show(fragment);
}
}
}
public static void showFragment(FragmentManager fragmentManager, Fragment fragment) {
if (null != fragmentManager && null != fragment) {
if (fragment.isVisible()) {
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.hide(fragment);
}
}
}
public static boolean isHidden(Fragment fragment) {
return null == fragment || fragment.isHidden();
}
public static void replaceFragment(FragmentManager fragmentManager, int rsd, Fragment fragment) {
if (null != fragmentManager && null != fragment) {
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(rsd, fragment);
transaction.commitAllowingStateLoss();
}
}
}
kotlin版
package myStudy
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentTransaction
import myStudy.myFragmentUtils
object myFragmentUtils {
private val TAG = myFragmentUtils::class.java.simpleName
//当没有oldFragment时
fun startFragment(fragmentManager: FragmentManager, rsd: Int, fragment: Fragment) {
startFragment(fragmentManager, rsd, fragment, null)
}
private fun startFragment(
fragmentManager: FragmentManager,
rsd: Int,
newFragment: Fragment,
oldFragment: Fragment?
) {
val transaction = fragmentManager.beginTransaction()
//将旧的移出
if (null != oldFragment) {
transaction.remove(oldFragment)
}
//将新的添加
if (!newFragment.isAdded) {
//没有添加就添加
transaction.add(rsd, newFragment, newFragment.javaClass.simpleName)
transaction.addToBackStack(newFragment.javaClass.simpleName)
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
transaction.commitAllowingStateLoss()
} else if (!newFragment.isVisible) {
//如果新的看不见就show
transaction.show(newFragment)
}
}
fun startFragmentWithoutBackStack(
fragmentManager: FragmentManager,
rsd: Int,
fragment: Fragment
) {
val transaction = fragmentManager.beginTransaction()
//将新的添加
if (!fragment.isAdded) {
//没有添加就添加
transaction.add(rsd, fragment, fragment.javaClass.simpleName)
transaction.addToBackStack(fragment.javaClass.simpleName)
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
transaction.commitAllowingStateLoss()
} else if (!fragment.isVisible) {
//如果新的看不见就show
transaction.show(fragment)
}
}
fun exitFragment(fragmentManager: FragmentManager?) {
fragmentManager?.popBackStack()
}
fun exitFragment(fragmentManager: FragmentManager?, fragment: Fragment?) {
if (null != fragmentManager && null != fragment) {
val transaction = fragmentManager.beginTransaction()
transaction.remove(fragment)
transaction.commitAllowingStateLoss()
}
}
fun hideFragment(fragmentManager: FragmentManager?, fragment: Fragment?) {
if (null != fragmentManager && null != fragment) {
if (fragment.isHidden) {
val transaction = fragmentManager.beginTransaction()
transaction.show(fragment)
}
}
}
fun showFragment(fragmentManager: FragmentManager?, fragment: Fragment?) {
if (null != fragmentManager && null != fragment) {
if (fragment.isVisible) {
val transaction = fragmentManager.beginTransaction()
transaction.hide(fragment)
}
}
}
fun isHidden(fragment: Fragment?): Boolean {
return null == fragment || fragment.isHidden
}
fun replaceFragment(fragmentManager: FragmentManager?, rsd: Int, fragment: Fragment?) {
if (null != fragmentManager && null != fragment) {
val transaction = fragmentManager.beginTransaction()
transaction.replace(rsd, fragment)
transaction.commitAllowingStateLoss()
}
}
}
FragmentManager
getSupportFragmentManager()就是获取所在fragment 的父容器的管理器.
getFragmentManager()同理。
getChildFragmentManager()所得到的是在fragment 里面子容器的管理器。
FragmentManager宿主环境指的是其管理类,通常在Activity中通过接口getSupportFragmentManager或者getFragmentManager获得FragmentManager对象, 可以认为Activity是FragmentManager的宿主环境类.
Fragment的七嘴八舌
1.fragment的通信问题跳转至Activity与Fragment通信
2.fragment的重叠问题,在屏幕旋转或者内存重启的前提条件下可能会出现fragment的重叠现象,这种通常是因为在恢复的时候会回复fragment,然后在oncreate时会重新创建,这就导致了重叠情况。