只需要在manifest.xml中配置两个activity标签就可以显示所有界面

最近又要开始找工作了,准备把私藏了四年…的库分享给大家,别问我为啥现在才分享,因为鄙人比较懒(自己偷笑了一下)但是哥们在生活中是个很勤快的人。其实对于程序猿来说懒也是一种优点,但是必备的条件是要面子,两者缺一不可。为啥呢因为懒人都不喜欢重复性的复制与粘贴,所以会去抽取公共的代码,慢慢形成框架。另外为啥还需要要面子呢?因为要面子的人交付给别人的代码一定会自检查许多遍, 交出去的东西一定是当时他能做到的最好的。好了开始了…

要使用本库只需要复制ReusingActivityHelper.java ReusingActivity.java 代码,在manifest.xml配置

   <!--用来展示界面内容的activity,因为我们要复用,所以不能配置启动模式-->
        <activity android:name="com.reusing.lib.ReusingActivity"/>

此库从2015年就开始使用,已经在7个项目使用,稳定性能够保证,而其此库代码逻辑并不难,很容易理解

代码下载地址:还没来得及更新到github上,等更新了 通知大家

链接:https://pan.baidu.com/s/1oIWisHCGOHbp_ojfXW0-4g
提取码:3srn

真的开始了~~~~~~

如果app有三个界面之前我们大概会这样做吧

  1. 创建三个activity
public class AActivity extends AppCompatActivity {   
     @Override    
     protected void onCreate(Bundle savedInstanceState) { 
         super.onCreate(savedInstanceState);                      							      
         setContentView(R.layout.activity_a);    
     }
}
public class BActivity extends AppCompatActivity {   
   ...
}
public class CActivity extends AppCompatActivity {   
   ...
}

2.创建三个布局文件
只需要在manifest.xml中配置两个activity标签就可以显示所有界面
3.在AndroidManifest.xml中配置这三个activity的标签
只需要在manifest.xml中配置两个activity标签就可以显示所有界面
上面这三个步骤是大家经常做的事,第三步是重复性最高,又非常重要让人很烦的东西,为什么呢,因为忘记配置第三步,那么恭喜你中奖了,而其android studio在编译的时候并不会告诉你忘记配置了。

接下来,我们把AndroidManifest.xml中CActivity的标签删除然后启动它:

   startActivity(new Intent(getApplication(), CActivity.class));

然后开奖了…
只需要在manifest.xml中配置两个activity标签就可以显示所有界面

android.content.ActivityNotFoundException: Unable to find explicit activity class {com.project.reusingactivity/com.project.reusingactivity.CActivity}; have you declared this activity in your AndroidManifest.xml?

如果大家是工作了三年以上的猴子,看到上面的错误都会楞一下,然后会心一笑吧…
接下来让我们只需要在manifest.xml配置一个activity来优化它。看到这里你估计心里在想吹牛…

我们先看看库效果

先坑你们一下,在老项目中使用需要把activity转成fragment。体力活…如上面的三个activity

public class AFragment extends Fragment {
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.activity_a, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        Bundle arguments = getArguments();
        if (arguments != null) {
            TextView tv = view.findViewById(R.id.tv_content);
            tv.setText(arguments.getString("content"));
        }
    }
}

然后
我们删除mainfest.xml中的A、B、C三个activity的标签,然后配置ReusingActivity 的标签,mainfest.xml内容大概像这样:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.project.reusingactivity">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <!--启动页-->
        <activity android:name=".SplashActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        
        <!--用来展示界面内容的activity,因为我们要复用,所以不能配置启动模式-->
        <activity android:name="com.reusing.lib.ReusingActivity"/>
    </application>
</manifest>

启动三个界面的代码

public class SplashActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

      findViewById(R.id.tv_to_a_activity).setOnClickListener(v -> {
            ReusingActivityHelper.IntentBuilder intentBuilder = ReusingActivityHelper.builder(this);
            if (intentBuilder == null) {
                return;
            }
            //设置SoftInputMode
            intentBuilder.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
            intentBuilder.setWindowFeature(Window.FEATURE_NO_TITLE);

            Bundle bundle = new Bundle();
            bundle.putString("content","从父界面传递过来的数据");
            super.startActivity(intentBuilder.setFragment(AFragment.class, bundle).build());

            //设置activity转场动画
            SplashActivity.this.overridePendingTransition(R.anim.activity_in, R.anim.activity_out);

        });

        findViewById(R.id.tv_to_b_activity).setOnClickListener(v -> {
            startFragment(BFragment.class);
        });

        findViewById(R.id.tv_to_c_activity).setOnClickListener(v -> {
            startFragment(CFragment.class);
        });
    }

    private void startFragment(Class<? extends  Fragment> fragmentClass) {
        ReusingActivityHelper.IntentBuilder intentBuilder = ReusingActivityHelper.builder(this);
       startActivity(intentBuilder.setFragment(fragmentClass,null).build());
    }
}
ok了,我们运行一下试试

