一个简单管理并切换fragment的导航器

在项目中经常遇到一个activity+多个fragment组合,这就要考虑fragmeng之间的切换了,如下示例是用于应用初始化时把fragmeng建好,并管理的一个Navigator。

一、新建父级Navigator抽象类

/**
 * author : CrazyDong
 * description :用于切换fragment的导航器,布局分为左、右两部分fragment
 */
public abstract class AbstractEnergyFragmentNavigator {
    private static final String TAG = "AbstractEnergyFragmentNavigator";
    public static final byte SHOW_IN_LEFT_SIDE = 1;//左边fragment标志
    public static final byte SHOW_IN_RIGHT_SIDE = 2;//右边fragment标志
    public static final int SIDE_EMPTY = -1;//布局空显示ID
    private FragmentManager _fragmentManager;
    private BaseFragment mLeftPreviousFragment;//当前左边的fragment
    private BaseFragment mRightPreviousFragment;//当前右边的fragment
    private int mLeftViewId; //显示左侧Fragment使用的FrameLayout的ID
    private int mRightViewId; //显示右侧Fragment使用的FrameLayout的ID
    private Map<Integer, BaseFragment> _frmStorage = new HashMap();//总的fragment容器
    private Map<Integer, BaseFragment> mLeftAddedFragments = new HashMap();//左边fragment容器
    private Map<Integer, BaseFragment> mRightAddedFragments = new HashMap();//右边fragment容器
    protected OnFragmentChangeListener mOnFragmentChangeListener;//切换fragment时的监听
    private List<Integer> _plugIn;//所有所要建立的fragment的key集合

    //初始化的方法
    public void initialize(final FragmentManager fragmentManager, final int leftViewId, final int rightViewId) {
        _fragmentManager = fragmentManager;
        mLeftViewId = leftViewId;
        mRightViewId = rightViewId;
    }

    //释放对象,防止OOM
    public void finalized() {
        mLeftPreviousFragment = null;
        mRightPreviousFragment = null;
        mRightAddedFragments.clear();
        mLeftAddedFragments.clear();
        _frmStorage.clear();
    }

    //将Fragment放入总的容器
    public void insertView(final int key, final BaseFragment view) {
        _frmStorage.put(key, view);
    }

    /**
     * commit()方法并不立即执行transaction中包含的动作,而是把它加入到UI线程队列中.
     * 如果想要立即执行,可以在commit之后立即调用FragmentManager的executePendingTransactions()方法.
     */
    protected void insertViewFinish() {
        _fragmentManager.executePendingTransactions();
    }

    /**
     * 默认将Fragment显示在左侧画页中
     *
     * @param key
     */
    public void gotoView(final int key) {
        gotoView(key, SHOW_IN_LEFT_SIDE);
    }

    /**
     * 页面跳转方法
     * @param key  页面ID
     * @param side 显示在哪一边
     */
    public void gotoView(final int key, final byte side) {
        LogTool.d(TAG, "gotoView() Fragment add to which side :" + side);
        if (SHOW_IN_LEFT_SIDE == side) {
            gotoLeftView(key);
        } else {
            gotoRightView(key);
        }
        if (mOnFragmentChangeListener != null) {
            mOnFragmentChangeListener.onFragmentChange(key, side);
            LogTool.d(TAG, "pageId is " + key);
        } else {
            LogTool.d(TAG, "pageId is " + key + " mOnFragmentChangeListener is null.");
        }
    }

    private synchronized void gotoRightView(final int key) {
        LogTool.d(TAG, "AbstractFragmentNavigator has showed --right key=>" + key);
        FragmentTransaction transaction = _fragmentManager.beginTransaction();
        if (SIDE_EMPTY == key && mRightPreviousFragment != null) {
            transaction.hide(mRightPreviousFragment);
            transaction.commitAllowingStateLoss();
            mRightPreviousFragment = null;
        }
        BaseFragment fragment = _frmStorage.get(key);
        if (null == fragment)//容器中没有此fragmeng
            return;
        if (fragment == mRightPreviousFragment)//当前fragmeng等于想要跳转的fragmeng
            return;
        if (null != mRightPreviousFragment)
            transaction.hide(mRightPreviousFragment);
        if (mRightAddedFragments.containsKey(key)) {
            transaction.show(fragment);
            LogTool.d(TAG, "%d gotoRightView() fragment has show---", key);
            LogTool.d(TAG, "%s gotoRightView() show fragment name---", fragment.toString());
        } else {
            transaction.add(mRightViewId, fragment);
            mRightAddedFragments.put(key, fragment);//TODO 需要做side的检测,是否是有效值
        }
        transaction.commitAllowingStateLoss();
        mRightPreviousFragment = fragment;
    }


    private synchronized void gotoLeftView(final int key) {
        LogTool.d(TAG, "AbstractFragmentNavigator has showed --left => " + key);
        BaseFragment fragment = _frmStorage.get(key);
        if (null == fragment) {
            LogTool.d(TAG, "gotoLeftView() fragment is null return. key=> " + key);
            return;
        }
        if (fragment == mLeftPreviousFragment) {
            LogTool.d(TAG, "gotoLeftView() key fragment == mLeftPreviousFragment return. key=> " + key);
            return;
        }
        FragmentTransaction transaction = _fragmentManager.beginTransaction();
        if (null != mLeftPreviousFragment) {
            transaction.hide(mLeftPreviousFragment);
            LogTool.d(TAG, "gotoLeftView() key hide mLeftPreviousFragment. key=>");
        }
        if (mLeftAddedFragments.containsKey(key)) {
            transaction.show(fragment);
            LogTool.d(TAG, "%d fragment has show---", key);
            LogTool.d(TAG, "%s show fragment name---", fragment.toString());
        } else {
            LogTool.d(TAG, "gotoLeftView() add key=> " + key);
            transaction.add(mLeftViewId, fragment);
            mLeftAddedFragments.put(key, fragment);//TODO 需要做side的检测,是否是有效值
        }
        transaction.commitAllowingStateLoss();
        mLeftPreviousFragment = fragment;
    }

