Fragment三:对Fragment切换,跳转的封装

概述:

在使用了良久的Fragment后,为了能够更方便更快捷更好的屏蔽掉fragment原有问题,于是自定对Fragemnt进行了使用的封装。

目录:
* 用法

用法

导入代码

在底部有类的完整源码,可自行Copy复制到项目。

所需Copy代码

FragmentController的初始化
  1. 在主activity中或者BaseActivity中,以成员变量初始化创建对象
public FragmentController mFragmentManager = new FragmentController(this);
  1. 在主activity中或者BaseActivity中的dispatchKeyEvent函数中,实现方法mFragmentManager.onBackPressedListener()接口调用
/**
     * Explain : 设定生效后退的间隔时间
     *
     * @author LiXaing create at 2017/8/21 18:30
     */
    public static final int MIN_CLICK_DELAY_TIME = 500;

    /**
     * Explain : 上一次点击后退的时间节点
     *
     * @author LiXaing create at 2017/8/17 0:12
     */
    private static long lastKeyDownTime = 0;

@SuppressLint("RestrictedApi")
    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {//点击的是返回键
            /**        Explain : 当高频率点击返回的时候,由于过渡动画的原因会导致程序Crash,所以需要设定,
             *                   在过渡动画展示的过程中,则不允许继续popFragment
             * @author LiXaing create at 2017/8/17 0:07*/
            long currentTime = Calendar.getInstance().getTimeInMillis();
            /**        Explain : 动画时间为300,MIN_CLICK_DELAY_TIME为400,是为了动画完全结束后再允许下一次的pop
             * @author LiXaing create at 2017/8/17 0:09*/
            if (currentTime - lastKeyDownTime < MIN_CLICK_DELAY_TIME) {
                return true;
            }
            lastKeyDownTime = currentTime;

            if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) {//按键的按下事件
                mFragmentManager.onBackPressedListener();
            } else if (event.getAction() == KeyEvent.ACTION_UP && event.getRepeatCount() == 0) {}
            return true;
        }
        return super.dispatchKeyEvent(event);
    }
  1. 在所有fragment的基类BaseFragment中的onCreateView中初始化FragmentController对象
        mActivity = (MainActivity) getActivity();//此处的MainActivity是主activity其父类BaseActivity初始化创建了FragmentController实例对象,此处自行修改为初始化创建了FragmentController实例对象的activity即可
        mFragmentManager = mActivity.mFragmentManager;
  1. 在所有fragment的基类BaseFragment中实现一个空函数
/**
     * Explain : 需要监听后退的Fragment子类就复写实现此方法
     *@return : 当子类返回true,则认为当前后退由子类自己执行,不执行后退操作,全权交给子类自己去处理
     *           当子类返回false,则认为当前子类不做处理,直接退出当前fragment
     * @author LiXaing create at 2017/7/19 17:54
     */
    protected boolean onBackPressed() {return false;}

API示例

getInstanceAaddFragment()
                .setFrameID(R.id.realcontent)//传入展示xml布局中展示的FrameLayout的id,此处可在下面给的AddFragmentBean中设定默认值,那么在后面的常规使用中,就不许要再设定
                .setFragment(fragment)//设置需要跳转的Fragment
                .setBundle(bundle)//需要传递的Bundle
                .setAddToBackStack(true)//添加入回退栈,false则不加入,默认为false
                .setAliasName("Alias")//设置当前Fragment的别名,当没传入,默认为calssName
                .setOpenAnimation(true)//是否开启加载动画,默认为true
                .setShow(true)//commit后,是否就直接展示出来,false则不展示,默认为true
                .setChildFragment(true)//当前跳转的Fragment是否是被嵌套的,如果是则需要设定为true,默认为false
                .setLoadTtpe(AddFragmentBean.LoadTtpe.add)//跳转的加载类型,有两个枚举类型,AddFragmentBean.LoadTtpe.add、AddFragmentBean.LoadTtpe.replace
                .commit();//提交完成的设定
