学不动也要学!ViewPager2 新特性

3ef5461af963988740c9e526f3b8c3c5.gif

作者 | tech-bus.丹卿

来源 | 程序员八十

前 言

浏览Android开发者官网的时候,发现Google竟然曾经悄悄推出过一个新的控件:ViewPager2;从名字上看就知道是ViewPager的升级版本,看了下推出这个控件的时间,早在2019年2月7号Google就已经发布了,之后再进行一波迭代更新,在2019年11月20号进行了正式的发布;

可以关联下Google曾经在2018年推出的Jetpack,旨在帮助开发者轻松构建更稳定健壮及可维护的Android开发生态解决方案,就可想而知此次推出ViewPager2,算是Google往被寄予厚望的Jetpack全家桶中又增添一员猛将;既然是升级版,相比ViewPager,它究竟有哪些新功能和特性呢?让我们接着往下看。

一、ViewPager2的新特性

ViewPager2新特性

  • 基于RecyclewView实现。这意味着ViewPager2将继承RecyclewView的优点,同样完全支持RecyclerView的相关配置功能

  • 支持垂直方向滑动。只需要一个参数就可以改变滑动方向;

  • 支持关闭用户输入和模拟用户滑动。通过设置setUserInputEnabled()来设置是否禁用用户滑动行为;通过fakeDragBy(float offsetPx)模拟用户滑动页面;

  • 支持多个PageTransformer

  • 支持DiffUtil,通过添加数据集合实现局部数据刷新和Item动画。

  • 支持RTL布局

和ViewPager进行对比

ViewPager2相比ViewPager做了哪些改变呢,下面对不同点进行了罗列:

  • 采用registerOnPageChangeCallback() 代替addPageChangeListener()监听页面的变化

  • 因为ViewPager2.java这个类被申明为fianl,无法继承它进行二次改造,不过可以copy一份进行修改加工

  • 采用FragmentStateAdapter 替代FragmentStatePagerAdapter,采用 RecyclerView.Adapter 替代PagerAdapter;

  • offScreenPageLimit新参数 新体验

二、Android ViewPager2的使用

ViewPager2 位于 androidx 包下,也就是它不像 ViewPager 一样被内置在系统源码中。因此,使用 ViewPager2 需要额外的添加依赖库。

另外,android support 中不包含 ViewPager2,也就是要使用 ViewPager2 必须迁移到 androidx 才可以。

① 添加依赖

目前ViewPager2的最新稳定版本是1.0.0。

dependencies {implementation "androidx.viewpager2:viewpager2:1.0.0"}

② 在XML文件中申明

<androidx.viewpager2.widget.ViewPager2android:id="@+id/view_pager"android:layout_width="match_parent"android:layout_height="match_parent"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent" />

③ 自定义Adapter

ViewPager2 是用 RecyclerView来实现的,因此它的 Adapter 其实就是 RecyclerView 的 Adapter。

class MyAdapter extends RecyclerView.Adapter<MyAdapter.PagerViewHolder> {private List<Integer> mList;public PagerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_page, parent, false);return new PagerViewHolder(view);}@Overridepublic void onBindViewHolder(@NonNull PagerViewHolder holder, int position) {holder.bindData(position);}@Overridepublic int getItemCount() {return mList.size();}public void setList(List<Integer> list){this.mList = list;}class PagerViewHolder extends RecyclerView.ViewHolder {private TextView mTextView = itemView.findViewById(R.id.tv_text);private String[] colors = new String[]{"#CCFF99", "#41F1E5", "#8D41F1", "#FF99CC"};public PagerViewHolder(@NonNull View itemView) {super(itemView);}private void bindData(int index) {mTextView.setText(index);mTextView.setBackgroundColor(Color.parseColor(colors[index]));}}}

item_page布局文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center"><TextViewandroid:id="@+id/tv_text"android:background="@color/colorPrimaryDark"android:layout_width="match_parent"android:layout_height="280dp"android:gravity="center"android:textColor="#ffffff"android:textSize="22sp" /></LinearLayout>

④ 绑定ViewPager和Adpater

ViewPager2 viewPager2 = findViewById(R.id.view_pager);MyAdapter myAdapter = new MyAdapter();myAdapter.setList(data)viewPager2.setAdapter(myAdapter);

通过上述接入,就可以完成一个ViewPager滑动页简单的效果,如下:

7471d27ac20bae402e145e57253acae1.gif

⑤ 设置竖向滑动

只需要一行代码就能设置ViewPager2进行竖向方向的滑动:

viewPager2.setOrientation(ViewPager2.ORIENTATION_VERTICAL);

而这一点,如果是换做之前的ViewPager是比较难达到的效果,可以来看下效果:

020ff9c5679da177e0e770bdadfec642.gif

⑥ 页面滑动监听事件

上面说到viewPager2监听页面滑动只需要重写我们需要的方法即可

viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {@Overridepublic void onPageSelected(int position) {super.onPageSelected(position);}});

⑦ 禁止用户滑动和模拟用户滑动

涉及 API:setUserInputEnabled() 与 fakeDragBy()。

我们知道,在使用 ViewPager 的时候想要禁止用户滑动需要重写 ViewPager 的 onInterceptTouchEvent()。而 ViewPager2 被声明为了 final,我们无法再去继承 ViewPager2。

那么我们应该怎么禁止 ViewPager2 的滑动呢?其实在 ViewPager2 中已经为我们提供了这个功能,只需要通过 setUserInputEnabled() 即可实现。

viewPager2.setUserInputEnabled(false);

同时 ViewPager2 新增了一个 fakeDragBy() 的方法。通过这个方法可以来模拟拖拽。在使用 fakeDragBy() 前需要先 beginFakeDrag() 方法来开启模拟拖拽。

fakeDragBy() 会返回一个 boolean 值:

true 表示有 fake drag 正在执行;false 表示当前没有 fake drag 在执行。我们通过代码来尝试下:

private void fakeDragBy(ViewPager2 viewPager2) {viewPager2.beginFakeDrag();if (viewPager2.fakeDragBy(100f)) {viewPager2.endFakeDrag();}}

需要注意到是 fakeDragBy() 接受一个 float 的参数,当参数值为正数时表示向前一个页面滑动,当值为负数时表示向下一个页面滑动。

下面来看下效果图:

0d8ad00ae15c94ad52ed87ee2401ab0d.gif

演示图中禁止了用户输入,通过按钮点击可以模拟用户滑动。

⑧ offScreenPageLimit()

在viewpager中也可以设置预加载页面参数,但是就算我们去设置了0,ViewPager的内部还是会强制改成,这也是被广大开发者诟病的地方;

而在ViewPager2中对这点进行了优化,可以通过源码发现:

# VewPager2private @OffscreenPageLimit int mOffscreenPageLimit = OFFSCREEN_PAGE_LIMIT_DEFAULT;/*** Value to indicate that the default caching mechanism of RecyclerView should be used instead* of explicitly prefetch and retain pages to either side of the current page.* @see #setOffscreenPageLimit(int)*/public static final int OFFSCREEN_PAGE_LIMIT_DEFAULT = -1;/** @hide */@SuppressWarnings("WeakerAccess")@RestrictTo(LIBRARY_GROUP_PREFIX)@Retention(SOURCE)@IntDef({OFFSCREEN_PAGE_LIMIT_DEFAULT})@IntRange(from = 1)public @interface OffscreenPageLimit {}

可以看到,将默认预加载页面数量设置为默认值-1,这里可以理解为不进行页面预加载操作;而且如果要设置预加载页面数量,可以通过设置setOffscreenPageLimit值来进行赋值,注意这里将其注解标注为大于等于1;