    //添加key的方法
    protected abstract List<Integer> buildPlugIn();

    protected abstract BaseFragment createFragment(final int frmId, final AbstractEnergyFragmentNavigator navigator);

    public void buildFragment() {
        _plugIn = buildPlugIn();
        for (int id : _plugIn) {
            BaseFragment baseFragment = createFragment(id, this);
            int idd = id;
            LogTool.d(TAG, "baseFragment " + baseFragment + " idd " + idd);
            insertView(idd, baseFragment);
        }
        insertViewFinish();
    }

    /**
     * 返回上级菜单
     */
    public void goBack() {
        if (mLeftPreviousFragment != null) {
            mLeftPreviousFragment.onBackEvent();
        }
    }

    public interface OnFragmentChangeListener {
        void onFragmentChange(int pageId, int whichSide);
    }

    public void registerOnFragmentChangeListener(OnFragmentChangeListener listener) {
        mOnFragmentChangeListener = listener;
    }
    

}

二、新建一个MyActivityNavigator继承AbstractEnergyFragmentNavigator

public class MyActivityNavigatorextends AbstractEnergyFragmentNavigator{
    public static final String TAG = "MyActivityNavigator";
    private Context mContext;
    public void init(Context context, final FragmentManager fragmentManager, final int leftViewId, final int rightViewId) {
        LogTool.d_end(TAG, "init()");
        super.initialize(fragmentManager, leftViewId, rightViewId);
        mContext = context;
        buildFragment();
    }

    public void finalized() {
        super.finalized();
    }
    @Override
    protected List<Integer> buildPlugIn() {
        final List<Integer> plugIns = new ArrayList<>();
        plugIns.add(Variables.aa);//Variables.aa是key值
        plugIns.add(Variables.bb);
        return plugIns;
    }

    @Override
    protected BaseFragment createFragment(int frmId, AbstractEnergyFragmentNavigator navigator) {
        switch (frmId){
            case Variables.aa://根据key值new 索要使用的fragmeng
                Afragment afragment = new Afragment();
                return afragment ;
            case Variables.bb:
                BFragment bFragment = new BFragment ();
                return bFragment ;
            default:
                return null;
        }
    }
}

 所用到的常量可以放到一个常量类中,如下:

/**
 * author : CrazyDong
 * description :用于存储常量
 */
public class Variables {
    public static final int aa = 100;
    public static final int bb= 200;

}

三、在MainActivity中使用

public class MainActivity extends Activity implements View.OnClickListener {
    public static final String TAG = "EnergyMainActivity";
    public static int cMenuLeft = -1;
    public static int cMenuRight = -1;
    private EnergyMainActivityNavigator _navigator;
    public Button btn_test;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        savedInstanceState = null;
        super.onCreate(savedInstanceState);
        LogTool.d(TAG, "onCreate start");
        setContentView(R.layout.new_energy_main);
        VehicleBean.getInstance().initCallBack();
        buildFragment();
        btn_test = (Button) findViewById(R.id.btn_test);
        btn_test.setOnClickListener(this);
        _navigator.gotoView(Variables.aa);//左边跳转AFragment
        _navigator.gotoView(Variables.bb,SHOW_IN_RIGHT_SIDE);//右边跳转BFragment
        LogTool.d(TAG, "onCreate end");

    }



    public void buildFragment() {
        _navigator = new EnergyMainActivityNavigator();
        _navigator.init(getApplicationContext(), getFragmentManager(), R.id.fragment_left_energy, R.id.fragment_right);
        _navigator.registerOnFragmentChangeListener(new EnergyOnFragmentChangeListener());
    }

    class EnergyOnFragmentChangeListener implements AbstractEnergyFragmentNavigator.OnFragmentChangeListener {
        @Override
        public void onFragmentChange(int pageId, int whichSide) {
            //监听fragmeng改变时的接口
            int type = pageId / 100;
            switch (type) {
                case 1:

                    break;
                default:
                    LogTool.d(TAG, "onFragmentChange() invalid value : " + pageId);
                    break;
            }

        }
    }

    @Override
    public void onClick(View view) {
        LogTool.d(TAG, "onClick() text=>" + ((RadioButton) view).getText());
        switch (view.getId()) {
            case R.id.btn_test:
                _navigator.gotoView(Variables.aa);
                _navigator.gotoView(Variables.bb,SHOW_IN_RIGHT_SIDE);
                break;
            default:
                break;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //回收一下资源,防止内存泄漏而OOM
        _navigator.finalized();
        _navigator = null;
    }


    @Override
    public void onBackPressed() {
        _navigator.goBack();
    }

}

layout布局文件如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/main_root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/common_background"
    android:fitsSystemWindows="true"
    android:orientation="horizontal">

    <Button
        android:id="@+id/btn_test"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <FrameLayout
            android:id="@+id/fragment_left_energy"
            android:layout_width="@dimen/dimen780dp"
            android:layout_height="match_parent"/>

        <FrameLayout
            android:id="@+id/fragment_right"
            android:layout_width="@dimen/dimen980dp"
            android:layout_height="match_parent"
            android:layout_toEndOf="@id/fragment_left_energy"/>

    </RelativeLayout>
</LinearLayout>

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值