Fragment工具类 - MvpFragmentManager

2020-08-27  本文已影响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>
上一篇下一篇

猜你喜欢

热点阅读