public void setOffscreenPageLimit(@OffscreenPageLimit int limit) {if (limit < 1 && limit != OFFSCREEN_PAGE_LIMIT_DEFAULT) {throw new IllegalArgumentException("Offscreen page limit must be OFFSCREEN_PAGE_LIMIT_DEFAULT or a number > 0");}mOffscreenPageLimit = limit;// Trigger layout so prefetch happens through getExtraLayoutSize()mRecyclerView.requestLayout();}

下面就让我们看下设置不同的mOffscreenPageLimit数量会有啥不同的效果:

首先我们在 ViewPager 中添加多个 Fragment,并且 setOffscreenPageLimit() 使用默认值,然后再 Fragment 声明周期中打印出日志,代码不再贴出,直接看日志打印的内容:

7ba7dd0d2ea0c066d48e42da494940f7.png

可以看到只有第一个fragment初始化了,那么当我们滑动到下个fragment,看下日志:

3ca90032c7796f9fe21dba372a7e060a.png

看到只有当滑动到第二个fragment时候,页面才开始加载;因此当采用默认值-1时,滑动过程中不会发生预加载

接下来我们将 offscreenPageLimit 值改为 1,再来看下输出日志:

d796c084d71f7b48d3cc9170a3616d67.png

此时可以看到 offscreenPageLimit 设置为 1 后,会预加载进来一个页面,和 ViewPager 几乎是一样的效果。

总之,ViewPager2 对于 ViewPager 的预加载机制做了优化,使得体验上变得更好。

看到这里,很多人都会觉得,就这就这?ViewPager2难道只多了这么点功能?别急,下面这个新动效才是亮点;

三、PageTransformer

ViewPager2 的 Transformer 功能相比于 ViewPager 有了很大的扩展。

ViewPager2 不仅可以通过 PageTransformer 用来设置页面动画,还可以同时添加多个 PageTransformer。接下来我们就来看看 ViewPager2 的 PageTransformer 吧!

首先介绍一下 CompositePageTransformer

从名字上可以看出,它是一个组合了的PageTransformer,其实CompositePageTransformer实现了 PageTransformer 的接口,内部维护了一个 PageTransformer的List集合;

那么看看如何使用这个CompositePageTransformer

CompositePageTransformer compositePageTransformer = new CompositePageTransformer();compositePageTransformer.addTransformer(new ScaleInTransformer());compositePageTransformer.addTransformer(new MarginPageTransformer(10));viewPager2.setPageTransformer(compositePageTransformer);

上面代码中,我们给CompositePageTransformer设置了一个自定义页面缩放的ScaleInTransformer和一个页边距的MarginPageTransformer,可以看下效果:

     73f380065480dffd41758f90ff860b8a.gif

自定义页面缩放的ScaleInTransformer代码如下:

class ScaleInTransformer implements ViewPager2.PageTransformer {static final float DEFAULT_MIN_SCALE = 0.85f;static final float DEFAULT_CENTER = 0.5f;@Overridepublic void transformPage(@NonNull View view, float position) {view.setElevation(-abs(position));int pageWidth = view.getWidth();int pageHeight = view.getHeight();view.setPivotY((pageHeight / 2));view.setPivotX((pageWidth / 2));if (position < -1) {view.setScaleX(DEFAULT_MIN_SCALE);view.setScaleY(DEFAULT_MIN_SCALE);view.setPivotX(pageWidth);} else if (position <= 1) {if (position < 0) {float scaleFactor = (1 + position) * (1 - DEFAULT_MIN_SCALE) + DEFAULT_MIN_SCALE;view.setScaleX(scaleFactor);view.setScaleY(scaleFactor);view.setPivotX(pageWidth * (DEFAULT_CENTER + DEFAULT_CENTER * -position));} else {float scaleFactor = (1 - position) * (1 - DEFAULT_MIN_SCALE) + DEFAULT_MIN_SCALE;view.setScaleX(scaleFactor);view.setScaleY(scaleFactor);view.setPivotX(pageWidth * ((1 - position) * DEFAULT_CENTER));}} else {view.setPivotX(0f);view.setScaleX(DEFAULT_MIN_SCALE);view.setScaleY(DEFAULT_MIN_SCALE);}}}

viewpager2一屏多页的实现

查看google官方文档,可以看到官方实现一屏多页给出的代码是通过给recyclerview设置padding来实现的,代码如下:

RecyclerView recyclerView = (RecyclerView) viewPager2.getChildAt(0);int padding = 20;recyclerView.setPadding(padding, 0, padding, 0);recyclerView.setClipToPadding(false);CompositePageTransformer compositePageTransformer = new CompositePageTransformer();compositePageTransformer.addTransformer(new ScaleInTransformer());compositePageTransformer.addTransformer(new MarginPageTransformer(10));viewPager2.setPageTransformer(compositePageTransformer);

最后来看下效果:

0b237c8458acc8b43b498b8ba5bc6650.gif

四、Fragment中如何使用ViewPager2

上文讲述到在 ViewPager2 中采用 FragmentStateAdapter 代替了原先的 FragmentStatePagerAdapter,那么接下来看下如何搭配Fragment去使用ViewPager2

4.1 xml布局文件中添加ViewPager2

<androidx.viewpager2.widget.ViewPager2android:id="@+id/vp_fragment"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_above="@id/rg_tab" />

4.2 实现 FragmentStateAdapter

要使用FragmentStateAdapter最好的方式就是去自定义一个自己的Adapter,让我们来看下代码:

class CustomAdapterFragmentPager extends FragmentStateAdapter {final int PAGE_HOME = 0;final int PAGE_FIND = 1;final int PAGE_INDICATOR = 2;final int PAGE_OTHERS = 3;public CustomAdapterFragmentPager(@NonNull FragmentActivity fragmentActivity) {super(fragmentActivity);}@NonNull@Overridepublic Fragment createFragment(int position) {switch (position) {case PAGE_HOME:return HomeFragment.getInstance();case PAGE_FIND:return PageFragment.getInstance();case PAGE_INDICATOR:return IndicatorFragment.getInstance();case PAGE_OTHERS:return OthersFragment.getInstance();default:return EmptyFragment.getInstance();}}@Overridepublic int getItemCount() {return 4;}}

上述代码覆写了createFragment和getItemCount方法,可以看到其实和FragmentStatePagerAdapter做的事情差不多;

4.3 ViewPager2设置FragmentStateAdapter

初始化完ViewPager2和FragmentStateAdapter之后,最后一步就是给ViewPager设置上adapter,代码如下:

viewPager2.setAdapter(new CustomAdapterFragmentPager(this));viewPager2.setOffscreenPageLimit(3);viewPager2.setUserInputEnabled(false);

五、TabLayout和ViewPager2

TabLayout在平时开发工作中出现的频率也不算低了,经常会用来和ViewPager一起搭配使用,那么在TabLayout中如何搭配使用ViewPager2呢?

和原有的ViewPager不同,不能直接通过setViewPager来进行vp的设置;在ViewPager2中需要用到一个控件 TabLayoutMediator,这个类是在 material-1.2.0 中新增的一个类,目前 material 包的最新版本是 1.2.0-alpha03,添加依赖如下:

implementation 'com.google.android.material:material:1.2.0-alpha03'

需要传入三个参数去构造 TabLayoutMediator,第一个参数为 TabLayout;第二个参数为 ViewPager2;第三个参数是 TabConfigurationStrategy,这是一个接口,里面需要实现一个方法, onConfigureTab(@NonNull TabLayout.Tab tab, int position),第一个参数是当前的tablayout,第二个是当前的位置:

public interface TabConfigurationStrategy {/*** Called to configure the tab for the page at the specified position. Typically calls {@link* TabLayout.Tab#setText(CharSequence)}, but any form of styling can be applied.** @param tab The Tab which should be configured to represent the title of the item at the given*     position in the data set.* @param position The position of the item within the adapter's data set.*/void onConfigureTab(@NonNull TabLayout.Tab tab, int position);}

通过构造TabLayoutMediator,我们就可以将tablayout和viewpager2搭配起来使用了:

new TabLayoutMediator(tabLayout, viewPager2, new TabLayoutMediator.TabConfigurationStrategy() {@Overridepublic void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {tab.setText(titles[position]);}});

最后来看下效果图:

ede89598ff8e37371d799e60a1f0c9ba.gif

总结

在上述文章带领大家了解了一下ViewPager2的新特性,以及和ViewPager在开发使用中的区别;可以看到不管是从API、性能还是动效上,ViewPager2都是远远领先于ViewPager的,所以我认为未来有很大概率将会取代原来的ViewPager的;

看完这些,是时候将ViewPager2接入到你的项目里了!

参考

  • https://www.jianshu.com/p/bd70970600aa

  • https://my.oschina.net/zhongsm/blog/4653730?utm_source=tuicool

  • https://blog.csdn.net/weixin_42797048/article/details/88397381

b2a819943afe3f71262e27b92f6995c6.gif

052895596a18a3487412a947d06e653f.png

往期推荐

云计算到底是谁发明的?

从Docker的信号机制看容器的优雅停止

Redis会遇到的坑,你踩过几个?

低代码平台会带动企业的组织变革吗?

458c4a49d101ce7745ccb8c063b8a2e8.gif

点分享

f265940e9c2c66d5206792f82b970fe1.gif

点收藏

33d5b744051dfce3c36bb89f44b8945f.gif

点点赞

e87de9ad82be493d142259cec4368dac.gif

点在看

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/513005.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

方舟手游服务器受人无限物资,方舟生存进化BUG无限刷物资方法 | 手游网游页游攻略大全...

发布时间&#xff1a;2015-10-23壳是铁房子必须的材料,今天小编为大家带来一天1000壳的方法,不过高收益伴随着高风险,大家一定要小心,来看这篇熔岩洞生存攻略以及刷壳方法把. 右下角坐标(75 85 ...标签&#xff1a;游戏攻略 游戏秘籍 方舟生存进化发布时间&#xff1a;2016-04-…

闲鱼如何保障交易链路质量

简介&#xff1a; 闲鱼交易质量自动化 背景 闲鱼作为一款垂直交易社区APP&#xff0c;拥有复杂多样的业务场景&#xff1a;涉及c2c、回收寄卖、租房租赁、见面交易、验货担保等&#xff0c;复杂多变的交易模式。比如验货流程&#xff1a;涉及39个状态机节点横跨10应用系统涉及…

DevOps发布策略简介

简介&#xff1a; DevOps追求更短的迭代周期、更高频的发布。但发布的次数越多&#xff0c;引入故障的可能性就越大。更多的故障将会降低服务的可用性&#xff0c;进而影响到客户体验。所以&#xff0c;为了保证服务质量&#xff0c;守好发布这个最后一道关&#xff0c;阿里逐步…

存储引擎 boltdb 的设计奥秘?

作者 | 奇伢来源 | 奇伢云存储etcd 的存储etcd v3 是使用的持久化存储来存储它的 kv 数据&#xff0c;etcd 存储的是非常核心的元数据信息&#xff0c;所以最重要的是稳定。使用的是 boltdb 。下面说道说道这个 boltdb 。boltdb 是什么&#xff1f;boltdb 是一个非常出名的存储…

提升你的职场竞争力——“低代码开发师”来了!

简介&#xff1a; 最近&#xff0c;钉钉发布了低代码开发师能力图谱&#xff0c;引发业界的广泛关注 。现在低代码开发师&#xff08;初级&#xff09;认证已经启动。 最近&#xff0c;钉钉发布了低代码开发师能力图谱&#xff0c;引发业界的广泛关注 。 所谓的低代码开发其实…

mapreduce复制连接的代码_我的 Hive 为什么跑不起来/跑得慢?看看是不是少了这几行代码?...

《饮食男女》开头说&#xff1a;“人生不能像做菜&#xff0c;把所有的料都准备好了才下锅。”但做大数据挖掘不一样&#xff0c;MapReduce 不同于人生&#xff0c;一定要把准备工作做好了&#xff0c;才能顺利运行后面的步骤。如果你的 HiveQL 代码没毛病&#xff0c;却一运行…

数字化转型的路上,手握一张地图,但路还得自己走

简介&#xff1a; 本文作者来自于中国人寿保险股份有限公司研发中心&#xff0c;对企业数字化转型、云原生实践有比较资深的经验。以下内容整理自作者对最新出版的《阿里云云原生架构实践》的读后感。 作者&#xff5c;肖晟 ​ 本文作者来自于中国人寿保险股份有限公司研发中…

tp 数据库查询排序_怎么进行数据库分库分表?

一&#xff0c;数据切分关系型数据库本身比较容易成为系统瓶颈&#xff0c;单机存储容量、连接数、处理能力都有限。当单表的数据量达到1000W或100G以后&#xff0c;由于查询维度较多&#xff0c;即使添加从库、优化索引&#xff0c;做很多操作时性能仍下降严重。此时就要考虑对…

流利说统一可观察性平台实践

简介&#xff1a; 流利说利用日志服务SLS构建统一可观察性平台最佳实践 在线教育行业现状 随着 90 年代互联网的引入&#xff0c;在线教育产品也依托于互联网诞生。随着互联网技术的发展&#xff0c;在线教育产品也开 始了出现新的模式。在线教育从最初单纯的文字形式&#xf…

“CSDN 2021年度IT技术影响力之星评选”正式开启报名!

2021年&#xff0c;数字化转型正磅礴兴起&#xff0c;大批传统企业正在拥抱数字化&#xff0c;云计算、大数据、AI、5G应用能力正在变成企业的核心竞争力&#xff1b;核心技术正在崛起&#xff0c;在操作系统、数据库&#xff0c;依靠开源的力量&#xff0c;众多开发者背后的行…

java log4j logback jcl_Java 日志二三事

前言Java 拥有功能和性能都非常强大的日志库&#xff0c;但另一方面&#xff0c;Java 日志库依赖看起来丰富的让人眼花缭乱。相信大家或多或少都有这样的疑问&#xff0c;Log4j&#xff0c;SLF4J&#xff0c;Logback&#xff0c;Log4j2 这些日志框架我该如何选择&#xff1f;它…

一文了解EPaxos核心协议流程

简介&#xff1a; EPaxos&#xff08;Egalitarian Paxos&#xff09;作为工业界备受瞩目的下一代分布式一致性算法&#xff0c;具有广阔的应用前景。但纵观业内&#xff0c;至今仍未出现一个EPaxos的工程实现&#xff0c;甚至都没看到一篇能把EPaxos讲得通俗一点的文章。EPaxos…

低代码发展系列专访之五:低代码的最大价值点是“技术平民化”吗?

话题&#xff1a;低代码专访编辑 | LLBin前言&#xff1a;2019年开始&#xff0c;低代码爆火。有人认为它是第四代编程语言&#xff0c;有人认为它是开发模式的颠覆&#xff0c;也有人认为是企业管理模式的变革……有很多声音&#xff0c;社区讨论很热烈。CSDN随后展开低代码平…

梦幻跨服购买需要登录服务器未响应,梦幻西游8月4日定期维护公告:跨服购买限制放宽...

核心提示&#xff1a;法宝”系统新增“多套法宝切换”功能。亲爱的玩家朋友&#xff1a;为保证服务器的运行稳定和服务质量&#xff0c;《梦幻西游2》所有服务器将于2015年8月4日上午8:00停机&#xff0c;进行每周例行的维护工作。预计维护时间为上午8:00&#xff5e;9:45。如果…

深度技术揭秘 | 大促狂欢背后,如何有效评估并规划数据库计算资源?

简介&#xff1a; 经过“双11”、“618”这类互联网促销活动的验证&#xff0c;越来越多的互联网公司采用不定期营销活动来刺激消费&#xff0c;达到提升营收能力的目标。然而&#xff0c;在每一次业务狂欢的背后&#xff0c;如何科学地为促销活动准备相应的计算资源就变成了困…

学画画软件app推荐_今日推荐:拍照摄影APP之稀缺软件篇

你也许热衷拍摄或喜欢摄影&#xff0c;那么日常的拍摄主要的工具离不开手机&#xff0c;好的拍照摄影APP当然也必不可少。一个好的拍照软件更加重要&#xff0c;有时候市面上常用的拍照软件不能满足你特殊的拍摄手法&#xff0c;经常需要重新编辑或修改才能达到效果&#xff0c…

干货|一文读懂阿里云数据库Autoscaling是如何工作的

简介&#xff1a; 阿里云数据库实现了其特有的Autosaling能力&#xff0c;该能力由数据库内核、管控及DAS&#xff08;数据库自治服务&#xff09;团队共同构建&#xff0c;内核及管控团队提供了数据库Autoscaling的基础能力&#xff0c;DAS则负责性能数据的监测、Scaling决策算…

jq动态渲染后获取不到元素高度_浏览器的渲染机制

面试肯定会问到这个吧~So&#xff1a;再一次的屡屡浏览器的渲染机制~在渲染一开始会先从网络层获取请求文档&#xff08;HTML、XML&#xff09;的内容&#xff0c;然后再进行以下基本流程3.1 解析HTML 》 DOM树从HTML文本解析到HTML语法树&#xff0c;再解析到文档对象树&#…

数字时代的抉择,金蝶 EBC 的破局

今年 10 月&#xff0c;Gartner 发布了企业在 2021 年需要关注的重要战略科技趋势&#xff0c;其中“可组装的企业”一词引起热议。Gartner 认为原本为了提高效率而建立的静态业务流程很脆弱&#xff0c;在疫情的冲击下容易变得支离破碎&#xff0c;因此企业应具有不断重组与改…

自己动手从0开始实现一个分布式RPC框架

简介&#xff1a; 如果一个程序员能清楚的了解RPC框架所具备的要素&#xff0c;掌握RPC框架中涉及的服务注册发现、负载均衡、序列化协议、RPC通信协议、Socket通信、异步调用、熔断降级等技术&#xff0c;可以全方位的提升基本素质。虽然也有相关源码&#xff0c;但是只看源码…