只需要在manifest.xml中配置两个activity标签就可以显示所有界面
我们点击一下AActivity试试,ok跳转成功,界面显示成功
只需要在manifest.xml中配置两个activity标签就可以显示所有界面

我们先分析一下startFragment()方法

  private void startFragment(Class<? extends  Fragment> fragmentClass) {
       ReusingActivityHelper.IntentBuilder intentBuilder = ReusingActivityHelper.builder(this);
       startActivity(intentBuilder.setFragment(fragmentClass,null).build());
    }

我们先看一下startFragment()中调用的ReusingActivityHelper.builder(this) 方法

 public static IntentBuilder builder(Context context) {
        IntentBuilder b = new IntentBuilder();
        return b.create(context, ReusingActivity.class);
 }

上面方法创建了一个IntentBuilder,并调用了IntentBuilder 的create()方法

  public IntentBuilder create(Context context,Class<? extends Activity> clazz) {
            intent = new Intent(context, clazz);//clazz 就是上个方法传入的ReusingActivity.class
            args = new Bundle(); 
            extra = new Bundle();
            return this;
  }

是不是发现点了啥~~~~~在 create() 中,我们创建一个intent对象并设置了我们要启动的activity是ReusingActivity,另外还创建了两个bundle对象,其中所有配置信息都会存放在 args中,在build()中extra也会被放入args中。

接下来我们看一下库源码,源码就两个文件

ReusingActivityHelper.java

public class ReusingActivityHelper {
    private static final String SINGLE_FRAGMENT_ACTIVITY_START_ME_PARAM = "SINGLE_FRAGMENT_ACTIVITY_START_ME_PARAM";

    private static final String FRAGMENT_NAME = "fragment_name";

    private static final String FRAGMENT_TAG = "fragment_tag";
    /**
     * 指定上个页面传递的数据
     */
    private static final String FRAGMENT_ARGU = "fragment_argu";


    public static final String EXTRA = "extra";

    /**
     * 指定layout资源,为0或不传,使用DecorView 主题不同 内容不同
     */
    public static final String EXTRA_PARAM_LAYOUT = "layout";

    /**
     * 指定fragment的container id,不传,使用android.R.id.content
     */
    public static final String EXTRA_PARAM_CONTAINER = "container";

    /**
     * 指定activity 启动的window feature参数
     */
    public static final String EXTRA_PARAM_WINDOW_FEATURE = "window_feature";

    /**
     * 指定activity 启动的window frag参数
     */
    public static final String EXTRA_PARAM_WINDOW_FLAGS = "window_flags";

    /**
     * 制定activity windowSoftInputMode
     */
    public static final String EXTRA_SOFT_INPUT_MODE = "soft_input_mode";


    Fragment mFragment;

    ReusingActivity mActivity;

    ReusingActivityHelper(ReusingActivity activity) {
        mActivity = activity;
    }

    /**
     * 设置window feature参数
     */
    void requestWindowFeature() {
        if (!isSingleFragmentIntent(mActivity)) {
            return;
        }
        Bundle param = mActivity.getIntent().getBundleExtra(
                SINGLE_FRAGMENT_ACTIVITY_START_ME_PARAM);
        Bundle extraParam = param.getBundle(EXTRA);
        if (extraParam != null
                && extraParam.containsKey(EXTRA_PARAM_WINDOW_FEATURE)) {
            int windowFeature = extraParam == null ? Window.FEATURE_ACTION_BAR
                    : extraParam.getInt(EXTRA_PARAM_WINDOW_FEATURE,
                    Window.FEATURE_ACTION_BAR);
            mActivity.requestWindowFeature(windowFeature);
            
            if(windowFeature == Window.FEATURE_NO_TITLE && mActivity.getSupportActionBar()!=null){
                mActivity.getSupportActionBar().hide();// 隐藏ActionBar
            }
        }
    }

