|
Android中WebView栏风格在新装修业务场景下的实践
Android中WebView栏风格在新装修业务场景下的实践
张炎@贝壳找房
贝壳产品技术
贝壳产品技术 “贝壳产品技术公众号”作为贝壳官方产品技术号,致力打造贝壳产品、技术干货分享平台,面向互联网/O2O开发/产品从业者,每周推送优质产品技术文章、技术沙龙活动及招聘信息等。欢迎大家关注我们。 242篇内容
2021年03月06日 00:20
前言在应用程序开发过程中,Native+H5混合开发一直是主流形式,作为内容信息的展示载体,H5无疑是更好的选择。一个标准样式的H5页面,包含头部栏和WebView内容区域,在贝壳体系下的App基本遵循这类型风格,如图所示:在被窝家装App初期,我们的H5页面也是遵循这种标准样式,在后面的迭代中,为了更好的用户视觉体验效果,我们对现有的H5页面进行梳理,总结出以下几类使用场景:#标准页面样式:默认白色栏+WebView组合布局形式;(图一)使用场景:默认的H5页面展示效果,如果没有其它的参数开关,跳转后样式风格固定如图所示;#有颜色的TitleBar样式:栏+状态栏颜色统一,达到视觉连贯效果,WebView上滑过程中,TitleBar不会变化;(如图二)使用场景:适用于一些活动页、广告页等H5页面,头部TitleBar+状态栏连贯,视觉体验效果更优;#沉浸式TitleBar样式:和原生的沉浸式页面效果一样,展示沉浸式状态栏效果,WebView上滑过程中,TitleBar会有透明度变化,例如设计师页(H5)、套餐页(H5)(如图三、图四)使用场景:适用于需要展示沉浸式样式的H5页面,通过参数简单配置即可;#沉浸式TitleBar + IconTextBtn按钮样式:在沉浸式TitleBar基础上,支持IconTextBtn组合按钮展示,例如点赞、收藏等交互操作;(如图五)使用场景:以前的TitleBar右上角容器只支持创建单一的ImageView、TextView、Drawable、自定义View,在家装实际使用过程中需要增加IconTextBtn这种组合交互按钮,点击后image、text会跟随变化,我们对它进行了扩展;针对以上不同的场景,我们开始了改造之路~1 有颜色的TitleBar以设计半包页为例,当前加载的url是:https://nowm.home.ke.com/jinggong/bj/designer_channelbgColor=C09978需要实现TitleBar有颜色的页面,我们和H5约定在访问链接中携带一个参数为bgColor,当bgColor有值时,客户端进行特殊处理,步骤如下:Step1: 将页面设置沉浸式样式,透明状态栏+白色文字;Step2: 栏布局样式是android:gravity="bottom"居底对齐,将mTopView和mTitleBar的高度设置成状态栏高度+栏高度;Step3: 给栏mTitleBar设置bgColor,设置文字和图标显示为白色;变量解释:mTopView是一个占位View,主要作用是将WebView的头部起点位置顶到TitleBar下方;示例代码如下:if(!TextUtils.isEmpty(bgColor)){initStatusBar();try{if(!bgColor.startsWith("#")){bgColor="#"+bgColor;}if(mTopView!=null){RelativeLayout.LayoutParamstopViewParams=(RelativeLayout.LayoutParams)mTopView.getLayoutParams();topViewParams.height=topHeight;mTopView.setLayoutParams(topViewParams);mTitleBar.setLayoutParams(topViewParams);}//不建议直接修改top_view的背景色,虽然可行省事,但是灵活性变差了。mTitleBar.setBackgroundColor(Color.parseColor(bgColor));mBtnBack.setImageResource(R.drawable.lib_webview_back_white);mTvTitle.setTextColor(Color.WHITE);}catch(Exceptione){e.printStackTrace();}}实际效果如图所示:2 沉浸式TitleBar以套餐页为例,当前加载的url是:https://nowm.home.ke.com/jinggong/bj/product/brand/package_overallimmersive=true&packageId=101584454034需要实现沉浸式TitleBar样式的页面,我们和H5约定在访问链接中携带一个参数为immersive,标准页面默认不传,当immersive有值且为true时,进行特殊处理,步骤如下:Step1:将页面设置沉浸式样式,透明状态栏+白色文字;Step2:栏布局样式是android:gravity="bottom"居底对齐,将titleBg、titleCover、mTitleBar的高度设置成状态栏高度+栏高度,titleBg、mTvTitle透明度设置0;变量解释:titleBg是一个View,用于垫在mTitleBar下方做滑动头部渐变效果;titleCover是一个View,作用单一,在沉浸式状态下显示,显示顶部阴影效果,其他状态隐藏;mTitleBar表示TitleBar栏;mTvTitle是TitleBar中的TextView;Step3:H5会监听WebView的滚动偏移量,通过JsBridge调用端能力和Native进行交互,将offsetY偏移量实时通知客户端;if(TextUtils.equals(targetUrl,URL_GETSCROLLOFFSET)){try{intoffsetY=Integer.parseInt(targetParams.get("offsetY"));H5CallBackManager.getInstance().onGetScrollOffset(offsetY);returntrue;}catch(Exceptione){CustomErrorManager.upload(CustomErrorManager.EXCEPTION,"jinggong/"+TAG,"H5沉浸式传递offsetY类型异常",JsonUtil.toJsonStr(e.toString()));e.printStackTrace();returnfalse;}}Step4:客户端收到通知后,变更状态栏和栏样式;@OverridepublicvoidonGetScrollOffset(intscrollHeight){if(null!=getActivity()&!((JsBridgeWebViewActivity)getActivity()).isFront()){return;}floatpercent=(float)(scrollHeight)/MAX_HEIGHT_VALUE;if(percent>1){percent=1;}if(percent>0.6){updateTitleStyle(STYLE_WHITE,percent);if(!isStatusBarTransparent){isStatusBarTransparent=true;StatusBarTintManagerstatusBarTintManager=newStatusBarTintManager(mActivity);statusBarTintManager.setStatusBarWhite();}}else{updateTitleStyle(STYLE_TRANSPARENT,1-percent);if(isStatusBarTransparent){isStatusBarTransparent=false;initStatusBar();}}if(null!=titleBg){titleBg.setAlpha(percent);}}静态效果展示:动态效果展示:3 沉浸式TitleBar + IconTextBtn按钮以文章页为例,当前加载的url是:https://nowm.home.ke.com/jinggong/bj/article_detailimmersive=true&id=A-2000000089在沉浸式栏的基础上,H5可以通过JsBridge方法setRightButton2设置栏右上角按钮结构,进行特殊处理:3.1:按钮数据结构定义如下;publicclassBaseRightButtonBean{publicStringname;publicStringclickUrl;//非沉浸式-展示的icon链接publicStringimageUrl;//沉浸式-展示的icon链接publicStringimmersiveImageUrl;//非沉浸式-展示的文字颜色publicStringtextHexColor;//沉浸式-展示的文字颜色publicStringimmersiveTextColor;...}3.2:根据实际交互约定,创建对应的RightIconTextButton组合按钮控件;@NonNullprivateViewcreateRightIconTextButton(@NonNullfinalBaseRightButtonBeanbean){Stringscheme=getCurrentUrl();Stringimmersive="false";if(!TextUtils.isEmpty(scheme)){finalMaptargetParams=UrlUtil.parseParams(scheme);immersive=targetParams!=nullTextUtils.isEmpty(targetParams.get("immersive"))"false":targetParams.get("immersive"):"false";}RightIconTextButtonbuttonView=newRightIconTextButton(mActivity);buttonView.bindData(bean,mImageLoader,immersive);returnbuttonView;}RightIconTextButton根据H5设置的参数进行赋值展示;3.3:H5滚动通知Native时,根据当前View类型,改变对应状态;3.4:当用户点击收藏/点赞按钮时,客户端不关心具体业务,根据clickUrl参数,客户端调用WebView能力通知H5,请求H5页面的方法:【当前传给native的协议是】:beikejinggong://postnotificationcallback=praiseClicked【回调给H5的js是】:javascript:praiseClicked()H5自行处理接口请求、刷新等逻辑,接口请求成功后再次通过JsBridge调用setRightButton2方法刷新右上角按钮样式和状态,示例BaseRightButtonBean数据结构如下:HybridBridge:setRightButton2:[{"name":"1","clickUrl":"beikejinggong://postnotificationcallback=praiseClicked","imageUrl":"https://image1.ljcdn.com/utopia-file/b7629f177b481c551123bc37cc5b9cdf.png","textHexColor":"#222222","immersiveImageUrl":"https://image1.ljcdn.com/utopia-file/6c66f6eb06b1cad108c85fc8a90b0f1e.png","immersiveTextColor":"#ffffff"},{"name":"0","clickUrl":"beikejinggong://postnotificationcallback=collectionClicked","imageUrl":"https://image1.ljcdn.com/utopia-file/d4a5343b4873759f2bee6f85e99efa58.png","textHexColor":"#222222","immersiveImageUrl":"https://image1.ljcdn.com/utopia-file/2813ade842a5445802143d9db78d2584.png","immersiveTextColor":"#ffffff"},{"name":"","clickUrl":"beikejinggong://h5/share/menushareType=0&webUrl=https%3A%2F%2Fnowm.home.ke.com%2Fjinggong%2Fbj%2Farticle_detail%3Fid%3DA-2000000673%26tab%3D%26immersive%3Dtrue&title=%E3%80%90%E6%88%B7%E5%9E%8B%E8%A7%A3%E8%AF%BB%EF%BD%9C%E4%B8%87%E5%B9%B4%E8%8A%B1%E5%9F%8E%E5%9B%9B%E6%9C%9F%E4%B8%A4%E5%AE%A4%E4%B8%80%E5%8E%85%E3%80%91&description=%E8%A2%AB%E7%AA%9D%E5%AE%B6%E8%A3%85%E4%B8%93%E4%B8%9A%E8%AE%BE%E8%AE%A1%E5%B8%88%E7%9C%BC%E9%87%8C%E7%9A%84%E6%88%B7%E5%9E%8B%E4%BC%98%E7%BC%BA%E7%82%B9%E5%92%8C%E6%94%B9%E9%80%A0%E9%87%8D%E7%82%B9&thumbUrl=https%3A%2F%2Fimage1.ljcdn.com%2Futopia-file%2Ff30fcf683fa1623151a89d2fd9323556.png","imageUrl":"https://img.ljcdn.com/home-web-pic/fc1854f248e2e385eca90221b5c72722","immersiveImageUrl":"https://img.ljcdn.com/home-web-pic/0d818aa08b77d63cfdbdc2b702a38586"}]实际运行效果如图:4 总结经过不断更新完善,目前这套WebView容器已经下沉封装到了通用引擎层中,在被窝家装、被窝设计、被窝运输、被窝精工、HOME等APP运行良好。
预览时标签不可点
移动端37大前端69移动端 · 目录#移动端上一篇一种按照library的维度进行Android包大小分析的方法和实践下一篇【GMTC·贝壳】贝壳找房 iOS 冷启动优化实践关闭更多小程序广告搜索「undefined」网络结果
|
|