常规调用
//上面给的是全面的参数设定,在一般的常规使用跳转,就如下,非常简洁的一行代码。
getInstanceAaddFragment().setFragment(fragment).commit();
//另外如果有什么需求,可以按照参数设定的解释,自行给出设定就好了

所需Copy代码

FragmentManager

/**
 * Created by Administrator on 2018/1/30.
 */

import android.annotation.SuppressLint;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;

import com.icarzoo.project.boss.bean.basebean.AddFragmentBean;
import com.icarzoo.project.ui.MainActivity;
import com.icarzoo.project_base_config.utill.LogSwitchUtils;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.List;

/**        Explain : 用于管理Fragmen的:
 *                   跳转
 *                   回退
 *                   回退监听
 *                   对Fragment的栈管理
* @author LiXiang create at 2018/1/30 18:46*/
public class FragmentController {

    private final FragmentManager supportFragmentManager;

    private FragmentActivity mActivity;
    private Fragment baseFragment;

    public FragmentController(FragmentActivity activity){
        this.mActivity = activity;
        this.supportFragmentManager = mActivity.getSupportFragmentManager();

    }

    public void setBaseFragment(Fragment baseFragment) {
        this.baseFragment = baseFragment;
    }

    /**        Explain : Fragment的回退监听
    * @author LiXiang create at 2018/1/30 19:03*/
    @SuppressLint("RestrictedApi")
    public void onBackPressedListener(){
        LogSwitchUtils.Log("回退","dispatchKeyEvent--Down");
        android.support.v4.app.FragmentManager fm = getFragmentManager(false);
        LogSwitchUtils.Log("回退",""+fm.getBackStackEntryCount()+" name:"+this.getClass().getSimpleName());

        if (fm.getBackStackEntryCount() > 1) {
            @SuppressLint("RestrictedApi")
            BaseFragment fragment = (BaseFragment) getFragments().get(fm.getBackStackEntryCount()-1);
            if (fragment != null) {
                LogSwitchUtils.Log("回退","当前Fragment的名字"+fragment.getClass().getSimpleName());
                /**        Explain : 判断上一个fragment是否需要监听后退事件,当需要的时候则执行
                 * @author LiXiang create at 2017/12/8 14:44*/
                /**        Explain : 当当前的fragment没有后退监听则看其内部有没有chlild,有看child有没有后退监听
                 * @author LiXiang create at 2017/12/8 15:57*/
                android.support.v4.app.FragmentManager fmChild = fragment.getChildFragmentManager();
                if (fmChild.getFragments()!= null && fmChild.getFragments().size() > 0) {
                    /**        Explain : 先循环子类需要执行的回退事件
                    * @author LiXiang create at 2018/3/21 11:47*/
                    for (Fragment fragment1 : fmChild.getFragments()) {
                        BaseFragment BFFragment1 = (BaseFragment) fragment1;
                        if (BFFragment1 != null) {
                            LogSwitchUtils.Log("回退","子fragment的名字:"+BFFragment1.getClass().getSimpleName());
                            if (BFFragment1.isShow && BFFragment1.onBackPressed() == false) {
                                fm.popBackStack();
                            }
                        }
                    }

                    /**        Explain : 执行父Fragment的回退事件
                     * @author LiXiang create at 2018/3/21 11:47*/
                    if (!fragment.onBackPressed()) {
                        fm.popBackStack();
                    }

                }else {
                    if (!fragment.onBackPressed()) {
                        fm.popBackStack();
                    }
                }
            }
        }else {
            BaseActivity activity = (BaseActivity) mActivity;
            activity.exitApp();
        }
    }



    /**
     * @apiNote Fragment的跳转封装
     * @author LiXaing
     * create at 2017/4/30 19:38
     */
    public AddFragmentBean getInstanceAaddFragment() {
        return new AddFragmentBean() {
            @Override
            public void AddFragmentListener() {
                Message message = new Message();
                message.obj = this;
                if (isOpenAnimation()) {
                    handler.sendMessageDelayed(message,305);
                }else {
                    handler.sendMessageDelayed(message,5);
                }
            }
        };
    }


