美文网首页
Fragment工具类 - MvpFragmentManager

Fragment工具类 - MvpFragmentManager

作者: 魔女小姐的猫 | 来源:发表于2020-08-27 07:04 被阅读0次

    使用简便

            /**
            * MvpFragmentManager 添加Fragment的工具类
            *       addOrShowFragment()  添加Fragment方法
            *
             * @param FragmentManager manager  布局管理器 
             * @param Class<? extends BaseFragment> willShowFragment  将要进入的Fragment 
             * @param BaseFragment preFragment 将要退出的Fragment(可以为null)
             *  @param @IdRes int containerId  放置Fragment的容器FrameLayout
            */
            MvpFragmentManager.addOrShowFragment(getSupportFragmentManager(), MenuFragment.class, null, R.id.home_menu_fl);
    

    BaseFragment 抽象类

    package com.example.mvplib.fragment;
    
    
    import android.os.Bundle;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.FrameLayout;
    import android.widget.RelativeLayout;
    import android.widget.Toast;
    
    import androidx.annotation.IdRes;
    import androidx.annotation.NonNull;
    import androidx.annotation.Nullable;
    import androidx.annotation.StringRes;
    import androidx.appcompat.widget.ContentFrameLayout;
    import androidx.constraintlayout.widget.ConstraintLayout;
    import androidx.fragment.app.Fragment;
    
    import com.example.mvplib.R;
    
    
    public abstract class BaseFragment extends Fragment {
    
        @Nullable
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            //获取布局
            if(getLayoutId() == 0){
                return null;
            }
            View v  = inflater.inflate(getLayoutId(),container,false);
    
            String viewClassName = v.getClass().getName();
    
            if(viewClassName.equals(RelativeLayout.class.getName())
                    || viewClassName.equals(ConstraintLayout.class.getName())
                    || viewClassName.equals(FrameLayout.class.getName())
                    || viewClassName.equals(ContentFrameLayout.class.getName())){
    
                return v;
            }else{
    
                FrameLayout frameLayout = new FrameLayout(getContext());
                frameLayout.addView(v);
                frameLayout.setTag("wrap");
    
                return frameLayout;
            }
    
        }
    
        @Override
        public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
            super.onViewCreated(view, savedInstanceState);
            //绑定控件  支持3.6(bingView)
            if(view.getTag() != null){
                bindView(((ViewGroup)view).getChildAt(0));
            }else{
                bindView(view);
            }
    
            initView();
    
    
        }
    
        protected void bindView(View view){
    
        }
    
        @Override
        public void onDestroyView() {
            super.onDestroyView();
        }
    
        protected abstract int getLayoutId();
    
        protected  void initView(){ }
    
    
         //绑定控件   findViewById
        public  <T extends View> T findViewById(@IdRes int id){
            return getView().findViewById(id);
        }
    
        //Toast 土司
        protected void showToast(String content){
            Toast.makeText(getContext(),content,Toast.LENGTH_SHORT).show();
        }
    
        protected void showToast(@StringRes int id){
            Toast.makeText(getContext(),id,Toast.LENGTH_SHORT).show();
        }
    
        //是否显示动画
        public boolean isNeedAnimation(){
            return true;
        }
    
        public int  getEnterAnimation(){
    
            return R.anim.common_page_right_in;
        }
    
        public int  getExitAnimation(){
            return R.anim.common_page_left_out;
        }
        public int  getPopEnterAnimation(){
            return R.anim.common_page_left_in;
        }
        public int  getPopExitAnimation(){
            return R.anim.common_page_right_out;
        }
        //是否进入到回退栈
        public boolean isNeedAddToBackStack(){
            return true;
        }
    
        /**
         * 对上一个fragment 如何进行处理
         */
        public Action getActionFroPreFragment(){
            return Action.HIDE;
        }
    
        public enum Action{
            NONE,HIDE,DETACH,REMOVE
        }
    }
    
    

    MvpFragmentManager 类

    package com.example.mvplib.fragment;
    
    import androidx.annotation.IdRes;
    import androidx.fragment.app.FragmentManager;
    import androidx.fragment.app.FragmentTransaction;
    
    
    public class MvpFragmentManager {
    
    
        /**
         * add  -- remove
         *
         * replace -> (add remove)
         *
         *
         * show --> hide
         * attach --> detach
         *
         *
         *
         * 某一次操作,add B hide A
         *
         * 返回时: remove B  show A
         */
    
    
    
    
        public static BaseFragment addOrShowFragment(FragmentManager manager, Class<? extends BaseFragment> willShowFragment,BaseFragment preFragment,@IdRes int containerId){
    
            FragmentTransaction transaction = manager.beginTransaction();
            try {
    
                String tag = willShowFragment.getName();
    
                BaseFragment  willShowFragmentInstance = (BaseFragment) manager.findFragmentByTag(tag);
    
                if(willShowFragmentInstance == null){ // 当前activity 已经添加了 该fragment
    
                    willShowFragmentInstance = willShowFragment.newInstance();
    
                    /**
                     * `17: 18  从 A  进入B   此时事务里面记录的 将要显示的fragment 是B ,上一个是A 。 提交过后,这个事务这个记录是不不是已经被记录了。17: 20 的时候
                     * 按返回键。拿出 17:18 分记录的那个事务,进行逆向操作。
                     *
                     * 比如:从A 里面 要显示B 。 B 就是将要显示的fragment .A 就是上一个 fragment
                     * 第一个 enter : 表示将要显示的 fragment 进入的动画
                     * 第二个 exit : 新fragment 进入,上一个fragment 退出的动画
                     * 第三个 popEnter : 表示按返回键时上一个fragment 弹进的动画
                     * 第四个 popExit: 表示按返回键时 将要显示的fragment 被弹出的动画
                     */
                    transaction.setCustomAnimations(
    
                            willShowFragmentInstance.isNeedAnimation() ?   willShowFragmentInstance.getEnterAnimation() : 0,
                            (preFragment == null ? 0 : (preFragment.isNeedAnimation() ? preFragment.getExitAnimation() :0)),
                            (preFragment == null ? 0 : (preFragment .isNeedAnimation() ? preFragment.getPopEnterAnimation() : 0))
                            , willShowFragmentInstance .isNeedAnimation() ? willShowFragmentInstance.getPopExitAnimation() : 0);
    
                    transaction.add(containerId,willShowFragmentInstance, tag);
    
                    if(willShowFragmentInstance.isNeedAddToBackStack()){
                        transaction.addToBackStack(tag); // 把这一次事务添加到回退栈里面
                    }
    
                }else{ // 当前 activity 已经添加过这个fragment
    
                   int count = manager.getBackStackEntryCount(); // 获取回退栈里面 事务的个数
    
                    FragmentManager.BackStackEntry entry = null;
                    for(int i = 0; i < count; i++){
                        entry = manager.getBackStackEntryAt(i);
                        if(entry.getName().equals(tag)){
                            manager.popBackStackImmediate(tag,0);
                            return willShowFragmentInstance;
                        }
                    }
                    if(count > 0){
                        manager.popBackStackImmediate(manager.getBackStackEntryAt(0).getName(),FragmentManager.POP_BACK_STACK_INCLUSIVE);
                        return willShowFragmentInstance;
                    }else{
                        if(!willShowFragmentInstance.isAdded()){ // 如果没有添加
                            transaction.add(containerId,willShowFragmentInstance, tag);
                        }
                        if(willShowFragmentInstance.isDetached()){ // 如果从activity  detach 了
                            transaction.attach(willShowFragmentInstance);
                        }
                        if(willShowFragmentInstance.isHidden()){// 如果被隐藏了
                            transaction.show(willShowFragmentInstance);
                        }
    
                    }
                }
    
                handPreFragment(transaction,preFragment,willShowFragmentInstance);
                transaction.commit();
                return willShowFragmentInstance; // 把自己(即将要显示的) 返回出去。
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
    
    
        private static void handPreFragment(FragmentTransaction transaction,BaseFragment preFragment,BaseFragment willShowFragment){
            if(preFragment != null){
    
                switch (willShowFragment.getActionFroPreFragment()){
                    case REMOVE:{
                        transaction.remove(preFragment);
                        break;
                    }
                    case DETACH:{
                        transaction.detach(preFragment);
                        break;
                    }
                    case HIDE:{
                        transaction.hide(preFragment);
                        break;
                    }
                }
            }
    
        }
    }
    
    

    四种动画

    R.anim.common_page_right_in

    <?xml version="1.0" encoding="utf-8"?>  
    <!--<set xmlns:android="http://schemas.android.com/apk/res/android">  
        <objectAnimator
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:duration="500"
            android:propertyName="x"
            android:valueFrom="640"
            android:valueTo="0"
            android:valueType="floatType" />
    </set> -->
    <set>
      <translate xmlns:android="http://schemas.android.com/apk/res/android"
       android:fromXDelta="100%"
       android:toXDelta="0"
       android:interpolator="@android:anim/decelerate_interpolator"
       android:duration="500"/>
    </set>
    

    R.anim.common_page_left_out

    <?xml version="1.0" encoding="utf-8"?>  
    <set>
      <translate xmlns:android="http://schemas.android.com/apk/res/android"
       android:fromXDelta="0"
       android:toXDelta="-100%"
       android:interpolator="@android:anim/decelerate_interpolator"
       android:duration="500"/>
    </set>
    

    R.anim.common_page_left_in

    <?xml version="1.0" encoding="utf-8"?>  
    <set>
      <translate xmlns:android="http://schemas.android.com/apk/res/android"
       android:fromXDelta="-100%"
       android:toXDelta="0"
       android:interpolator="@android:anim/decelerate_interpolator"
       android:duration="500"/>
    </set>
    

    R.anim.common_page_right_out

    <?xml version="1.0" encoding="utf-8"?>  
    <!-- <set xmlns:android="http://schemas.android.com/apk/res/android">  
       <objectAnimator
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:duration="500"
            android:propertyName="x"
            android:valueFrom="0"
            android:valueTo="640"
            android:valueType="floatType" />
    </set> -->
    <set>
      <translate xmlns:android="http://schemas.android.com/apk/res/android"
       android:fromXDelta="0"
       android:toXDelta="100%"
       android:interpolator="@android:anim/decelerate_interpolator"
       android:duration="500"/>
    </set>
    

    相关文章

      网友评论

          本文标题:Fragment工具类 - MvpFragmentManager

          本文链接:https://www.haomeiwen.com/subject/fagnjktx.html