为何须要扩充Lottie?原生Lottie的抖音抖音的赞不足袁记短视频热门业务教程网
Lottie相信端侧开发的朋友一定十分熟悉,打一出世就技惊四座,买赞直接将动漫开发的小时显示在线刷qq空间主页赞效率提升到了极高的级别,将我们开发从动漫的自助深渊中一把拽出,可以说没有Lottie之前碰到动漫的平台项目毛发掉一地,有了Lottie后的不出动漫需求真就保温杯里泡沙参了。
于是抖音抖音的赞我们可以渐渐欣赏Lottie呈现出以下疗效
随着业务迭代,设计师er将动漫又推向了一个新的买赞高度,早已不仅仅满足做一下展示型动漫了,小时显示她们想在更多的自助业务场景加入动漫来提升交互体验,例如拆个红包,平台砍个价等等
右图拆红包动漫供你们参考:
保温杯是不出否能够握得住了?
我们的需求
如上图所示是一个开红包的动漫,动漫中的抖音抖音的赞抢按键可点击,红包结果页的买赞让利券信息是插口动态下发,下边的小时显示金币,双击数,星星数都是用户独有的,不晓得你们工作中有没有类似场景呢?
抖音电商的在线刷qq空间主页赞场景下则有好多类似涉及动态业务数据的交互动漫,但这类需求我们就无法继续使用Lottie了,被迫又回归到最原始的原生代码方案,开发效率一下回到解放前,因而这类场景的开发效率亟需增强。
前期打算方案督查
需求场景明晰后接出来就是核高基方案了,我们先对功能做个拆解可以发觉我们动漫中须要满足动态替换文本,且文本的背景须要自适应拉伸,应当还有其他场景例如贴图的替换等,再加上按键的点击交互风波。
了解到我们的目标功能后则须要从Lottie开放或半开放的能力中找到切入点
Lottie给我们提供了替换文本和贴图的能力,这种能力是否能满足我们的需求呢?
Lottie可以替换文本和贴图,因而上述的动漫场景中文本可以动态替换
但做不到:
简单版方案
假如暂不考虑按键点击风波的话(有一些比较粗糙的方案来做点击)和动态控件疗效(并不是十分普遍的场景),我们是否有方案可以支持上述功能呢?
我们把思维打开一下,这种动态数据是否和原生的一个xml布局填充数据后十分相像?那既然Lottie支持动态替换贴图的话,我们是否可以动态生成贴图之后再进行替换呢?
其实是可以的,我们可以将动漫中所有动态的部份在动漫中用一张贴图占位,之后运行时动态将布局转换成贴图对占位贴图做一个替换,这样我们的动漫就实现了业务数据的动态绑定了
写了个简单的demo验证了该方案是可行的,如右图
第一步:将动态布局生成bitmap(相关代码网上好多)
/** * 获取已经显示的view的bitmap * @param view * @return */ public static Bitmap getCacheBitmapFromView(View view) { final boolean drawingCacheEnabled = true; view.setDrawingCacheEnabled(drawingCacheEnabled); view.buildDrawingCache(drawingCacheEnabled); final Bitmap drawingCache = view.getDrawingCache(); Bitmap bitmap = null; if (drawingCache != null) { bitmap = Bitmap.createBitmap(drawingCache); view.setDrawingCacheEnabled(false); } return bitmap; } /** * 获取未显示的view的bitmap * @param view * @param width * @param height * @return */ public static Bitmap getBitmapFromView(View view, int width, int height) { layoutView(view, width, height); return getCacheBitmapFromView(view); } /** * 布局控件 * @param view * @param width * @param height */ private static void layoutView(View view, int width, int height) { view.layout(0, 0, width, height); int measuredWidth = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY); int measuredHeight = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY); view.measure(measuredWidth, measuredHeight); view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight()); }
第二步:通过LottieAssetDelegate动态替换掉占位贴图即可
public class LottieAssetDelegate implements ImageAssetDelegate { private Context context; private String replaceImgName; private Bitmap replaceBitmap; private String imagesFolder; public LottieAssetDelegate(Context context, String replaceImgName, Bitmap replaceBitmap, String imagesFolder) { this.context = context; this.replaceImgName = replaceImgName; this.replaceBitmap = replaceBitmap; if (!TextUtils.isEmpty(imagesFolder) && imagesFolder.charAt(imagesFolder.length() - 1) != '/') { this.imagesFolder = imagesFolder + '/'; } else { this.imagesFolder = imagesFolder; } } @Nullable @Override public Bitmap fetchBitmap(LottieImageAsset asset) { if (replaceImgName.equals(asset.getFileName())) { return replaceBitmap; } return getBitmap(asset); } private Bitmap getBitmap(LottieImageAsset asset) { Bitmap bitmap = null; String filename = asset.getFileName(); BitmapFactory.Options opts = new BitmapFactory.Options(); opts.inScaled = true; opts.inDensity = 160; InputStream is; try { is = context.getAssets().open(imagesFolder + filename); } catch (IOException e) { return null; } try { bitmap = BitmapFactory.decodeStream(is, null, opts); } catch (IllegalArgumentException e) { return null; } return bitmap; }}
进阶版方案
简单版方案可以满足一些需求,而且不够完美,好多场景受限,假如我须要替换的部份是一个倒计时呢?如上图上面的让利券正式过期的那个文本是个倒计时,设计师须要倒计时运行上去的抖音的赞显示不出来的,但简单版的方案由于是生成静态贴图难以做到更新,所以简单版本的方案是还不错,但总感觉没有血肉,不够强壮有力!
成年人的世界为何不能全都要?我们要支持未来可能遇见的所有场景,我们要完美的支持点击,我们要完美的支持动态业务数据,我们也要完美的支持动态组件,我们要Lottie能像我们希望的那样支持我们的功能。
那就让我们把思路彻底打开,是否可以将占位贴图替换成原生的布局控件呢?也即是在渲染占位贴图的时侯直接换成渲染原生布局,这样动漫和原生布局就无缝衔接在一起
原理示例图
我们的选择场景覆盖业务逻辑动态布局点击交互扩充性
简单版
60%
支持
不支持
不支持
差
进阶版
100%
支持
支持
支持
好
和简单版方案做个对比就可以很容易作出选择
方案介绍核心原理
方案的核心原理是创建一个动态布局视口DynamicLayoutLayer,和Lottie上面支持的ImageLayer、TextLayer、CompostionLayer一样,由自己来实现勾画逻辑,之后在运行期间hook原动漫占位视口(ImageLayer),替换成DynamicLayoutLayer,占位视口上所有属性变换都代理到DynamicLayoutLayer上,进而实现无缝替换。
类图如下:
核心问题
要实现该方案须要解决其中几个核心的问题,首先要解决视口的同层渲染问题让替换的视口和原始占位视口在同一个层级进行渲染,就能实现无缝衔接,其次原始视口的动漫疗效也须要同步给替换的视口,这样作用在原始视口上的动漫变换疗效能够在替换视口上彰显,最后须要解决下点击交互风波和布局动态刷新的问题,能够完整的支持所有需求场景,下边会对每位核心问题做详尽方案剖析。
下文贴的代码均非即将代码,只做大致原理理解
Lottie的每位视口还会调用自身的draw来勾画到canvas上,假如要做到替换后实现同层渲染则也须要将native控件根据占位图层层级勾画到Lottie的canvas上,因而我们的解决方案就是将占位视口的勾画代理到DynamicLayoutLayer,将Lottie的画布传入,之后调用DynamicLayoutLayer的勾画逻辑将内容勾画到传入的画布中即可
示例代码:
static BaseLayer forModel( Layer layerModel, LottieDrawable drawable, LottieComposition composition) { switch (layerModel.getLayerType()) { case SHAPE: return new ShapeLayer(drawable, layerModel); case PRE_COMP: return new CompositionLayer(drawable, layerModel, composition.getPrecomps(layerModel.getRefId()), composition); case SOLID: return new SolidLayer(drawable, layerModel); case IMAGE: //判断是否是动态布局图层 是则替换成DynamicLayoutLayer if (isDynamicLayout(layerModel)) { return new DynamicLayoutLayer(drawable, layerModel); } return new ImageLayer(drawable, layerModel); case NULL: return new NullLayer(drawable, layerModel); case TEXT: return new TextLayer(drawable, layerModel); case UNKNOWN: default: // Do nothing L.warn("Unknown layer type " + layerModel.getLayerType()); return null; } }
public class DynamicLayoutLayer extends BaseLayer{ ...... @Override void drawLayer(Canvas canvas, Matrix parentMatrix, int parentAlpha) { //动态布局绘制 }}
替换后视口的层级问题解决了,而且视口上绑定的动漫也须要同步到替换视口上,这是我们须要解决的第二个困局,动漫的问题我们须要从Lottie动漫的原理来入手,须要了解两个概念帧时间轴和Matrix变换
帧时间轴
Lottie动漫数据是由无数个关键帧组成的,设计师在每一个关键帧上设置属性数据,则两个关键帧之间就是数据的变换,我把这个称做帧时间轴,Lottie动漫的原理就是随着帧轴运行时估算出当前帧的属性数据,再把数据设置给视口,通过每位视口在对应帧同步对应的属性数据进而达到动漫的疗效。
举个简单的事例,我在第1帧设置了一个缩放的关键帧,数据设置成100%,之后在第5帧上设置一个缩放关键帧,数据设置成50%,再在第10帧设置缩放关键帧,数据150%,则呈现下来的动漫疗效就是该视口从开始原始大小在5帧的时间内缩小到50%,再5帧的时间内从50%放大到150%,之后再动漫运行的时侯随着动漫浏览到的帧率估算当前帧的数据,例如第一帧的时侯数据为100%,之后浏览到第2帧的时侯估算出数据为90%,把数据设置给视口,以这种推每一帧都估算出自己的数据进行设置,串上去就产生的动漫疗效
Matrix变换
Matrix是一种矩阵变换,通常图象处理上会使用到,在Android中也有大量应用场景,我们熟知的View的一些属性变换疗效都是Matrix来实现的,通过Matrix的变换可以改变View的属性,例如缩放值、位移值、旋转角度等,而Lottie的动漫疗效也是使用Matrix数据变换来得到的,AE上面导入的数据会转换成一组Matix,在每帧渲染的时侯估算出对应的Matrix数据之后设置给layer,进而实现了视口的属性变换疗效,而视口就是组成Lottie动漫的基础元素,所有视口结合上去就是完整的Lottie动漫了
关于Matrix的相关知识点可自行学习抖音的赞显示不出来的,这儿只引入概念
通过对动漫原理的剖析我们要解决动漫同步的问题就很简单了,只须要将原先动漫中应用到占位视口上的基础数据和matrix变换数据全部代理给动态布局视口即可
示例代码:
//动态布局图层绘制void drawLayer(Canvas canvas, Matrix parentMatrix, int parentAlpha) { View view = getReplaceView(); //重点是下面这段代码,将matrix设置给画布,再将原生控件绘制到当前画布上 canvas.save(); canvas.concat(parentMatrix); view.draw(canvas);}
解决了以上两个问题,我们的方案大致完成了60%,但Lottie动漫的一个最大的痛点问题就是点击风波,大部份的Lottie动漫虽然没有动态的业务数据并且按键点击的需求是大机率会有的,而在之前我使用Lottie的时侯遇见点击的需求则直接在Lottie动漫之上对应位置添加一个虚拟的点击区域,是不是很粗糙暴力?那假如使用我们如今这个方案那点击风波是不是就不是问题了?
虽然还是有一点点小小的问题,由于我们的动态控件是替换占位视口的,动漫中会存在一些matrix的变换,变换后的控件位置就不是初始位置,也就是说你的matrix变换可能有位移或则缩放,致使点击区域错位,那这个问题如何解决呢?
虽然我们可以参考属性动漫,为何属性动漫缩放或则平移后点击区域也跟随调整了呢?虽然属性动漫的内部有做一个matrix的反向矫治,我们同样可以参考这块的实现对区域做一个矫治处理即可
示例代码:
private MotionEvent getTransformedMotionEvent(MotionEvent event, View child) { final float offsetX = mScrollX - child.mLeft; final float offsetY = mScrollY - child.mTop; final MotionEvent transformedEvent = MotionEvent.obtain(event); transformedEvent.offsetLocation(offsetX, offsetY); if (!child.hasIdentityMatrix()) { transformedEvent.transform(child.getInverseMatrix()); } return transformedEvent;}public final Matrix getInverseMatrix() { ensureTransformationInfo(); if (mTransformationInfo.mInverseMatrix == null) { mTransformationInfo.mInverseMatrix = new Matrix(); } final Matrix matrix = mTransformationInfo.mInverseMatrix; mRenderNode.getInverseMatrix(matrix); return matrix;}
支持以上3个功能就早已满足我们大部份日常使用的场景了,虽然Lottie设计之初就是给我提供一个动漫展示的框架,并不能支持各类订制和功能扩充,且他的生命周期则很明晰动漫执行到结束(非循环动漫),倘若动漫有130帧,那Lottie就是从第一帧开始渲染,到130帧渲染结束,但假如有超出这个生命周期的动态布局还须要有更新则如何处理呢?例如我们里面红包开下来让利券的说明上面的有效期不是静态的文本而是一个倒计时,那在Lottie浏览到最后一帧后这个倒计时控件就没有办法继续走下去了,由于驱动倒计时重画的是Lottie的画布,Lottie由于生命周期早已结束,画布不在继续刷新,所对应的驱动力就割断了,因而这些场景下我们应当如何去解决呢?
只需提供一个重画刷新插口给到控件自己去触发即可
示例代码:
/** * 请求重绘 */public void redraw() { LottieAnimationView lottieAnimationView = getLottieAnimationView(); lottieAnimationView.invalidate();}
最终疗效
最终疗效入右图(左原图&慢放)
方案的利润
我们的Lottie扩充方案对我们来说有两个特别大的利润
第一利润就是提效,假如没有这套方案,我们就得回归到使用最原生的代码来实现动漫了,效率之低经历过的同学都有感受,至于扩充方案具体提效多少则和动漫的复杂度成反比,越复杂疗效越好!
第二个利润就是对Lottie源码的“掌控”能力,这儿用了“掌控”一词其实有些托大,但确实只有把Lottie的实现原理全理解了能够对Lottie进行大刀阔斧的扩充,理解原理后我们对Lottie的一些问题都可以自行更改且还可以扩充更多的特点,例如让Lottie支持音频?甚至支持视频资源等一些更中级的能力!
后续计划
目前方案还有一些不太常见的场景不支持,例如动漫里嵌入一个滚动的列表,再例如动漫的分段浏览逻辑(适宜做互动小游戏),在后续开发中若果有碰到类似需求则会考虑把相关场景扩充支持下,我们也会同步把方案思路分享给你们,同时该方案也会相继在我们内部其他项目组中试用,后期迭代稳定成熟后也会有开源的计划。
hi,我是抖音电商的HD
抖音电商无线技术团队正在招贤纳士!我们是公司的核心业务线,这儿云集了各路前辈,也饱含了机会与挑战.伴随着业务的高速发展,团队也在快速扩张.欢迎诸位前辈加入我们,一起创造世界级的电商产品~
热招岗位:Android/iOS中级开发,Android/iOS专家,Java构架师,产品总监(电商背景),测试开发...大量HC等你来呦~
内部推荐请发简历至>>>我们的邮箱:hr.ec@kuaishou.com
袁记短视频热门业务教程网 顶: 59271踩: 6涓轰簡鎹変綇鏇村楂樻綔鍔涚敤鎴凤紝2024骞达紝SYNEXT灏嗙户缁己鍖栧鍟嗗搧鍗$殑鍔犵爜鎶栭煶涓氬姟涓嬪崟24灏忔椂锛屽苟瀵瑰晢鍝佸崱鐨勮惀杩愯繘琛岃皟鏁达紝閫氳繃鎺ㄥ嚭鏇村鐗╃編浠峰粔鐨勪骇鍝侊紝鍚稿紩鏇村娑堣垂鑰呭叧娉紝浠ュ疄鐜扮敓鎰忕殑闀挎晥缁忚惀銆侟/p>
鎹倝锛岀帇闆洴杩樻彁鍙婏細鈥滄姈闊崇數鍟嗗畼鏂规彁渚涗笓闂ㄧ殑鏈嶅姟浜哄憳涓庡簵瀹跺鎺ワ紝璁稿宸ヤ綔鑳芥洿杩呴€熷畬鎴愩€傚悗鍙板伐鍏锋彁渚涚殑鏁版嵁鐩存帴鎸囧钀ヨ繍宸ヤ綔锛屽皢浜轰负骞叉壈鐨勮鍥犻檷鍒版渶浣庛€傗€滭/p>
鎶栭煶鐢靛晢鐨勬敮鎸佽繙涓嶆杩欎箞锛孲YNEXT鐨勬垚鍔熻繕涓庡晢鍝佸崱鍏嶄剑鏂版斂瀵嗗垏鐩稿叧銆?023骞?鏈堬紝鎶栭煶鐢靛晢鎺ㄥ嚭浜嗏€滃晢鍝佸崱鍏嶄剑鈥濇斂绛栵紝骞跺湪10鏈堝崌绾т负鈥滃疄鏃跺厤浣b€濓紝鍗冲彧瑕佹湰鏈堝畬鎴愬厤浣g殑鍟嗗搧鍗¤鍗曪紝涓嬩釜鏈堢粨绠楁椂灏卞彲浠ョ洿鎺ュ厤浣c€傚湪甯稿勾銆佸疄鏃跺厤浣g殑鏂版斂鏂借涓嬶紝2023骞达紝骞冲彴鍏嶄剑閲戦绱杈?0浜匡紝鍗曚釜搴楀鏈€楂樺厤浣i噾棰濊揪1260浜垮厓銆傝鏂版斂瀹炲疄鍦ㄥ湪鍦扮粰涓庡簵瀹舵敮鎸侊紝閲婃斁鍑虹敓鎰忛┍鍔ㄥ姏锛屼績浣跨敓鎰忛檷鏈鏁堛€侟/p>
宸︽粦鏌ョ湅鍥剧墖
閫氳繃鍟嗗搧鍗″疄鏃跺厤浣o紝搴楀钀ヨ繍鎶曞叆鎬ュ墽鍏嶉櫎锛屽緱浠ュ皢鏇村璧勯噾鎶曟斁鍒颁骇鍝佽惀杩愪腑锛屽疄鐜版洿楂樺搧璐ㄣ€佹洿骞挎笭閬撳拰鏇村缓绔嬪晢涓氬伐鍏风殑鐩爣锛屼粠鑰岄噴鏀惧晢鍝佸崱鏇村ぇ鐨勬綔鍔涖€傛嵁鎮夛紝鏈変簺搴楀灏变細閫氳繃鎶樻墸銆佺孩鍖呯瓑鏂规硶灏嗚繖绗旂粡璐圭敤浜庢洿濂藉湴鏈嶅姟娑堣垂鑰咃紝浣垮晢鍝佸崱鐨勭孩鍒╂晥搴旀墠鑳藉欢缁洿闀挎椂闂淬€侟/p>
宸︽粦鏌ョ湅鍥剧墖
璞亾涔冲搧瀹樻柟鏃楄埌搴楋紙涓嬭竟绠€绉扳€滆鲍閬撯€濓級灏辨槸绱ч殢鎶栭煶鐢靛晢骞冲彴椋庡悜锛岃緝鏃╁叆灞€鍟嗗搧鍗℃壘鍒扮敓鎰忓彂灞曟柟鍚戠殑鍏稿瀷妗堜緥銆傚搧鐗岄€氳繃鍟嗗搧鍗$粡钀ユ墿鍏呴攢鍞笭閬擄紝琛ヨ冻鈥滀汉鎵捐揣鈥濈殑閾捐矾锛屼粠鑰屾帰姹傚嚭鏇村骞跨殑澧為暱绌洪棿銆侟/p>
鈥滃湪鍒濇湡锛屾垜浠殑鎶曟斁绛栫暐鐫€閲嶄簬鐩存挱鍜岀煭瑙嗛鐨勮耽鍒╋紝鑰屽晢鍝佸崱浣滀负涓€涓浉瀵硅緝鏂扮殑褰版樉鏂瑰紡骞舵湭琚厖鍒嗚€冭檻銆備絾鏄?strong>鎶栭煶涓氬姟涓嬪崟24灏忔椂锛屽綋鎴戜滑瀵熻鍒板钩鍙板鍟嗗搧鍗$殑娉ㄩ噸锛屼究閫愭笎鍔犲己瀵瑰晢鍝佸崱鐨勬姇鏀撅紝閫氳繃鍐呭鍦恒€佽揣鏋跺満鎵撻€氾紝淇冧娇鍟嗗搧鍗$殑鐖嗗厜涓嬮檷锛屾潈閲嶆彁楂橈紝浠庤€屼績杩涘晢鍝佸崱甯︽潵鐨勯攢閲忕垎鍙戙€傗€濊鲍閬撶數鍟嗕笟鍔¤礋璐d汉鏇瑰溅鏂硅〃绀猴紝鍟嗗搧鍗′綔涓鸿仈鎺ョ敤鎴峰拰鍟嗗搧鐨勭航甯︼紝閫氳繃涓€у寲鎺ㄨ崘銆佸仠鐣欐椂闂寸瓑鏁版嵁鎸栨帢锛屾垚鍔熷疄鐜颁簡鈥滀汉鎵捐揣鈥濈殑绮惧噯鍖归厤銆侟/p>
鍦ㄨ繖涓€鎴樼暐璋冩暣涓嬶紝璞亾涔冲搧鍦?019骞撮攢鍞涓嶈冻100涓囩殑鍩虹涓婏紝浜?023骞磋繀閫熶笅闄嶈嚦杩?浜匡紝鍏朵腑鍟嗗搧鍗¤础鐚殑GMV鏁板€煎崰鏁翠綋浜у€肩殑30%銆侟/p>
鏇瑰溅鏂归璁★紝鍟嗗搧鍗′細鍦?024骞寸户缁垚涓哄搧鐗岄攢鍞涓嬮檷鐨勪富瑕佹帹杩涘姏銆備笌姝ゅ悓鏃讹紝涓轰簡鏇村ソ鍦拌惀杩愬晢鍝佸崱锛岃鲍閬撲钩鍝佸洟闃熻鍒掍笓闂ㄧ粍寤轰竴涓皬鍥㈤槦锛屾棬鍦ㄤ簬鍟嗗搧鍗$殑鎿嶇洏涓庤€曡€樸€侟/p>
杩欑閮藉厖鍒嗗嵃璇佷簡鍟嗗搧鍗$殑浼樺娍锛岃€岃繖涓€浼樺娍鐨勫叧閿鍏堝湪浜庝俊鎭紶閫掓晥鐜囥€傚湪蹇妭濂忕殑绀句氦濯掍綋鐜涓紝鐢ㄦ埛甯稿父甯屾湜杩呴€熻幏鍙栨墍闇€淇℃伅銆傚晢鍝佸崱浠ョ畝绾﹁€岀洿瑙傜殑鏂规硶鍛堢幇鍟嗗搧鐗规€э紝鍔犱箣涓庢悳绱㈡剰鍥鹃珮搴﹀鍚堬紝鏃㈣兘鏅鸿兘寮曟祦锛岄檷浣庝骇鍝佺垎鍏夐噺锛屽張鑳介珮鏁堣浆鍖栵紝鎻愰珮鏁翠綋钀ヨ繍鏁堢巼銆傚叾娆★紝骞冲彴鏂版斂涔熶负搴楀鎸囨槑浜嗙敓鎰忓彂灞曟柟鍚戙€傛垚鍔熻€呯殑缁忛獙琛ㄦ槑锛屽ス浠€氳繃鎻愭棭甯冨眬鍟嗗搧鍗″偍澶囧姏閲忥紝骞跺湪瀹炴椂鍏嶄剑鏂版斂鐨勬敮鎸佷笅杩涜瀹炴搷璁粌锛屽崰棰嗘洿澶氱敓鎰忔満浼氾紝濂界殑缁撴灉鑷劧楠ょ劧鑰岃嚦銆侟/p>
灏忓伐鍏锋€庝箞鎾姩澶т笅闄岦/p>
杩欎箞锛屽湪闈㈠鍟嗗搧鍗¤繖涓柊鐨勬祦閲忓叆鍙f椂锛屽簵瀹跺埌搴曡鎬庝箞鎺屾彙鏈轰細锛熶簨瀹炰笂锛岃澶氬簵瀹堕兘閫氳繃绉瀬甯冨眬鍟嗗搧鍗★紝瀹炵幇涓氬姟鐮村眬鍜岀敓鎰忎笅闄嶏紝杩欑鎴愬姛缁忛獙涓哄叾浠栧簵瀹跺仛濂藉晢鍝佸崱缁忚惀鎻愪緵浜嗘湁鍔涚殑鍊熼壌銆侟/p>
婧湪婧愬畼鏂规棗鑸板簵锛堜笅杈圭畝绉扳€滄邯鏈ㄦ簮鈥濓級鐨勮〃鐜板氨鎰堝姞浜溂銆?023骞村弻鍗佷竴澶т績鏈熼棿锛岃鍝佺墝鍦ㄦ姈闊崇數鍟嗙幆姣斾笅闄嶈揪鍒?4%锛屾帓琛屽熀鏈ǔ瀹氫繚鎸佸湪鏂伴攼鍥借揣鍝佺墝No.1锛岀編濡嗗叏琛屼笟TOP10锛屽叾澶氭鐜嬬墝浜у搧锛屼害鍦ㄦ棩甯稿父骞寸ǔ灞呮姈闊冲晢鍩庢帓鍚嶆姒滈銆侟/p>
婧湪婧愬娆剧帇鐗屼骇鍝佸父骞寸ǔ灞呮姈闊虫棣朁/p>
杩欐槸涓€瀹跺湪2019骞村垱绔嬪苟涓撴敞浜庡叏鑲岃偆鏁忔劅鑲屼笓涓氭姢鐞嗙殑鍝佺墝銆傚郊鏃讹紝瀵逛簬鍦ㄥ垱绔嬩箣鍒濆氨鍦ㄧ嚎涓婅繘琛屽叏娓犻亾甯冨眬鐨勬邯鏈ㄦ簮鑰岃█锛屾姈闊崇數鍟嗚繖鏍峰叿鏈夎冻澶熻摑娴峰闀跨┖闂寸殑骞冲彴锛岃兘甯姪鍝佺墝鑾峰緱杩呯寷涓嬮檷銆侟/p>
2020骞达紝婧湪婧愮暀蹇冨埌鎶栭煶骞冲彴闆嗚仛鐫€澶ч噺鐨勬椿璺冨勾闈掍汉鐢ㄦ埛锛屼笌鍝佺墝鐢ㄦ埛鐢诲儚鍗佸垎鍖归厤锛屼簬鏄晱閿愬湴鎶撶墷澧為噺杩呴€熺殑骞冲彴鏈洪亣锛屼笌骞冲彴鍏卞悓蹇€熸垚闀裤€侟/p>
鍦ㄥ叆椹绘姈闊崇數鍟嗗悗锛屾邯鏈ㄦ簮鍦ㄦ寔缁爺鍒躲€佷笂绾垮ソ璐х殑鍩虹涓婏紝涔熻繘琛屼簡鍏ㄥ煙鐨勭瀛﹀竷灞€锛屽仛濂芥棩甯歌惀杩愶紝涓虹敤鎴峰甫鏉ユ洿濂界殑浣撻獙銆傚晢鍝佸崱灏辨槸閲嶈鐨勭粍鎴愰儴浠戒箣涓€銆傚搧鐗岃寰楃浉杈冧簬鐩存挱鐢靛晢鐨勫嵆鏃舵€э紝鍟嗗搧鍗$垎鍏夊叿鏈夐暱灏炬晥搴旓紝缁欎笌鐢ㄦ埛鈥滈殢鏃堕€涒€濄€佲€滈殢鏃朵拱鈥濈殑24灏忔椂璐墿鑷敱銆侟/p>
缁忚繃甯稿勾鐨勫疄璺碉紝婧湪婧愯繕鎬荤粨鍑哄晢鍝佸崱缁忚惀鏂瑰紡璁猴細涓ょ偣鏋佷负鍏抽敭锛屼竴鏄鏈夊ソ璐э紝鍙湁濂界殑浜у搧浣撻獙鑳藉甯︽潵娑堣垂鑰呭彛纰戝拰鍥炶喘锛屾敮鎾戝搧鐗屽父骞村彂灞曘€傚洜鑰屾邯鏈ㄦ簮閮芥槸浠ョ帇鐗屼骇鍝佸仛鍩虹鏀拺锛屼緥濡傚父骞撮湼姒滅涓€鐨勭編鐧藉幓鏂戠帇鐗屼骇鍝佹剤鍒涙湪绮惧崕锛岄拡瀵瑰共鏁忚倢鐨勩€佷粠鍒涚珛浼婂鐣呴攢鑷充粖鐨勬邯鏈ㄦ簮娌规鑺变钩娑蹭互鍙婇拡瀵规补鏁忚倢鐨勫眰瀛旇弻涔虫恫绛夈€備簩鏄墡瀹炲仛濂借揣鏋惰惀杩愮殑鍩烘湰鍔熴€傞€氳繃浼樺寲鎼滅储鏍囬銆佸晢鍩庢帹鑽愬叆姹狅紝鍋氬ソ搴楅潰瀹惰锛岀敤濂藉簵闈細鍛樸€佺簿缁嗗寲钀ヨ繍绛夌浉鍏冲姩浣滐紝瀹炵幇鐢熸剰鎸佺画涓嬮檷銆侟/p>
2024骞达紝婧湪婧愪篃甯屾湜杩樿兘鎹変綇鎶栭煶鐢靛晢鍟嗗搧鍗¤繖涓柊鐨勬満閬囩獥鍙o紝涓哄搧鐗屽湪鎶栭煶鐢靛晢鐨勫彂灞曟墦涓嬪畾蹇冧父銆侟/p>
涓轰簡鍏呭垎鍙戞尌鍟嗗搧鍗$殑娼滃姏锛屾湁鐨勫簵瀹跺氨浼氬湪鍟嗗搧鍗℃爣棰樹笂涓嬭冻宸ュか銆備竴涓患鍚堣€屾湁鏁堢殑绛栫暐鏄患鍚堣繍鐢ㄩ暱灏捐瘝銆佷富璇嶃€侀鍗囪瘝鍜岃摑娴疯瘝锛屼互纭繚鏍囬鏃㈣创鍒囧張鍚稿紩鐪肩彔銆傞暱灏捐瘝椤昏鎻愪緵鏇翠负璇﹀敖鐨勫晢鍝佹弿杩帮紝鎻愬崌鍟嗗搧涓庣敤鎴峰疄闄呴渶姹傜殑鍖归厤搴︼紱鍘熻搴斿綋绠€娲佽€屽叿浣擄紝纭繚鐢ㄦ埛鍦ㄤ竴鐬ヤ箣闂寸悊瑙e晢鍝佺殑涓昏鐗圭偣鍜岀被鍒紱鏆存定璇嶅垯搴斿弽鏄犲綋鍓嶅競鍦虹殑鐑偣鍜屾祦琛岃秼鍔匡紝鎷挎潵鍚稿紩鏇村鍏虫敞銆侟/p>
铏界劧锛屽晢鍝佸崱闄や簡鏄媺鏂扮殑鏈夋晥杞戒綋锛屾洿鏄ǔ瀹氭祦閲忋€佸讥琛ョ洿鎾拰鐭棰戝姩鎬佹祦閲忕殑鍏抽敭鐜妭銆傚浜庣敓浜у瀷搴楀杩欑被涓嶆搮闀垮仛鍐呭鐨勫簵瀹舵潵璇达紝鍟嗗搧鍗℃彁渚涗簡鍙︿竴绉嶉珮鏁堢垎鍏変骇鍝佺殑褰㈠紡銆傚晢鍝佸崱鍙互灏嗚繖绉嶅晢鍝佺洿鎺ュ憟鐜板湪鐢ㄦ埛闈㈠墠锛屽厖鍒嗗彂鎸ユ棦鏈夎揣婧愪紭鍔匡紝鎵惧埌鏇村骞跨殑甯傚満銆侟/p>
鍙互鐪嬪嚭鏃犺鏄摢浜涚被鍨嬬殑搴楀锛岄兘鏈夋満浼氶€氳繃鍟嗗搧鍗¤繖涓皬宸ュ叿鎾姩澶т笅闄嶃€傚簵瀹朵滑閫氳繃鎸佺画浼樺寲鍟嗗搧鍗★紝闄や簡鑳藉湪骞冲彴鍐呰幏寰楅珮鐖嗗厜锛屽氨鑳藉疄鐜伴珮杞寲銆侟/p>
鍟嗗搧鍗¤鏇村鍝佺墝鍦ㄦ姈闊崇數鍟嗙殑鐢熸剰椋欏崌鍒版柊鐨勯珮搴︺€?024骞达紝鎶栭煶鐢靛晢灏嗛『鐫€鍟嗗搧鍗′环閽卞姏鏂瑰悜杩涜杩唬锛屾帹鍔ㄤ綆浠锋帹鎵嬬瓑宸ュ叿浠诲姟涓婄嚎锛屾彁楂樿揣鏋跺満绔炰簤浼樺娍锛屽府鍔╁簵瀹舵洿鐏垫椿鍦板簲瀵瑰競鍦洪渶姹傦紝鏇寸瀛﹀湴杩涜瀹氫环銆侟/p>
杩欎篃鎰忓懗鐫€锛屾姈闊崇數鍟嗙敓鎬佸皢鎸佺画婕斿寲锛屼负搴楀鎻愪緵鏇村鍒涙柊鐨勮惀閿€宸ュ叿鍜屾洿寮烘倣鐨勭珵浜夊姏銆侟/p>
END
评论专区