    Handler handler = new Handler(new Handler.Callback(){
        @Override
        public boolean handleMessage(Message msg) {
            AddFragmentBean mAddFragmentBean = (AddFragmentBean) msg.obj;
                            addFragment(mAddFragmentBean);
//            selectFragmentShow(msg.what);
            return true;
        }
    });



    public ArrayList<Fragment> getFragments() {
        ArrayList<Fragment> fragments1 = new ArrayList<>();
        @SuppressLint("RestrictedApi") List<Fragment> fragments = getFragmentManager(false).getFragments();
        for (Fragment fragment : fragments) {
            if (fragment != null) {
                fragments1.add(fragment);
            }
        }
        return fragments1;

    }

    @SuppressLint("RestrictedApi")
    public void addFragment(AddFragmentBean addFragmentBean) {
        addFragmentBean.fragment.setArguments(addFragmentBean.bundle);
        FragmentManager fm;
        /**        Explain : 判断是否是Fragment中的Fragment
         * @author LiXiang create at 2017/10/12 18:18*/
        if (addFragmentBean.isChildFragment) {
            LogSwitchUtils.Log("addFragment          ",getFragmentManager(false).getBackStackEntryCount()-1+"");
            LogSwitchUtils.Log("addFragment Fragments",getFragmentManager(false).getFragments()+"");


            LogSwitchUtils.Log("addFragment           2",getFragmentManager(false).getBackStackEntryCount()-1+"");
            LogSwitchUtils.Log("addFragment Fragments 2",getFragments().size()+"");

            fm =  getFragmentManager(true);
//            fm =  addFragmentBean.baseFragment.getChildFragmentManager();
            BaseFragment BFfragment = (BaseFragment) addFragmentBean.fragment;
            LogSwitchUtils.Log("isChildFragment",""+addFragmentBean.isChildFragment()+" name:"+BFfragment.getClass().getSimpleName());
        }  else {
            fm = supportFragmentManager;
        }
        if (fm == null) {
            return;
        }
        FragmentTransaction tx = fm.beginTransaction();
        if (addFragmentBean.loadTtpe == AddFragmentBean.LoadTtpe.add) {
            tx.add(addFragmentBean.FrameID, addFragmentBean.fragment, addFragmentBean.fragment.getClass().getName());
        } else {
            tx.replace(addFragmentBean.FrameID, addFragmentBean.fragment, addFragmentBean.fragment.getClass().getName());
        }
        if (addFragmentBean.addToBackStack && addFragmentBean.isChildFragment == false) {
//            aliasName = fragment.getClass().getName();
            if (addFragmentBean.aliasName == null) {
                tx.addToBackStack(addFragmentBean.fragment.getClass().getName());
                LogSwitchUtils.Log("addFragmentBean.fragment.getClass:", addFragmentBean.fragment.getClass().getSimpleName());
                LogSwitchUtils.Log("addFragmentBean.fragment.getClass:", addFragmentBean.fragment.getClass().getName());
            } else {
                tx.addToBackStack(addFragmentBean.aliasName);
            }
        }
        if (!addFragmentBean.isShow()) {
            tx.hide(addFragmentBean.fragment);
            BaseFragment bf = (BaseFragment) addFragmentBean.fragment;
            bf.isShow = false;
        }
        tx.commitAllowingStateLoss();
    }




    /**
     * show一个Fragment,hide另一个/多个Fragment ; 主要用于类似微信主页那种 切换tab的情况
     *
     * @param showFragment    需要show的Fragment
     * @param hideFragment    需要hide的Fragment
     * @param isChildFragment 当时Fragment是否是在Fragment中的fragment
     */
    public void showHideFragment(Fragment showFragment, Fragment hideFragment, Boolean isChildFragment) {

        if (showFragment == hideFragment) return;
        FragmentManager fm = getFragmentManager(isChildFragment);
        FragmentTransaction ft = fm.beginTransaction();
        if (hideFragment == null) {
            @SuppressLint("RestrictedApi") List<Fragment> fragmentList = fm.getFragments();
            if (fragmentList != null) {
                for (Fragment fragment : fragmentList) {
                    if (fragment != null && fragment != showFragment) {
                        ft.hide(fragment);
                        BaseFragment bf = (BaseFragment) fragment;
                        bf.isShow = false;
                        LogSwitchUtils.Log("fragmentName",fragment.getClass().getSimpleName());
                    }
                }
            }
        } else {
            ft.hide(hideFragment);
            BaseFragment bf = (BaseFragment) hideFragment;
            bf.isShow = false;
        }
        ft.show(showFragment);
        BaseFragment bf = (BaseFragment) showFragment;
        bf.isShow = true;
        ft.commitAllowingStateLoss();
    }


