轻量级免声明的 Activity 代理框架,SystemBar 一体化,Activity 和 Frament 状态存储

来源:互联网 发布:柔宇科技工资高吗 知乎 编辑:程序博客网 时间:2024/06/05 03:37

AyoActivityNoManifest

项目地址:cowthan/AyoActivityNoManifest
简介:轻量级免声明的 Activity 代理框架,SystemBar 一体化,Activity 和 Frament 状态存储
A light tool sdk include: Activity without 声明 in manifest,SystemBar 一体化,Activity 和 Frament 状态存储

1 这是什么?

  • 这个库提供了:
    • 一个轻量级的 Activity 代理框架(ActivityAttacher,使用方式基本和 Activity 一样),目的在于不必在 Manifest 反复声明 Activity
    • 同时提供了一个轻量级的 Bundle 机制(SimpleBundle,使用方式基本和 Bundle 一样),目的在于在 Activity 之间传递参数时考虑序列化问题,适用于进程内通信
    • 提供了一个轻量级的 OnActivityResult 机制(OnResultCallback,使用方式基本和 OnActivity 不一样)
    • 状态栏一体化的简单封装
    • Activity 和 Fragment 状态保存的问题
    • 其他 Activity 和 Fragment 问题的解决方案,后期一个一个加

2 ActivityAttacher 的使用

(1) manifest

在 gradle 里引入:compile 'org.ayo:ayo-attacher:1.0.0'

  • manifest 里只需要声明:
    • 主 Activity
    • 有特殊需求的 Activity,如支持旋转
    • 模板 Activity,暂时只支持一个启动模式对应一个模板 Activity
    • 模板 Activity 有几个默认配置项,如果需要更改,也需要声明自己的 Activity

Manifest 中的声明:

<activity            android:name="com.cowthan.sample.MainActivity"            android:configChanges="orientation|screenSize|keyboardHidden|navigation"            android:screenOrientation="portrait"            android:theme="@style/AppTheme"            >            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>        <activity            android:name="org.ayo.attacher.TmplActivityStandard"            android:configChanges="orientation|screenSize|keyboardHidden|navigation"            android:screenOrientation="portrait"            android:launchMode="standard"            android:theme="@style/AyoTransparentTheme" />        <activity            android:name="org.ayo.attacher.TmplActivitySingleTask"            android:configChanges="orientation|screenSize|keyboardHidden|navigation"            android:screenOrientation="portrait"            android:launchMode="singleTask"            android:theme="@style/AyoTransparentTheme" />        <activity            android:name="org.ayo.attacher.TmplActivitySingleTop"            android:configChanges="orientation|screenSize|keyboardHidden|navigation"            android:screenOrientation="portrait"            android:launchMode="singleTop"            android:theme="@style/AyoTransparentTheme" />        <activity            android:name="org.ayo.attacher.TmplActivitySingleInstance"            android:configChanges="orientation|screenSize|keyboardHidden|navigation"            android:screenOrientation="portrait"            android:launchMode="singleInstance"            android:theme="@style/AyoTransparentTheme" />

(2) ActivityAttacher

  • ActivityAttacher 的意义:
    • ActivityAttacher 就是附着在上面 4 个模板 Activity 里的 Activity 代理
    • ActivityAttacher 中持有一个 Activity 实例对象,是在 onCreate 时赋值的
    • ActivityAttacher 可以处理 Activity 中的所有配置和生命周期
    • ActivityAttacher 提供的接口,原则上应该完全仿 Activity,这一点类似 v7 源码中的和 AppCompactActivity 相关的一个 delegate 类,但不知道这个类是干什么用的

(3) 定义 Activity

看代码,这两个只有基类不一样,内部代码应该是一样的,其中继承 AyoActivity 的是一个普通 Activity,需要去 manifest 声明, 而继承 AyoActivityAttacher,就不需要再去 manifest 声明了

public class SampleActivity extends AyoActivityAttacher{    public static void start(Context c, boolean takeSystemBar, int lanuchMode, OnResultCallBack callBack){        SimpleBundle sb = new SimpleBundle();        sb.putExtra("takeSystemBar", takeSystemBar);        ActivityAttacher.startActivity(c, SampleActivity.class, sb, false, lanuchMode, callBack);    }    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.ac_tmpl);    }}public class SampleActivity extends AyoActivity{    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.ac_tmpl);    }}

(4) 启动 ActivityAttacher

启动方式变成这样:

public static void start(Context c, boolean takeSystemBar, int lanuchMode, OnResultCallBack callBack){    SimpleBundle sb = new SimpleBundle();    sb.putExtra("takeSystemBar", takeSystemBar);    ActivityAttacher.startActivity(c, SampleActivity.class, sb, false, lanuchMode, callBack);}
  • SimpleBundle:功能类似于 intent 或者 bundle,存的是传到下一个 Activity 的参数
    • 取出参数:boolean takeSystemBar = getIntent().getBooleanExtra("takeSystemBar");
    • 这里,在 Activity 之间传的都是引用,不再需要考虑序列化问题,当然只适用于 app 单进程内
  • OnResultCallBack 是接收 Activity 的回传结果
    • 如何回传:getResultCallback().onResult("代替 OnActivityReslt 和 setResult"); finish();
  • lanuchMode 是选择 Activity 的启动模式,也就是选择模板:
    • ActivityAttacher.LAUNCH_MODE_STANDARD
    • ActivityAttacher.LAUNCH_MODE_SINGLE_TASK
    • ActivityAttacher.LAUNCH_MODE_SINGLE_TOP
    • ActivityAttacher.LAUNCH_MODE_SINGLE_INSTANCE

(5) Activity 主题

这里提供了两个主题:AyoTransparentTheme 和 AyoTheme,没啥特殊的

3 状态栏一体化问题

问题 1:颜色设置,可以开启和关闭,分 status bar 和 navigation bar

问题 2:是否侵入,可以开启和关闭,和颜色设置不冲突

代码:

@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.sample_ac_main);    //关闭 StatusBar 和 NavigationBar 侵入    getAgent().enableSystemBarTakenByContent(false);    //给 StatusBar 和 NavigaionBar 染色    getAgent().renderSystemBar(Color.parseColor("#55ff0000"), Color.parseColor("#55ff0000"));}
  • 解析:
    • 这里就是对开源代码 SystemBarTintManager 的简单封装
    • enableSystemBarTakenByContent 其实就是设置根布局的android:fitsSystemWindows属性

fitSystemWindows 是 true 时:enableSystemBarTakenByContent(false),内容给 SystemBar 留空 

fitSystemWindows 是 false 时:enableSystemBarTakenByContent(true),内容侵入 SystemBar 

4 状态保存问题

https://github.com/frankiesardo/icepick

5 其他

关于 clipToPadding 和 clipToChildren:默认都为 truehttp://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0317/2613.html

好像和滚动有关,可以上下滚动时,内容是否可以滚动到标题栏里

<ListView    android:layout_gravity="center_vertical"    android:id="@+id/list"    android:clipChildren="false"    android:clipToPadding="false"    android:paddingTop="50dip"    android:layout_width="match_parent"    android:layout_height="match_parent" />

ListView 初始化之后,由于 top 的 50dp 的 padding,看似顶着标题栏,但往上滚动时,内容就会跑到 padding 的 50dp 里,也就能从标题栏看到了(如果标题栏带透明)

0 0