import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
/**
* 用 show / hide 切换的Fragment
*/
public abstract class BaseFragmentX extends Fragment implements View.OnClickListener {
protected abstract void initViews(View v);
protected abstract int getLayoutId();
/**
* 当这个Fragment显示
*/
protected abstract void onFmgShow();
/**
* 第一次显示
*/
protected abstract void onFirstShow();
/**
* 当这个Fragment隐藏
*/
protected abstract void onFmgHide();
private View mRootView;
protected View getRootView() {
return mRootView;
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
if (mRootView == null) {
View root = inflater.inflate(getLayoutId(), container, false);
mRootView = root;
initViews(root);
} else {
if (mRootView.getParent() != null) {
((ViewGroup) mRootView.getParent()).removeView(mRootView);
}
}
return mRootView;
}
protected <T extends View> T bindView(int resID) {
T view = mRootView.findViewById(resID);
view.setOnClickListener(this);
return view;
}
/**
* 如果fragment是通过hide/show切换的
* onResume只会在一开始的时候走一遍
* 所以原本在onResume/onPause中做的事情
* 改到这里来做
*
* onHiddenChanged必须是在发生切换之后才会被调用
*
* @param hidden 是否隐藏
*/
@Override
public void onHiddenChanged(boolean hidden) {
/*
* Fragment如果add了多个
* 并且 transaction.setMaxLifecycle(otherFragment1,Lifecycle.State.STARTED)
* .setMaxLifecycle(otherFragment2,Lifecycle.State.STARTED)
* .setMaxLifecycle(otherFragment3,Lifecycle.State.STARTED)
* .setMaxLifecycle(otherFragment4,Lifecycle.State.STARTED)
* .setMaxLifecycle(targetFragment,Lifecycle.State.RESUMED)
* commit之后它们都将经过onCreateView 而只有targetFragment走到了onResume
* 这个时候如果切换Fragment
* 没有显示(走了onResume)过的其他Fragment依然会触发onHiddenChanged
* */
if (hidden){
//只有 onFmgShow 发生过了之后 hide才触发 onFmgHide
if (hasShown){
onFmgHide();
}
}else{
hasShown = true;
if (!firstShow){
firstShow = true;
onFirstShow();
}
//fragment切换显示时理想情况childFragment也跟着走onFmgShow 但是并不会 这里手动调用一下
if (!getChildFragmentManager().getFragments().isEmpty()){
for (Fragment fragment : getChildFragmentManager().getFragments()){
if (fragment.isVisible()){
fragment.onHiddenChanged(false);
break;
}
}
}
onFmgShow();
}
//在super之前执行 否则childFragment不走onHiddenChanged
super.onHiddenChanged(hidden);
}
private boolean hasShown;//是否已经显示过
private boolean firstShow;//第一次显示
@Override
public void onResume() {
super.onResume();
if (!hasShown){
hasShown = true;
firstShow = true;
onFirstShow();
onFmgShow();
}
}
}
测试一下
public class TAty extends AppCompatActivity {
private TFragment f1,f2,f3;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.aty_t);
f1 = TFragment.newInstance(1);
f2 = TFragment.newInstance(2);
f3 = TFragment.newInstance(3);
getSupportFragmentManager().beginTransaction()
.add(R.id.frame,f1)
.add(R.id.frame,f2)
.add(R.id.frame,f3)
.setMaxLifecycle(f1, Lifecycle.State.RESUMED)
.setMaxLifecycle(f2, Lifecycle.State.STARTED)
.setMaxLifecycle(f3, Lifecycle.State.STARTED)
.commit();
}
}
![](https://img.haomeiwen.com/i2108326/30d088a428816200.png)
切换到fragment2
getSupportFragmentManager().beginTransaction()
.hide(f1)
.hide(f3)
.show(f2)
.setMaxLifecycle(f2, Lifecycle.State.RESUMED)
.commit();
![](https://img.haomeiwen.com/i2108326/f55ccbb80c814cd9.png)
切换到fragment3
getSupportFragmentManager().beginTransaction()
.hide(f1)
.hide(f2)
.show(f3)
.setMaxLifecycle(f3, Lifecycle.State.RESUMED)
.commit();
![](https://img.haomeiwen.com/i2108326/8c0876a5fe1d82bc.png)
再切回fragment1
getSupportFragmentManager().beginTransaction()
.hide(f2)
.hide(f3)
.show(f1)
.setMaxLifecycle(f1, Lifecycle.State.RESUMED)
.commit();
![](https://img.haomeiwen.com/i2108326/74561d2658e9beb9.png)
技拙 欢迎批评指正O(∩_∩)O
网友评论