    /**
     * show一个Fragment,hide另一个/多个Fragment ; 主要用于类似微信主页那种 切换tab的情况
     *
     * @param showFragment    需要show的Fragment的全路径名称
     * @param hideFragment    需要hide的Fragment的全路径名称
     * @param isChildFragment 当时Fragment是否是在Fragment中的fragment
     */
    protected void showHideFragment(String showFragment, String hideFragment, Boolean isChildFragment) {

        if (showFragment == hideFragment) return;

        FragmentManager fm = getFragmentManager(isChildFragment);
        FragmentTransaction ft = fm.beginTransaction();

        if (hideFragment == null) {
            @SuppressLint("RestrictedApi") List<Fragment> fragmentList = getFragments();
            if (fragmentList != null) {
                for (Fragment fragment : fragmentList) {
                    if (fragment != null && fragment.getClass().getName() != showFragment) {
                        ft.hide(fragment);
                        BaseFragment bf = (BaseFragment) fragment;
                        bf.isShow = false;
                    }
                }
            }
        } else {
            Fragment hideFragment1 = fm.findFragmentByTag(hideFragment);
            ft.hide(hideFragment1);
            BaseFragment bf = (BaseFragment) hideFragment1;
            bf.isShow = false;
        }
        if (fm.findFragmentByTag(showFragment) != null) {
            Fragment showFragment1 = fm.findFragmentByTag(showFragment);
            ft.show(showFragment1);
            BaseFragment bf = (BaseFragment) showFragment1;
            bf.isShow = true;
        }
        ft.commitAllowingStateLoss();
    }

    /**
     * Explain : 展示某一个Fragemnt
     *
     * @author LiXiang create at 2017/10/4 16:45
     */
    public Fragment showFragment(Fragment showFragment, boolean isChildFragment) {
        FragmentManager fm = getFragmentManager(isChildFragment);
        BaseFragment bf = (BaseFragment) showFragment;
        bf.isShow = true;
        fm.beginTransaction().show(showFragment).commitAllowingStateLoss();
        return showFragment;
    }

    /**
     * Explain : 展示某一个Fragemnt
     *
     * @author LiXiang create at 2017/10/4 16:45
     */
    protected void showFragment(String showFragmentTag, boolean isChildFragment) {
        FragmentManager fm = getFragmentManager(isChildFragment);
        Fragment showFragment1 = fm.findFragmentByTag(showFragmentTag);
        BaseFragment bf = (BaseFragment) showFragment1;
        bf.isShow = true;
        fm.beginTransaction().show(showFragment1).commitAllowingStateLoss();
    }


    /**
     * Explain : 隐藏某一个Fragemnt
     *
     * @author LiXiang create at 2017/10/4 16:45
     */
    protected Fragment hideFragment(Fragment hideFragment, boolean isChildFragment) {
        FragmentManager fm = getFragmentManager(isChildFragment);
        BaseFragment bf = (BaseFragment) hideFragment;
        bf.isShow = false;
        fm.beginTransaction().hide(hideFragment).commitAllowingStateLoss();
        return hideFragment;
    }

    /**
     * Explain : 隐藏某一个Fragemnt
     *
     * @author LiXiang create at 2017/10/4 16:45
     */
    protected void hideFragment(String hideFragmentTag, boolean isChildFragment) {
        FragmentManager fm = getFragmentManager(isChildFragment);
        Fragment hideFragment = fm.findFragmentByTag(hideFragmentTag);
        BaseFragment bf = (BaseFragment) hideFragment;
        bf.isShow = false;
        fm.beginTransaction().hide(hideFragment).commitAllowingStateLoss();
    }