    /**
     * 设置 setSoftInputMode
     */
    public void setSoftInputMode() {
        if (!isSingleFragmentIntent(mActivity)) {
            return;
        }
        Bundle param = mActivity.getIntent().getBundleExtra(
                SINGLE_FRAGMENT_ACTIVITY_START_ME_PARAM);
        Bundle extraParam = param.getBundle(EXTRA);
        if (extraParam != null
                && extraParam.containsKey(EXTRA_SOFT_INPUT_MODE)) {
            int softInputMode = extraParam.getInt(EXTRA_SOFT_INPUT_MODE);
            try {
                mActivity.getWindow().setSoftInputMode(softInputMode);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 设置window frag参数
     */
    void setWindowFlags() {
        if (!isSingleFragmentIntent(mActivity)) {
            return;
        }

        Bundle param = mActivity.getIntent().getBundleExtra(
                SINGLE_FRAGMENT_ACTIVITY_START_ME_PARAM);
        Bundle extraParam = param.getBundle(EXTRA);
        if (extraParam.containsKey(EXTRA_PARAM_WINDOW_FLAGS)) {
            mActivity.getWindow().addFlags(extraParam.getInt(EXTRA_PARAM_WINDOW_FLAGS));
        }
    }

    /**
     * 初始化fragment
     */
    Fragment ensureFragment() {
        Bundle param = mActivity.getIntent().getBundleExtra(
                SINGLE_FRAGMENT_ACTIVITY_START_ME_PARAM);
        if (param == null) {
            return null;
        }
        return ensureFragmentInternal(param);
    }

    public String getFragmentSimpleName() {
        Bundle param = mActivity.getIntent().getBundleExtra(
                SINGLE_FRAGMENT_ACTIVITY_START_ME_PARAM);
        if (param == null) {
            return null;
        }
        return param.getString(FRAGMENT_TAG);
    }

    /**
     * 初始化fragment
     *
     * @param param
     */
    private Fragment ensureFragmentInternal(Bundle param) {
        Bundle extraParam = param.getBundle(EXTRA);

        // 设置activity layout
        int layoutId = extraParam == null ? 0 : extraParam.getInt(
                EXTRA_PARAM_LAYOUT, 0);
        if (layoutId != 0) {
            /*
               如果我们在intentBuild中设置了layoutId就会调用setContentView(layoutId)
               其实调用setContentView(layoutId) 只是把layoutId布局添加到DecorView的android.R.id.content中
            */
            mActivity.setContentView(layoutId);
        }
        String fragmentTag = param.getString(FRAGMENT_TAG);

        mFragment = mActivity.getSupportFragmentManager()
                .findFragmentByTag(fragmentTag);

        if (mFragment == null) {//看看我们是不是已经在fragmentManager中添加了要显示的fragment,防止重复添加
            // 初始化fragment
            String fragmentName = param.getString(FRAGMENT_NAME);

            Bundle argu = param.getBundle(FRAGMENT_ARGU);

            // 设置fragment container id
            int containerId = layoutId == 0 || extraParam == null ? 0
                    : extraParam.getInt(EXTRA_PARAM_CONTAINER, 0); //如果我们没设置layoutId则不生效
            if (containerId != 0) { //如果我们在intentBuild中设值layoutId 和 containerId 我们把fragment内容显示到containerId中
                mFragment = addFragmentByTag(containerId, fragmentName,
                        fragmentTag, argu);//argu是上个页面传递给显示的fragment参数
            } else {//如果没有containerId 把fragment内容显示到android.R.id.content中
                mFragment = addFragmentByTag(android.R.id.content,
                        fragmentName, fragmentTag, argu);//argu是上个页面传递给显示的fragment参数
            }
        }
        return mFragment;
    }


    private Fragment addFragmentByTag(int container, String clazz, String tag,
                                      Bundle argument) {
        FragmentManager fm = mActivity.getSupportFragmentManager();
        Fragment f = fm.findFragmentByTag(tag);
        if (f == null) {
            FragmentTransaction ft = fm.beginTransaction();
            f = Fragment.instantiate(mActivity, clazz, argument);
            if (container == 0) {
                ft.add(f, tag);
            } else {
                ft.add(container, f, tag);
            }

            ft.commitAllowingStateLoss();
        } else if (f.isDetached()) {
            FragmentTransaction ft = fm.beginTransaction();
            ft.attach(f);
            ft.commitAllowingStateLoss();
        }
        return f;
    }

    static boolean isSingleFragmentIntent(Activity activity) {
        Bundle param = activity.getIntent().getBundleExtra(
                SINGLE_FRAGMENT_ACTIVITY_START_ME_PARAM);
        return param != null;
    }

    public static IntentBuilder builder(Context context) {
        IntentBuilder b = new IntentBuilder();
        return b.create(context, ReusingActivity.class);
    }

    public static IntentBuilder builder(Context context, Class<? extends ReusingActivity> claz) {
        IntentBuilder b = new IntentBuilder();
        return b.create(context, claz);
    }

    public static IntentBuilder builder(Fragment fragment) {
        if (fragment == null || fragment.getActivity() == null) {
            return null;
        }
        return builder(fragment.getActivity());
    }


    public static class IntentBuilder {
        private Intent intent;

        private Bundle args;

        private Bundle extra;

        private IntentBuilder() {

        }

        private IntentBuilder create(Context context,
                                     Class<? extends Activity> clazz) {
            intent = new Intent(context, clazz);
            args = new Bundle();
            extra = new Bundle();
            return this;
        }

        public IntentBuilder setFragment(Class<? extends Fragment> fragment,
                                         Bundle args4fragment) {
            args.putString(FRAGMENT_NAME, fragment.getName());
            args.putString(FRAGMENT_TAG, fragment.getSimpleName());
            args.putBundle(FRAGMENT_ARGU, args4fragment);
            return this;
        }

        public IntentBuilder setFragment(String fragmentName,
                                         String fragmentTag, Bundle args4fragment) {
            args.putString(FRAGMENT_NAME, fragmentName);
            args.putString(FRAGMENT_TAG, fragmentTag);
            args.putBundle(FRAGMENT_ARGU, args4fragment);
            return this;
        }


        public IntentBuilder setExtra(Bundle extra) {
            this.extra.putAll(extra);
            return this;
        }
        /**
         * 设置我们要显示的布局id
         */
        public IntentBuilder setLayoutId(int layoutId) {
            extra.putInt(EXTRA_PARAM_LAYOUT, layoutId);
            return this;
        }
        /**
         * 设置我们要显示的fragment 显示在LayoutId中那个容器里
         */
        public IntentBuilder setContainerId(int containerId) {
            extra.putInt(EXTRA_PARAM_CONTAINER, containerId);
            return this;
        }

        public IntentBuilder setWindowFlag(int windowFlag) {
            extra.putInt(EXTRA_PARAM_WINDOW_FLAGS, windowFlag);
            return this;
        }

        public IntentBuilder addIntentFlags(int flags) {
            intent.addFlags(flags);
            return this;
        }

        public IntentBuilder setWindowFeature(int windowFeature) {
            extra.putInt(EXTRA_PARAM_WINDOW_FEATURE, windowFeature);
            return this;
        }

        public IntentBuilder setSoftInputMode(int softInputMode) {
            extra.putInt(EXTRA_SOFT_INPUT_MODE, softInputMode);
            return this;
        }

        public Intent build() {
            args.putBundle(EXTRA, extra);
            intent.putExtra(SINGLE_FRAGMENT_ACTIVITY_START_ME_PARAM, args);
            return intent;
        }
    }
}

先不要慌~~~~ 很简单的
我们先看一下 ReusingActivityHelper 的静态内部类 IntentBuilder , 刚才我们分析了在create()中,我们创建了三个对象intent、args、extra并存到成员变量中,其中intent设置了我们要启动的ReusingActivity

接下来我们看一下setFragment()方法,这个方法很关键

    public IntentBuilder setFragment(Class<? extends Fragment> fragment,
                                         Bundle args4fragment) {
            args.putString(FRAGMENT_NAME, fragment.getName());
            args.putString(FRAGMENT_TAG, fragment.getSimpleName());
            args.putBundle(FRAGMENT_ARGU, args4fragment);
            return this;
        }

这个方法我们往args中添加了FRAGMENT_NAME这是我们要启动的fragment的类全路径,FRAGMENT_TAG,FRAGMENT_ARGU是传递给启动fragment的参数(比如:上个页面选中条目的id)

下面几个方法功能一样,都是把参数存放到extra中
setWindowFeature(int windowFeature)
setWindowFlag(int windowFlag)
setLayoutId(int layoutId)
setContainerId(int containerId)
setSoftInputMode(int softInputMode)

 public IntentBuilder setContainerId(int containerId) {
            extra.putInt(EXTRA_PARAM_CONTAINER, containerId);
            return this;
        }

另外有一个addIntentFlags(int flags)方法需要注意一下

  public IntentBuilder addIntentFlags(int flags) {
            intent.addFlags(flags);
            return this;
        }

通过上面方法我们set完配置信息后,调用build()方法返回intent

       public Intent build() {
            args.putBundle(EXTRA, extra);//extra被放入到args中
            //把所有信息放入到SINGLE_FRAGMENT_ACTIVITY_START_ME_PARAM中
            intent.putExtra(SINGLE_FRAGMENT_ACTIVITY_START_ME_PARAM, args);
            return intent;
        }

我们在返过去看看startFragment()方法,最终我们还是调用的startActivity(intent);

startActivity(intentBuilder.setFragment(fragmentClass,null).build());

接下来我们看一下ReusingActivity.java 我们需要在manifest.xml中配置activity

public class ReusingActivity extends AppCompatActivity {

    private ReusingActivityHelper helper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        if (ReusingActivityHelper.isSingleFragmentIntent(this)) {
            helper = new ReusingActivityHelper(this);
        }
        
        if (helper != null) {
        	//这三个方法是让我们设置的值生效,我们就不做分析了,自己看一下就可以了
            helper.requestWindowFeature();
            helper.setWindowFlags();
            helper.setSoftInputMode();
        }
        super.onCreate(savedInstanceState);
        if (helper != null) {
        	//显示界面内容
            helper.ensureFragment();
        }
    }
    
   @Override
    protected void onDestroy() {
        super.onDestroy();
        helper = null;
    }
}

看到上面的源码你们是不是舒了一口气,在Manifest.xml中配置ReusingActivity的标签

        <!--用来展示界面内容的activity,因为我们要复用,所以不能配置启动模式-->
        <activity android:name="com.reusing.lib.ReusingActivity"/>

我们先分析一下isSingleFragmentIntent()方法

 static boolean isSingleFragmentIntent(Activity activity) {
        Bundle param = activity.getIntent().getBundleExtra(
                SINGLE_FRAGMENT_ACTIVITY_START_ME_PARAM);
        return param != null;
    }

这个方法就是检查,我们是不是设置了SINGLE_FRAGMENT_ACTIVITY_START_ME_PARAM,为了防止其它页面直接启动ReusingActivity,而不是通过ReusingActivityHelper.IntentBuilder()。 其中SINGLE_FRAGMENT_ACTIVITY_START_ME_PARAM的值是在ReusingActivityHelper.IntentBuilde.build()方法设置的

helper = new ReusingActivityHelper(this); 逻辑比较简单

ReusingActivityHelper(ReusingActivity activity) {
mActivity = activity;
}

关键代码来了 helper.ensureFragment(); 我们看一下ensureFragment()方法

 Fragment ensureFragment() {
        Bundle param = mActivity.getIntent().getBundleExtra(
                SINGLE_FRAGMENT_ACTIVITY_START_ME_PARAM);
        if (param == null) {
            return null;
        }
        return ensureFragmentInternal(param);
    }

调用了ensureFragmentInternal(Bundle param)

   private Fragment ensureFragmentInternal(Bundle param) {
        Bundle extraParam = param.getBundle(EXTRA);

        // 设置activity layout
        int layoutId = extraParam == null ? 0 : extraParam.getInt(
                EXTRA_PARAM_LAYOUT, 0);
        if (layoutId != 0) {
            /*
               如果我们在intentBuild中设置了layoutId就会调用setContentView(layoutId)
               其实调用setContentView(layoutId) 只是把layoutId布局添加到DecorView的android.R.id.content中
            */
            mActivity.setContentView(layoutId);
        }
        String fragmentTag = param.getString(FRAGMENT_TAG);

        mFragment = mActivity.getSupportFragmentManager()
                .findFragmentByTag(fragmentTag);

        if (mFragment == null) {//看看我们是不是已经在fragmentManager中添加了要显示的fragment,防止重复添加
            // 初始化fragment
            String fragmentName = param.getString(FRAGMENT_NAME);

            Bundle argu = param.getBundle(FRAGMENT_ARGU);

            // 设置fragment container id
            int containerId = layoutId == 0 || extraParam == null ? 0
                    : extraParam.getInt(EXTRA_PARAM_CONTAINER, 0); //如果我们没设置layoutId则不生效
            if (containerId != 0) { //如果我们在intentBuild中设值layoutId 和 containerId 我们把fragment内容显示到containerId中
                mFragment = addFragmentByTag(containerId, fragmentName,
                        fragmentTag, argu);//argu是上个页面传递给显示的fragment参数
            } else {//如果没有containerId 把fragment内容显示到android.R.id.content中
                mFragment = addFragmentByTag(android.R.id.content,
                        fragmentName, fragmentTag, argu);//argu是上个页面传递给显示的fragment参数
            }
        }
        return mFragment;
    }

在上面方法中,我们设置了我们要显示的界面的layoutId(比如:activity_main),以及我们要显示的fragment显示在layoutId布局中那个view中containerId ,fragment最终显示代码在addFragmentByTag()中,我们看一下

private Fragment addFragmentByTag(int container, String clazz, String tag,
                                      Bundle argument) {
        FragmentManager fm = mActivity.getSupportFragmentManager();
        Fragment f = fm.findFragmentByTag(tag);
        if (f == null) {
            FragmentTransaction ft = fm.beginTransaction();
            f = Fragment.instantiate(mActivity, clazz, argument);
            if (container == 0) {
                ft.add(f, tag);
            } else {
                ft.add(container, f, tag);
            }

            ft.commitAllowingStateLoss();
        } else if (f.isDetached()) {
            FragmentTransaction ft = fm.beginTransaction();
            ft.attach(f);
            ft.commitAllowingStateLoss();
        }
        return f;
    }

是不是很简单~~~~argument是什么呢? 前面已经提到它是传递给要显示fragment的参数,我们看一下Fragment.instantiate(mActivity, clazz, argument);方法就明白了

   public static Fragment instantiate(Context context, String fname, @Nullable Bundle args) {
            ....
            Class<?> clazz = (Class)sClassMap.get(fname);
            if (clazz == null) {
                clazz = context.getClassLoader().loadClass(fname);
                sClassMap.put(fname, clazz);
            }

            Fragment f = (Fragment)clazz.getConstructor().newInstance();
            if (args != null) {
                args.setClassLoader(f.getClass().getClassLoader());
                f.setArguments(args);
            }
            ....
	}

看到 f.setArguments(args); 代码没,这下明白了吧,我们可以在fragment中 调用getArguments();获取到,比如:


public class BFragment extends Fragment {
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        Bundle arguments = getArguments();
        return inflater.inflate(R.layout.activity_b,container,false);
    }
}


好了,接下来我们看剩下的1000行代码
别慌~~没了 哈哈

总结:用这种方式有什么优点和缺点呢?

优点:
1、我们不需要每写一个页面就需要在manifest中配置相应的标签了
2、如果多个页面部分内容相同(比如好几个页面的列表相同),因为我们所有页面都是基于fragment实现的,所以直接可以复用,activity不行滴~~~

缺点:
你有没用发现activity四大启动模式挂了~~~~~
不过呢 我们可以自定义一个fragment启动栈来实现,对不
这时,你可能又要问了,singleInstance 怎么办,这时我们可以用ReusingActivity的子类
另外我们可能需要拦截activity finish事件 我们可以这样做,让fragment实现一个接口,重写ReusingActivity的onBackPressed()、finish()

 @Override
    public void onBackPressed() {
        if (helper != null && helper.mFragment != null && helper.mFragment instanceof OnInterceptListener) {
            OnInterceptListener onInterceptListener = (OnInterceptListener) helper.mFragment;
            if (onInterceptListener.interceptOnBackPressed()) {//如果fragment不拦截
                return;
            }
        }
        super.onBackPressed();
    }

    @Override
    public void finish() {
        if (helper != null && helper.mFragment != null && helper.mFragment instanceof OnInterceptListener) {
            OnInterceptListener onInterceptListener = (OnInterceptListener) helper.mFragment;
            if (onInterceptListener.interceptOnFinish()) {
                return;
            }
        }
        super.finish();
    }

好了~~~完事了

上一篇:MTU & MSS 详解记录(转)


下一篇:安卓学习,参数的双向传递