让android应用实现只有一个activity的fragmentOnlySupportActivity

来源:互联网 发布:4621三星网络打印设置 编辑:程序博客网 时间:2024/06/07 18:19

自从fragment出现以来,很多app都开始使用fragment做界面,由于fragment的生命周期比activity丰富,如果管理不好fragment,就是增加开发难度,如果对fragment的生命周期管理到位就会事半功倍,按我的理解,fragment的生命周期其实就是activity生命周期的加强版,很多生命周期的方法和activity生命周期的方法是一个效果的,如果你的应用design不是android的那种design,很多都是自定义的,那么你可以尝试使用只有一个activity的编码(其实一般来说,在普通的开发中并没有什么卵用,但如果你使用插件技术吧fragment做出插件,界面跳转无需什么,可以增加删除,那意义就重大了)。

如何管理fragment的回退栈

一般的,你会想到使用popbackstack,其实popbackstack只是fragment的事务回退操作,注意了是事务,fragment的事务回退包括了fragment状态的回退,事务处理在处理自定义的复杂fragment跳转就会变得很繁琐,甚至不明白会应为不明白他的原理而研究他的源码!

在这里,我用的方法是hide,show,remove等方法对fragment经常自定义的管理。

假设你要启动一个fragment,那么将它实例化后add进来,add之前要对所有的fragment都做hide处理,不然底部会出现上一个fragment的背景,甚至能够点击。

假如你按了返回键,回到上一个fragment,那么从fragmentManger里面获取fragmentList(请勿对它操作,不然会出问题),注意了,这个fragmentList的顺序不一定跟你add的顺序一致,而且部分fragment销毁掉的,在这个list里面会空,对于没有顺序的fragmentList,我们需要对fragment设置Tag标记fragment是第几个add进去的,按返回键的时候,枚举一次fragmentList,按照tag,取到上一个界面的fragment,然后remove当前fragment,show出上一个fragment。

如何像activity那样finish掉指定界面?

如果你拿到他的实例,直接remove掉,如果你只有fragment的Class,那么枚举fragmentList,判断className相同后删除。

如果给fragment添加载入退出动画

抛开fragment动画,你一定会知道app中不一定全部activity载入动画是相同的,那么这个一个让fragmentOnlySupport一定也要能知道不同fragment对应不同的动画,此时,如何给fragment设置对应的动画?还是给fragment设置Tag,上面讲到fragment设置加载的index,那么index和动画一起加起来,可以用json作为字符串,把index和对应的动画都绑定在一起。

博客出处

创建实体与之对应:

public class FragmentTagVo {    public FragmentTagVo(){};    public FragmentTagVo(int index, String animType) {        this.index = index;        this.animType = animType;    }    public String animType;    public int index;    public static FragmentTagVo build(String json) {        FragmentTagVo tagVo = new FragmentTagVo();        try {            JSONObject jsonObject = new JSONObject(json);            tagVo.index = jsonObject.getInt("index");            tagVo.animType = jsonObject.getString("animType");        } catch (Exception e) {            e.printStackTrace();        }        return tagVo;    }    @Override    public String toString() {        JSONObject jsonObject = new JSONObject();        try {            jsonObject.put("index",index);            jsonObject.put("animType",animType);        } catch (Exception e) {            e.printStackTrace();        }        return jsonObject.toString();    }}

在加载fragment的时候设置tag:

            fragmentIndex++;                FragmentTagVo tagVo = new FragmentTagVo(fragmentIndex,animType==null?AnimType.NONE.toString():animType.toString());                try {                    mFragmentTransaction.add(containerId, tagfragment, tagVo.toString());                } catch (Exception e) {                    e.printStackTrace();                }                mFragmentTransaction.show(tagfragment);                mFragmentTransaction.commitAllowingStateLoss();                KeyboradUtil.hideSoftKeyboard(this);