    protected void removeFragment(Fragment removeFragment, boolean isChildFragment) {
        FragmentManager fm = getFragmentManager(isChildFragment);
        fm.beginTransaction().remove(removeFragment).commit();
    }

    protected void removeFragment(String Tag, boolean isChildFragment) {
        FragmentManager fm= getFragmentManager(isChildFragment);
        fm.beginTransaction().remove(fm.findFragmentByTag(Tag)).commitAllowingStateLoss();
    }

    protected void removeAllFragment(boolean isChildFragment) {
        FragmentManager fm = getFragmentManager(isChildFragment);


        @SuppressLint("RestrictedApi") List<Fragment> fragmentList = getFragments();
        if (fragmentList != null) {
            for (Fragment fragment : fragmentList) {
                if (fragment != null) {
                    fm.beginTransaction().remove(fragment);
                }
            }
        }

    }

    @SuppressLint("RestrictedApi")
    private FragmentManager getFragmentManager(boolean isChildFragment){
//        System.out.println("getFragmentManager: "+supportFragmentManager.getBackStackEntryCount()+"");
//            System.out.println("getFragmentManager  name:  "+supportFragmentManager.getFragments().get(supportFragmentManager.getBackStackEntryCount()-1).getClass().getName());
        FragmentManager fm;
        if (isChildFragment) {
//            fm = supportFragmentManager.getFragments().get(supportFragmentManager.getBackStackEntryCount()-1).getChildFragmentManager();;
            fm = getFragments().get(supportFragmentManager.getBackStackEntryCount()-1).getChildFragmentManager();;

        } else {
            fm = supportFragmentManager;
        }
        return fm;
    }



    /**
     * Explain : 设定生效后退的间隔时间
     *
     * @author LiXaing create at 2017/8/21 18:30
     */
    public static final int MIN_CLICK_DELAY_TIME = 500;

    /**        Explain : 设定生效动画的的间隔时间
     * @author LiXaing create at 2017/8/21 18:31*/
//  public static final int MIN_ANIMATION_TIME = 300;

    /**
     * Explain : 上一次点击后退的时间节点
     *
     * @author LiXaing create at 2017/8/17 0:12
     */
    private static long lastKeyDownTime = 0;

    /**        Explain : 弹栈的方式
    * @author LiXiang create at 2018/1/31 17:33*/
    public enum popType {
        INCLUDING_YOURSELF,//包括自己
        NOT_INCLUDING_YOURSELF;//不包括自己
    }

    /**
     * Explain : 选择弹出Fragment的方式
     *
     * @param isHaveFlage 是否一次弹出多个Fragment
     * @param nameTag     一次弹出多个Fragment,回退到指定的nameTag的Fragment
     * @param type        一次弹出多个Fragment,的类型,是否包含自身一起弹出
     * @author LiXaing create at 2017/8/21 18:24
     */
    public void switchPopBackStack(BaseFragment baseFragment,boolean isHaveFlage, String nameTag, popType type) {
        /**        Explain : 当高频率点击返回的时候,由于过渡动画的原因会导致程序Crash,所以需要设定,
         *                   在过渡动画展示的过程中,则不允许继续popFragment
         * @author LiXaing create at 2017/8/17 0:07*/
        long currentTime = Calendar.getInstance().getTimeInMillis();
        /**        Explain : 动画时间为300,MIN_CLICK_DELAY_TIME为400,是为了动画完全结束后再允许下一次的pop
         * @author LiXaing create at 2017/8/17 0:09*/
        if (currentTime - lastKeyDownTime < MIN_CLICK_DELAY_TIME) {
            return;
        }
        lastKeyDownTime = currentTime;
        if (!baseFragment.onBackPressed()) {
            LogSwitchUtils.Log("switchPopBackStack", "内部方法");
            if (!isHaveFlage) {
                baseFragment.getFragmentManager().popBackStack();
            } else {
                if (type.equals(popType.INCLUDING_YOURSELF)) {
                    LogSwitchUtils.Log("switchPopBackStack", "INCLUDING_YOURSELF");
                    baseFragment.getFragmentManager().popBackStack(nameTag, FragmentManager.POP_BACK_STACK_INCLUSIVE);
                } else {
                    baseFragment.getFragmentManager().popBackStack(nameTag, 0);
                }
            }
        }
    }



}
AddFragmentBean


