hide/show切换的BaseFragment

2020-07-02  本文已影响0人  九格
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();
    }
}
初始

切换到fragment2

getSupportFragmentManager().beginTransaction()
            .hide(f1)
            .hide(f3)
            .show(f2)
            .setMaxLifecycle(f2, Lifecycle.State.RESUMED)
            .commit();
show f2

切换到fragment3

getSupportFragmentManager().beginTransaction()
          .hide(f1)
          .hide(f2)
          .show(f3)
          .setMaxLifecycle(f3, Lifecycle.State.RESUMED)
          .commit();
show f3

再切回fragment1

getSupportFragmentManager().beginTransaction()
         .hide(f2)
         .hide(f3)
         .show(f1)
         .setMaxLifecycle(f1, Lifecycle.State.RESUMED)
         .commit();
切回f1

技拙 欢迎批评指正O(∩_∩)O

上一篇 下一篇

猜你喜欢

热点阅读