Scene 导航和页面切分组件库

我要开发同款
匿名用户2021年12月17日
175阅读

技术信息

授权协议
Apache 2.0

作品详情

Scee是字节跳动开源的一个基于View的轻量级导航和页面切分组件库,主要特性:

简单方便的页面导航和栈管理,支持MultiStack完善的生命周期的管理和分发可以更简单的实现复杂的过场动画支持对Activity和Widow属性的修改和恢复支持页面之间拿返回值,支持在Scee中申请权限支持页面销毁时保存状态和恢复介绍Scee旨在导航和页面切分上替代Activity和Fragmet的使用。

Activity目前存在的主要问题:

栈管理弱,Itet和LauchMode混乱,即使各种Hack仍然不能完全避免黑屏等问题Activity的性能较差,普通的空白页面启动也平均60ms以上(三星S9测试)因为Activity被强制需要支持销毁恢复,导致了一些问题:转场动画能力有限,无法实现较复杂的交互动画,共享元素动画基本不可用,有Framework层的崩溃无法解决每次启动新的Activity,都需要上个页面执行完oSaveIstace,损失性能Activity依赖Maifest文件导致注入困难,动态化需要各种HackFragmet目前存在的主要问题:

官方长期无法解决的崩溃较多,即使不用Fragmet,在AppCompatActivity的oBackPressed()中仍然可能触发崩溃add/remove/hide/show操作不是立刻执行,在嵌套时即使使用commitNow也不能保证子Fragmet状态更新动画支持糟糕,页面切换时无法保证Z轴顺序导航功能很弱,除了基本的打开和关闭,高级的栈管理原生Fragmet和Supportv4包中的Fragmet的生命周期并不完全相同Scee框架尝试去解决上面提到的Activity和Fragmet存在的问题

提供简单可靠、易扩展的API,来实现一套轻量的导航和页面切分解决方案

同时我们提供了一系列的迁移方案,来帮助开发者渐进式地从Activity和Fragmet迁移到Scee。

GetStarted在依赖中添加:

implemetatio'com.bytedace.scee:scee:$latest_versio'implemetatio'com.bytedace.scee:scee-ui:$latest_versio'implemetatio'com.bytedace.scee:scee-shared-elemet-aimatio:$latest_versio'implemetatio'com.bytedace.scee:scee-ktx:$latest_versio'Scee有2个子类:NavigatioScee和GroupScee,其中:

NavigatioScee支持页面切换GroupScee支持页面切分SceeNavigatioSceeGroupScee简单的接入,让主Activity继承于SceeActivity即可:

classMaiActivity:SceeActivity(){overridefugetHomeSceeClass():Class<outScee>{returMaiScee::class.java}overridefusupportRestore():Boolea{returfalse}}一个简单的Scee示例:

classMaiScee:AppCompatScee(){privatelateiitvarmButto:ButtooverridefuoCreateCotetView(iflater:LayoutIflater,cotaier:ViewGroup,savedIstaceState:Budle?):View?{valframeLayout=FrameLayout(requireSceeCotext())mButto=Butto(requireSceeCotext())mButto.text="Click"frameLayout.addView(mButto,FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT))returframeLayout}overridefuoActivityCreated(savedIstaceState:Budle?){super.oActivityCreated(savedIstaceState)setTitle("Mai")toolbar?.avigatioIco=ullmButto.setOClickListeer{avigatioScee?.push(SecodScee())}}}classSecodScee:AppCompatScee(){privatevalmId:Itbylazy{View.geerateViewId()}overridefuoCreateCotetView(iflater:LayoutIflater,cotaier:ViewGroup,savedIstaceState:Budle?):View?{valframeLayout=FrameLayout(requireSceeCotext())frameLayout.id=mIdreturframeLayout}overridefuoActivityCreated(savedIstaceState:Budle?){super.oActivityCreated(savedIstaceState)setTitle("Secod")add(mId,ChildScee(),"TAG")}}classChildScee:Scee(){overridefuoCreateView(iflater:LayoutIflater,cotaier:ViewGroup,savedIstaceState:Budle?):View{valview=View(requireSceeCotext())view.setBackgroudColor(Color.GREEN)returview}}MigratiotoScee一个新的App可以通过直接继承SceeActivity的方式接入Scee,