import android.os.Bundle;
import android.support.v4.app.Fragment;

import com.icarzoo.R;

/**
 * Created by lixiang on 2017/4/30.
 */
public abstract class AddFragmentBean {
    /**@author LiXiang create at 2018/1/31 17:19*/
    /**Explain : FrameID : 当Fragment展示的界面的ID
     */


    public  int FrameID = R.id.realcontent;

    /**@author LiXiang create at 2018/1/31 17:19*/
    /**Explain : fragment:当前需要展示的fragment
     */
    public Fragment fragment;

    /**@author LiXiang create at 2018/1/31 17:19*/
    /**Explain : bundle:fragment跳转中需要传递数据用的bundle
     */
    public Bundle bundle = null;

    /**@author LiXiang create at 2018/1/31 17:18*/
    /**Explain : aliasName : 设置当前Fragement的aliasName,当不设置默认为null的时候,会默认为当前类的全路径名称
     */
    public String aliasName = null;

    /**@author LiXiang create at 2018/1/31 17:18*/
    /**Explain : addToBackStack : 是否添加到回退栈中,默认为true(添加)
     */
    public boolean addToBackStack = true;

    /**@author LiXiang create at 2018/1/31 17:16*/
    /**Explain : isChildFragment : 当前的fragment是否是属于在当前Fragemnt里展示,当是的时候需要设置为true,添加到childManager中
     */
    public boolean isChildFragment= false;


    /**@author LiXiang create at 2018/1/31 17:17*/
    /**Explain : isShow : 加载完成之后是否展示,默认为展示
     */
    public boolean isShow= true;

    /**@author LiXiang create at 2018/1/31 17:18*/
    /**Explain : LoadTtpe:在manager栈中的添加方式;有两种:add和replace;默认为add
     */
    public LoadTtpe loadTtpe = LoadTtpe.add;

    public enum LoadTtpe{
        add,
        replace;
    }



    public boolean isOpenAnimation= true;

    public boolean isOpenAnimation() {
        return isOpenAnimation;
    }

    public AddFragmentBean setOpenAnimation(boolean openAnimation) {
        isOpenAnimation = openAnimation;
        return this;
    }

    public boolean isShow() {
        return isShow;
    }

    public AddFragmentBean setShow(boolean show) {
        isShow = show;
        return this;
    }

    public boolean isChildFragment() {
        return isChildFragment;
    }

    public AddFragmentBean setChildFragment(boolean childFragment) {
        isChildFragment = childFragment;
        return this;
    }

    public LoadTtpe getLoadTtpe() {
        return loadTtpe;
    }

    public AddFragmentBean setLoadTtpe(LoadTtpe loadTtpe) {
        this.loadTtpe = loadTtpe;
        return this;
    }

    public boolean isAddToBackStack() {
        return addToBackStack;
    }

    public AddFragmentBean setAddToBackStack(boolean addToBackStack) {
        this.addToBackStack = addToBackStack;
        return this;
    }

    public int getFrameID() {
        return FrameID;
    }

    public AddFragmentBean setFrameID(int frameID) {
        FrameID = frameID;
        return this;
    }

    public Fragment getFragment() {
        return fragment;
    }

    public AddFragmentBean setFragment(Fragment fragment) {
        this.fragment = fragment;
        return this;
    }

    public Bundle getBundle() {
        return bundle;
    }

    public AddFragmentBean setBundle(Bundle bundle) {
        this.bundle = bundle;
        return this;
    }

    public String getAliasName() {
        return aliasName;
    }

    public AddFragmentBean setAliasName(String aliasName) {
        this.aliasName = aliasName;
        return this;
    }

    public void commit(){
        AddFragmentListener();
    }


    public abstract  void AddFragmentListener();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值