智通东莞人才网,泰州seo公司,灰色行业网站,word上下页边距怎么调前言
在我之前的文章 Cordova初探 的开篇中说到了Cordova在Android应用开发中的一个显著的局限性就是我们的Activity必须继承其提供的CordovaActivity。这种设计对于那些追求个性化UI设计的项目而言#xff0c;显得尤为受限。 其实也可以理解#xff0c;Cordova主要旨在为前…前言
在我之前的文章 Cordova初探 的开篇中说到了Cordova在Android应用开发中的一个显著的局限性就是我们的Activity必须继承其提供的CordovaActivity。这种设计对于那些追求个性化UI设计的项目而言显得尤为受限。 其实也可以理解Cordova主要旨在为前端开发者提供一个方便的框架让他们可以专注于编写HTML、CSS和JS代码以满足业务需求并确保这些代码能够在iOS和Android平台上运行。 这对于纯H5的开发方式来说是非常合适的其中Cordova充当的是H5内容的容器。但是在我遇到的项目中纯H5开发方式实际上并不常见。 H5在理论上能够实现优雅的跨平台功能但在实践中我们需要考虑到多个关键因素如兼容性、性能以及与原生应用交互的成熟度。 所以本片文章主要是为Android开发的同学们提供一个基于Cordova封装的全场景适用的组件使得我们在Cordova原有功能的基础上能够突破必须继承CordovaActivity限制能够随心所欲的自定义我们的ui并提供更加丰富的功能以更好的支撑我们的业务需求。
目标 思路
目标
保持Cordova的原有功能和使用方式。摆脱继承Activity的限制使其像Webview控件一样灵活使用。提供基于Activity和Fragment的封装简化开发同时支持UI个性化。提供关键节点的回调以满足更广泛的业务需求。
思路
以CordovaActivity这个入口源码为切入点我们会发现CordovaActivity代码量并不大其核心功能集中在几个关键节点上例如处理SplashScreen、加载配置、初始化变量、创建CordovaInterface等。所以一个思路就是将CordovaActivity中关于CordovaWebView和CordovaWebViewEngine的核心代码提取出来封装成一个更小粒度的自定义view供外部使用同时提供Activity和Fragment的模版类暴露出自定义ui的接口。这样一来就可以实现核心目标了。
具体的代码实现已经上传到github上了欢迎感兴趣的读者前往查看。下面主要详细介绍组件的使用方法。
组件使用
添加依赖
implementation(com.xeonyu:cordova-webcontainer:1.0.5)继承CordovaWebContainerActivity使用
该方式适用于绝大部分业务场景集成简单且保持UI灵活。
布局示例
?xml version1.0 encodingutf-8?
androidx.constraintlayout.widget.ConstraintLayout xmlns:androidhttp://schemas.android.com/apk/res/androidxmlns:apphttp://schemas.android.com/apk/res-autoxmlns:toolshttp://schemas.android.com/toolsandroid:layout_widthmatch_parentandroid:layout_heightmatch_parenttools:contextcom.yzq.demo.activity.WebContainerActivity!--标题栏--androidx.appcompat.widget.Toolbarandroid:idid/toolbarandroid:layout_widthmatch_parentandroid:layout_heightwrap_contentandroid:backgroundcolor/purple_200app:layout_constraintStart_toStartOfparentapp:layout_constraintTop_toTopOfparentapp:titleTextColorcolor/white /!--进度条--ProgressBarandroid:idid/progressbarstyleandroid:style/Widget.ProgressBar.Horizontalandroid:layout_widthmatch_parentandroid:layout_height5dpapp:layout_constraintStart_toStartOfparentapp:layout_constraintTop_toBottomOfid/toolbar /!--基于Cordova封装的web容器控件--com.yzq.cordova_webcontainer.CordovaWebContainerandroid:idid/web_containerandroid:layout_widthmatch_parentandroid:layout_height0dpapp:layout_constraintBottom_toBottomOfparentapp:layout_constraintTop_toBottomOfid/progressbarapp:layout_goneMarginTop5dp /!--浮动按钮--com.google.android.material.floatingactionbutton.FloatingActionButtonandroid:idid/reload_fabandroid:layout_widthwrap_contentandroid:layout_heightwrap_contentandroid:layout_margin16dpandroid:contentDescription刷新android:srcdrawable/refreshandroid:tintcolor/whiteapp:layout_constraintBottom_toBottomOfparentapp:layout_constraintEnd_toEndOfparent /
/androidx.constraintlayout.widget.ConstraintLayout代码示例
/*** description 继承自WebcontainerActivity的使用示例* author yuzhiqiang (zhiqiang.yu.xeongmail.com)*/class WebContainerActivity : CordovaWebContainerActivity() {private lateinit var binding: ActivityWebContainerBindingprivate val TAG WebContainerActivity/*布局初始化*/override fun initContentView() {binding ActivityWebContainerBinding.inflate(layoutInflater)setContentView(binding.root)}/*初始化Webcontainer控件*/override fun initWebContainer(): CordovaWebContainer {with(binding) {webContainer.run {/*** 初始化webcontainer*/init(thisWebContainerActivity,thisWebContainerActivity)return binding.webContainer}override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)val url https://baidu.com/binding.webContainer.loadUrl(url)binding.webContainer.setOnPageScrollChangedListener { xOffset, yOffset, oldxOffset, oldyOffset -Log.i(TAG, yOffset:$yOffset,oldyOffset:$oldyOffset)}binding.reloadFab.setOnClickListener {binding.webContainer.reload()}}}在Fragment中使用
支持在Fragment中使用继承CordovaWebContainerFragment即可api跟CordovaWebContainerActivity 一致。需要注意的是Fragment的宿主Activity需要处理下页面结果回调的方法。
宿主的Activity中重写下面两个方法写法固定
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {super.onActivityResult(requestCode, resultCode, data)currentFragment?.onActivityResult(requestCode, resultCode, data)}override fun onRequestPermissionsResult(requestCode: Int,permissions: Arrayout String,grantResults: IntArray,) {super.onRequestPermissionsResult(requestCode, permissions, grantResults)currentFragment?.onRequestPermissionsResult(requestCode, permissions, grantResults)}Fragment正常使用即可示例代码
package com.yzq.demo.fragment/*** description 在Fragment中使用示例* author yuzhiqiang (zhiqiang.yu.xeongmail.com)*/class WebContainerFragment(val webUrl: String) : CordovaWebContainerFragment() {private lateinit var rootView: Viewprivate lateinit var webContainer: CordovaWebContaineroverride fun initContentView(inflater: LayoutInflater,container: ViewGroup?,savedInstanceState: Bundle?,): View {rootView layoutInflater.inflate(R.layout.fragment_web_container, container, false)return rootView}override fun initWebContainer(): CordovaWebContainer {webContainer rootView.findViewById(R.id.web_container)webContainer.init(requireActivity() as AppCompatActivity, this)return webContainer}override fun initWidget() {if (webUrl.isNotEmpty()) {webContainer.loadUrl(url webUrl)} else {webContainer.loadUrl()}}}作为自定义view使用
如果你不希望继承指定的Activity你可以把CordovaWebContainer作为自定义view使用。
package com.yzq.demo.activity/*** description 直接使用Webcontainer控件的示例适用于更加灵活的场景,例如你不想继承指定的Activity* author yuzhiqiang (zhiqiang.yu.xeongmail.com)*/class MainActivity : AppCompatActivity() {private lateinit var binding: ActivityMainBindingprivate val TAG MainActivityoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)binding ActivityMainBinding.inflate(layoutInflater)setContentView(binding.root)binding.run {toolbar.title 基于Cordova的webview使用/*初始化*/webContainer.init(thisMainActivity, thisMainActivity)/*加载url*/
// val url https://www.baidu.com/webContainer.loadUrl()}}//固定写法override fun onSaveInstanceState(outState: Bundle, outPersistentState: PersistableBundle) {super.onSaveInstanceState(outState, outPersistentState)binding.webContainer.onSaveInstanceState(outState)}//固定写法override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {super.onActivityResult(requestCode, resultCode, data)binding.webContainer.onActivityResult(requestCode, resultCode, data)}//固定写法override fun startActivityForResult(intent: Intent, requestCode: Int, options: Bundle?) {binding.webContainer.startActivityForResult(requestCode)super.startActivityForResult(intent, requestCode, options)}
//固定写法override fun onRequestPermissionsResult(requestCode: Int,permissions: Arrayout String,grantResults: IntArray,) {super.onRequestPermissionsResult(requestCode, permissions, grantResults)binding.webContainer.onRequestPermissionsResult(requestCode, permissions, grantResults)}
}API
列一下主要的api具体的使用可以参考github上的示例代码。
初始化WebContainer
传入Activity以及LifecycleOwner
/*初始化(必须)*/
webContainer.init(this, this)加载url
/*必须*/
webContainer.loadUrl(url)关键事件回调
webContainer.addPagePbserver(PageObserver)支持以下事件监听
请求拦截处理
/*可选拦截请求 等同于shouldInterceptRequest 记得用这个*/webContainer.webviewClient.interceptRequest { view, request, response -val url request.url.toString()Log.i(TAG, interceptRequest:$url)returninterceptRequest response}loadurl 处理
/*可选 处理准备load的url 等同于 shouldOverrideUrlLoading*/webContainer.webviewClient.overrideUrlLoading { view, request -Log.i(TAG, overrideUrlLoading:${request.url})request.url.toString().let {if (it.startsWith(baidu://)) {returnoverrideUrlLoading true}}returnoverrideUrlLoading false}滚动监听
webContainer.setOnPageScrollChangedListener { xOffset, yOffset, oldxOffset, oldyOffset -Log.i(TAG, yOffset:$yOffset,oldyOffset:$oldyOffset)}其他使用跟webview api一样
混淆
组件内部已包含必要的混淆规则。
#Cordova
-keep class org.apache.cordova.**{*;}
-keep interface org.apache.cordova.**{*;}
-keep enum org.apache.cordova.**{*;}这就是基于Cordova封装的全场景组件。如果您觉得本组件对您有所帮助欢迎在GitHub上点个star希望能帮到你。
github地址 cordova-webcontainer 感谢阅读觉有有帮助点赞支持如果有任何疑问或建议欢迎在评论区留言。如需转载请注明出处喻志强的博客 谢谢