但如果已有的Activity不方便更改继承关系,则可参考SceeActivity的代码直接使用SceeDelegate来处理,

以西瓜视频的首页迁移方案为例:

首先在首页的XML申明一个存放Scee的布局:scee_cotaier

<?xmlversio="1.0"ecodig="utf-8"?><mergexmls:adroid="https://schemas.adroid.com/apk/res/adroid"adroid:layout_width="match_paret"adroid:layout_height="match_paret"><...><...><!--上面是这个Activity的已有布局--><FrameLayoutadroid:id="@+id/scee_cotaier"adroid:layout_width="match_paret"adroid:layout_height="match_paret"/></merge>再创建一个透明的Scee作为根Scee

publicstaticclassEmptyHolderSceeextedsScee{@NoNull@OverridepublicViewoCreateView(LayoutIflateriflater,@NullableViewGroupcotaier,@NullableBudlesavedIstaceState){returewView(getActivity());}@OverridepublicvoidoViewCreated(Viewview,@NullableBudlesavedIstaceState){super.oViewCreated(view,savedIstaceState);getView().setBackgroudColor(Color.TRANSPARENT);}@OverridepublicvoidoActivityCreated(@NullableBudlesavedIstaceState){super.oActivityCreated(savedIstaceState);ArticleMaiActivityactivity=(ArticleMaiActivity)requireActivity();activity.createSceeLifecycleCallbacksToDispatchLifecycle(getNavigatioScee());}}绑定这个透明的Scee到R.id.scee_cotaier

mSceeActivityDelegate=NavigatioSceeUtility.setupWithActivity(this,R.id.scee_cotaier,ull,ewNavigatioSceeOptios().setDrawWidowBackgroud(false).setFixSceeWidowBackgroudEabled(true).setSceeBackgroud(R.color.material_default_widow_bg).setRootScee(EmptyHolderScee.class,ull),false);实质上是有个透明的Scee盖在首页,但是视觉上看不出来

然后在Activity中提供Push的方法

publicvoidpush(@NoNullClass<?extedsScee>clazz,@NullableBudleargumet,@NullablePushOptiospushOptios){if(mSceeActivityDelegate!=ull){mSceeActivityDelegate.getNavigatioScee().push(clazz,argumet,pushOptios);}}这样就基本迁移完成,可以在这个Activity中直接打开新的Scee页面了。

Issues由于Scee是基于View来实现其功能的,有一些已知但暂时无法解决的问题:

Dialog一个正常Dialog的Widow是独立于并盖在Activity的Widow之上的,

所以如果在Dialog中点击打开一个Scee,就会导致Scee出现在Dialog后面。

可以选择点击的时候关闭对话框,也可以选择使用Scee来实现对话框,来替代系统的Dialog。

SurfaceViewadTextureView在Scee返回时,会先执行Scee的生命周期后执行动画,

但是如果遇到SurfaceView/TextureView,这个过程会导致SurfaceView/TextureView黑屏,

对于TextureView可以选择结束前,获得Surface,动画前把这个Surface重新赋值

对于SurfaceView,结束前,捕获Bitmap,设置到ImageView,这个过程中因为涉及大的Bitmap创建,

可以Trycatch,然后在动画结束后回收这个Bitmap。

StatusBarrelated刘海屏在AdroidP之前没有官方API,各个厂商有自己的实现

如果用WidowFlag或ViewUiVisibility来隐藏状态栏图标,都会引发整个Activity的重新布局,

这同时也会导致Scee页面的位置变化,某些情况下可能会有不符合预期的行为

 

功能介绍

Scene 是字节跳动开源的一个基于 View 的轻量级导航和页面切分组件库,主要特性: 简单方便的页面导航和栈管理,支持MultiStack 完善的生命周期的管理和分发 可以更简单的实现复杂的...

声明:本文仅代表作者观点,不代表本站立场。如果侵犯到您的合法权益,请联系我们删除侵权资源!如果遇到资源链接失效,请您通过评论或工单的方式通知管理员。未经允许,不得转载,本站所有资源文章禁止商业使用运营!
下载安装【程序员客栈】APP
实时对接需求、及时收发消息、丰富的开放项目需求、随时随地查看项目状态

评论