返回时找到上一个fragment的方法:

                PLog.i("list:" + fragmentlist);                for (int i = fragmentlist.size()-1; i >= 0 ; i--) {                    Fragment fragment = fragmentlist.get(i);                    if (!(fragment == null || !fragment.isVisible())) {//可视且不是没有设置view的fragment                        //这里可以写应用自己的返回逻辑                        //                        Fragment backFragment = null;                        PLog.d("tag:" + fragment.getTag());                        FragmentTagVo tagVo = JSONObject.parseObject(fragment.getTag(),FragmentTagVo.class);                        int fragIndex = tagVo.index-1;                        Looper:                        while (fragIndex >= 0) {//从list后面开始找,高效查找方法                        FindByTag:                            for (AnimType animType:AnimType.values()) {                                tagVo = new FragmentTagVo(fragIndex,animType.toString());                                backFragment = fragmentManager.findFragmentByTag(JSONObject.toJSONString(tagVo));                                if (backFragment!=null) {                                    break FindByTag;                                }                            }                            PLog.d("backFragment:" + backFragment);                            if (backFragment != null) {                                PLog.d("backFragment add?:" + backFragment.isAdded());                                PLog.d("backFragment removing?:" + backFragment.isRemoving());                            }                            if (backFragment == null || !backFragment.isAdded() || backFragment.isRemoving()) {                                --fragIndex;                            } else {                                break Looper;                            }                        }                        PLog.d("currFragment:" + fragment.getClass().getSimpleName());                        PLog.d("backFragment:" + backFragment);                    }                }

处理完动画绑定在fragment的逻辑,开始往fragment添加动画。

先声明一个动画枚举类,包括以下动画:

public enum AnimType {    NONE,//没有动画    LeftInRightOut,//左进右出    BottomInTopOut,//上进,往下出    ZoomShow//fragment默认缩放    ;    public static int[] getAnimRes (AnimType animType){        switch (animType) {            case LeftInRightOut:                return new int[]{R.anim.push_left_in,R.anim.push_left_out,R.anim.back_left_in, R.anim.back_right_out};            case BottomInTopOut:                return new int[]{R.anim.push_bottom_in,R.anim.push_top_out,R.anim.push_bottom_in,R.anim.push_top_out};            default:                return new int[]{0,0,0,0};        }    }}

add之前添加动画:

public void loadFragment(Fragment tagfragment, FragmentTransaction mFragmentTransaction,@NonNull AnimType animType) {                if (mFragmentTransaction == null) {                    mFragmentTransaction = getSupportFragmentManager().beginTransaction();                }                //動畫                if (animType==AnimType.ZoomShow) {                    mFragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);                } else if (animType== AnimType.LeftInRightOut) {                    mFragmentTransaction.setCustomAnimations(R.anim.push_left_in, R.anim.push_left_out,R.anim.back_left_in,R.anim.back_right_out);                } else if (animType== AnimType.BottomInTopOut) {                    mFragmentTransaction.setCustomAnimations(R.anim.push_bottom_in,R.anim.push_top_out,R.anim.push_bottom_in,R.anim.push_top_out);                } else {                    //NONE                }     }

退出时设置对于退出动画:

public void backPressed () {......code for find back Fragmentif (backFragment != null) {                            tagVo = JSONObject.parseObject(fragment.getTag(),FragmentTagVo.class);                            AnimType exitAnim = null;                            if(tagVo!=null)                                for (AnimType animType:AnimType.values()) {                                    if (animType.toString().equals(tagVo.animType.toString())) {                                        exitAnim = animType;                                    }                                }                            final Fragment animShowFragment = backFragment;                            final Fragment animHideFragment = fragment;                            if (exitAnim==null || exitAnim==AnimType.NONE) {                                FragmentTransaction mFragmentTransaction = getSupportFragmentManager().beginTransaction();                                mFragmentTransaction.show(animShowFragment);                                mFragmentTransaction.remove(animHideFragment);                                mFragmentTransaction.commitAllowingStateLoss();                            } else if (exitAnim==AnimType.ZoomShow) {                                FragmentTransaction mFragmentTransaction = getSupportFragmentManager().beginTransaction();                                mFragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE);                                mFragmentTransaction.show(animShowFragment);                                mFragmentTransaction.remove(animHideFragment);                                mFragmentTransaction.commitAllowingStateLoss();                            } else {                                int[] animRes = AnimType.getAnimRes(exitAnim);                                Animation animation = AnimationUtils.loadAnimation(getApplicationContext(), animRes[3]);                                animation.setAnimationListener(new Animation.AnimationListener() {                                    @Override                                    public void onAnimationStart(Animation animation) {                                    }                                    @Override                                    public void onAnimationEnd(Animation animation) {                                        FragmentTransaction mFragmentTransaction = getSupportFragmentManager().beginTransaction();                                        mFragmentTransaction.show(animShowFragment);                                        mFragmentTransaction.remove(animHideFragment);                                        mFragmentTransaction.commitAllowingStateLoss();                                        fragmentChangeing = false;                                    }                                    @Override                                    public void onAnimationRepeat(Animation animation) {                                    }                                });                                fragment.getView().startAnimation(animation);                                backFragment.getView().setAnimation(AnimationUtils.loadAnimation(getApplicationContext(), animRes[2]));                            }                        } else {                            finish();                        }                    }//end if (!(fragment == null || !fragment.isVisible())) {//可视的    .......code for do other}

如果让fragment拦截返回事件,或实现带条件的返回?

重写activity的onBackPressed返回方法,加入以下代码,让fragment调用就Ok了:

 public void setCanBackPress(boolean can) {        this.mCanBackPress = can;    }    protected boolean mCanBackPress = true;    protected OnBackPressedListener onBackPressedListener;    public void setOnBackPressedListener(OnBackPressedListener listener) {        this.onBackPressedListener = listener;    }    @Override    public void onBackPressed() {        if (onBackPressedListener != null) {            onBackPressedListener.OnBackKeyDown();            return;        }        if (!mCanBackPress) {            return;        }        backPressed();//该方法用于返回上一个fragment,如果没上一个界面了,最终执行finish    }

如果打通这些fragments通信通道?实现像activity的onActivityResult方法一样

类似于广播者模式,每个fragment都可以是观察者和被观察者,用onActivityResult充当Observer接口,用枚举fragmentList的Fragment调用onActivityResult方法充当被观察者。有以下代码:

博客出处

public void pushMsgToSubFragments (boolean needShow,int pushCode,Intent pushData) {        pushMsgToSubFragments(getSupportFragmentManager(), needShow,pushCode, Activity.RESULT_OK, pushData);    }    public void pushMsgToSubFragments (@NonNull FragmentManager fragmentManager,boolean needShow,int requestCode,int resultCode, Intent data) {        List<Fragment> fragmentlist =  fragmentManager.getFragments();        if (fragmentlist!=null)            for (Fragment fragment:fragmentlist) {                if (fragment==null) {                    continue;                }                if (fragment.isAdded()) {                    if (needShow) {                        if (!fragment.isHidden()) {                            PLog.i("send to:" + fragment);                            fragment.onActivityResult(requestCode, resultCode, data);                        }                    } else {                        PLog.i("send to:" + fragment);                        fragment.onActivityResult(requestCode, resultCode, data);                    }                    //如果fragment里面还嵌套了fragment,继续观察                    pushMsgToSubFragments(fragment.getChildFragmentManager(),needShow,requestCode,resultCode,data);                }            }    }    //Fragment里面重写onActivityResult接送观察类型和数据

如果activity调用其他activity,返回数据,继续重新onactivityresult方法:

@Override    public void onActivityResult(int requestCode, int resultCode, Intent data) {        PLog.i("onActivityResult:" + requestCode);        try {            super.onActivityResult(requestCode, resultCode, data);        } catch (Exception e) {            e.printStackTrace();        }        pushMsgToSubFragments(getSupportFragmentManager(), false, requestCode, resultCode, data);    }

最后献上完整代码:

import android.app.Activity;import android.content.Intent;import android.os.Build;import android.support.annotation.NonNull;import android.support.annotation.Nullable;import android.support.v4.app.Fragment;import android.support.v4.app.FragmentManager;import android.support.v4.app.FragmentTransaction;import android.util.Log;import android.view.animation.Animation;import android.view.animation.AnimationUtils;import java.util.ArrayList;import java.util.List;/** * Created by george.yang on 15/11/18. */public abstract class FragmentOnlySupportActivity extends PlugBaseActivity {    public abstract int getContainerId();    private int containerId = getContainerId();    public static boolean fragmentChangeing = false;    public <T extends Fragment> T getFragment(@Nullable FragmentManager manager, Class clazz) {        return getFragment(manager, false, clazz);    }    public <T extends Fragment> T getFragment(@Nullable FragmentManager manager, boolean showing, Class clazz) {        if (clazz == null) {            return null;        }        if (manager == null) {            manager = getSupportFragmentManager();        }        List<Fragment> fragmentlist = manager.getFragments();        if (fragmentlist != null) {            for (Fragment fragment : fragmentlist) {                if (fragment == null || fragment.isRemoving() || !fragment.isAdded() || (showing && fragment.isHidden())) {                    continue;                }                if (clazz.getName().equals(fragment.getClass().getName())) {                    return (T) fragment;                } else {                    Fragment fragmentInner = getFragment(fragment.getChildFragmentManager(), showing, clazz);                    if (fragmentInner != null) {                        return (T) fragmentInner;                    }                }            }        }        return null;    }    public void loadFragment(Fragment tagfragment, FragmentTransaction mFragmentTransaction) {        loadFragment(tagfragment,mFragmentTransaction, AnimType.LeftInRightOut);    }    public void loadFragment(Fragment tagfragment) {        loadFragment(tagfragment,AnimType.LeftInRightOut);    }    public void loadFragment(String fragmenName) {        try {            loadFragment((Class<? extends Fragment>) Class.forName(fragmenName));        } catch (Exception e) {            e.printStackTrace();        }    }    public void loadFragment(Class<? extends Fragment> fragmentClass) {        try {            loadFragment((Fragment) fragmentClass.newInstance());        } catch (Exception e) {            e.printStackTrace();        }    }    public void loadFragment(Fragment tagfragment,@NonNull AnimType animType) {        loadFragment(tagfragment, null, animType);    }    private int fragmentIndex;    public void loadFragment(Fragment tagfragment, FragmentTransaction mFragmentTransaction,@NonNull AnimType animType) {        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {            if (isDestroyed()) {                return;            }        }        if (isFinishing()) {            return;        }        PLog.i("load:" + tagfragment);        if (!fragmentChangeing) {            fragmentChangeing = true;            if (tagfragment!=null) {                if (mFragmentTransaction == null) {                    mFragmentTransaction = getSupportFragmentManager().beginTransaction();                }                //動畫                if (animType==AnimType.ZoomShow) {                    mFragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);                } else if (animType== AnimType.LeftInRightOut) {                    mFragmentTransaction.setCustomAnimations(R.anim.push_left_in, R.anim.push_left_out,R.anim.back_left_in,R.anim.back_right_out);                } else if (animType== AnimType.BottomInTopOut) {                    mFragmentTransaction.setCustomAnimations(R.anim.push_bottom_in,R.anim.push_top_out,R.anim.push_bottom_in,R.anim.push_top_out);                } else {                    //NONE                }                List<Fragment> fragmentlist = getSupportFragmentManager().getFragments();                if (fragmentlist != null)                    for (int i = 0; i < fragmentlist.size(); i++) {                        Fragment fragment = fragmentlist.get(i);                        if (fragment != null) {                            mFragmentTransaction.hide(fragment);                        }                    }                fragmentIndex++;                FragmentTagVo tagVo = new FragmentTagVo(fragmentIndex,animType==null?AnimType.NONE.toString():animType.toString());                try {                    mFragmentTransaction.add(containerId, tagfragment, JSONObject.toJSONString(tagVo));                } catch (Exception e) {                    e.printStackTrace();                }                mFragmentTransaction.show(tagfragment);                mFragmentTransaction.commitAllowingStateLoss();                KeyboradUtil.hideSoftKeyboard(this);            }            fragmentChangeing = false;        }    }    public void pushMsgToSubFragments (boolean needShow,int pushCode,Intent pushData) {        pushMsgToSubFragments(getSupportFragmentManager(), needShow,pushCode, Activity.RESULT_OK, pushData);    }    public void pushMsgToSubFragments (@NonNull FragmentManager fragmentManager,boolean needShow,int requestCode,int resultCode, Intent data) {        List<Fragment> fragmentlist =  fragmentManager.getFragments();        if (fragmentlist!=null)            for (Fragment fragment:fragmentlist) {                if (fragment==null) {                    continue;                }                if (fragment.isAdded()) {                    if (needShow) {                        if (!fragment.isHidden()) {                            PLog.i("send to:" + fragment);                            fragment.onActivityResult(requestCode, resultCode, data);                        }                    } else {                        PLog.i("send to:" + fragment);                        fragment.onActivityResult(requestCode, resultCode, data);                    }                    pushMsgToSubFragments(fragment.getChildFragmentManager(),needShow,requestCode,resultCode,data);                }            }    }    @Override    public void onActivityResult(int requestCode, int resultCode, Intent data) {        PLog.i("onActivityResult0:" + requestCode);        try {            super.onActivityResult(requestCode, resultCode, data);        } catch (Exception e) {            e.printStackTrace();        }        pushMsgToSubFragments(getSupportFragmentManager(), false, requestCode, resultCode, data);    }    final List<Fragment> removeFragment = new ArrayList<>();    public boolean removeFragment(Class clazz) {        if (clazz == null) {            return false;        }        synchronized (removeFragment) {            List<Fragment> fragmentlist = getSupportFragmentManager().getFragments();            if (fragmentlist != null) {                for (Fragment fragment : fragmentlist) {                    if (fragment == null) {                        continue;                    }                    if (clazz.getName().equals(fragment.getClass().getName())) {                        PLog.i("remove:" + clazz.getName());                        removeFragment.add(fragment);                    }                }                FragmentTransaction ft = getSupportFragmentManager().beginTransaction();                for (Fragment fragment : removeFragment) {                    ft.remove(fragment);                }                ft.commitAllowingStateLoss();                removeFragment.clear();            }            //                }        }        return true;    }    public void setCanBackPress(boolean can) {        this.mCanBackPress = can;    }    protected boolean mCanBackPress = true;    protected OnBackPressedListener onBackPressedListener;    public void setOnBackPressedListener(OnBackPressedListener listener) {        this.onBackPressedListener = listener;    }    @Override    public void onBackPressed() {        if (onBackPressedListener != null) {            onBackPressedListener.OnBackKeyDown();            return;        }        if (!mCanBackPress) {            return;        }        backPressed();    }    //[博客出处](http://georgeyang.cn)    public void backPressed () {        boolean waitAnimEndUnLock = false;        if (!fragmentChangeing) {            fragmentChangeing = true;            try {                FragmentManager fragmentManager = getSupportFragmentManager();                fragmentManager.executePendingTransactions();//同步结束                List<Fragment> fragmentlist = fragmentManager.getFragments();                if (fragmentlist==null) {                    finish();                }                PLog.i("list:" + fragmentlist);                for (int i = fragmentlist.size()-1; i >= 0 ; i--) {                    Fragment fragment = fragmentlist.get(i);                    if (!(fragment == null || !fragment.isVisible())) {//可视且不是没有设置view的fragment                        //这里可以写应用自己的返回逻辑                        //                        Fragment backFragment = null;                        PLog.d("tag:" + fragment.getTag());                        FragmentTagVo tagVo = JSONObject.parseObject(fragment.getTag(),FragmentTagVo.class);                        int fragIndex = tagVo.index-1;                        Looper:                        while (fragIndex >= 0) {                        FindByTag:                            for (AnimType animType:AnimType.values()) {                                tagVo = new FragmentTagVo(fragIndex,animType.toString());                                backFragment = fragmentManager.findFragmentByTag(JSONObject.toJSONString(tagVo));                                if (backFragment!=null) {                                    break FindByTag;                                }                            }                            PLog.d("backFragment:" + backFragment);                            if (backFragment != null) {                                PLog.d("backFragment add?:" + backFragment.isAdded());                                PLog.d("backFragment removing?:" + backFragment.isRemoving());                            }                            if (backFragment == null || !backFragment.isAdded() || backFragment.isRemoving()) {                                --fragIndex;                            } else {                                break Looper;                            }                        }                        PLog.d("currFragment:" + fragment.getClass().getSimpleName());                        PLog.d("backFragment:" + backFragment);                        if (backFragment != null) {                            tagVo = JSONObject.parseObject(fragment.getTag(),FragmentTagVo.class);                            AnimType exitAnim = null;                            if(tagVo!=null)                                for (AnimType animType:AnimType.values()) {                                    if (animType.toString().equals(tagVo.animType.toString())) {                                        exitAnim = animType;                                    }                                }                            final Fragment animShowFragment = backFragment;                            final Fragment animHideFragment = fragment;                            if (exitAnim==null || exitAnim==AnimType.NONE) {                                FragmentTransaction mFragmentTransaction = getSupportFragmentManager().beginTransaction();                                mFragmentTransaction.show(animShowFragment);                                mFragmentTransaction.remove(animHideFragment);                                mFragmentTransaction.commitAllowingStateLoss();                            } else if (exitAnim==AnimType.ZoomShow) {                                FragmentTransaction mFragmentTransaction = getSupportFragmentManager().beginTransaction();                                mFragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE);                                mFragmentTransaction.show(animShowFragment);                                mFragmentTransaction.remove(animHideFragment);                                mFragmentTransaction.commitAllowingStateLoss();                            } else {                                int[] animRes = AnimType.getAnimRes(exitAnim);                                Animation animation = AnimationUtils.loadAnimation(getApplicationContext(), animRes[3]);                                animation.setAnimationListener(new Animation.AnimationListener() {                                    @Override                                    public void onAnimationStart(Animation animation) {                                    }                                    @Override                                    public void onAnimationEnd(Animation animation) {                                        FragmentTransaction mFragmentTransaction = getSupportFragmentManager().beginTransaction();                                        mFragmentTransaction.show(animShowFragment);                                        mFragmentTransaction.remove(animHideFragment);                                        mFragmentTransaction.commitAllowingStateLoss();                                        fragmentChangeing = false;                                    }                                    @Override                                    public void onAnimationRepeat(Animation animation) {                                    }                                });                                fragment.getView().startAnimation(animation);                                backFragment.getView().setAnimation(AnimationUtils.loadAnimation(getApplicationContext(), animRes[2]));                            }                        } else {                            finish();                        }                    }//end if (!(fragment == null || !fragment.isVisible())) {//可视的                }            } catch (Exception e) {                e.printStackTrace();            }            KeyboradUtil.hideSoftKeyboard(this);            if (!waitAnimEndUnLock) {                PLog.i("unlock:338");                fragmentChangeing = false;            }        }    }}
0 0
原创粉丝点击