Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

General solution of Android Multi-child view nesting in UI Series

2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >

Share

Shulou(Shulou.com)05/31 Report--

This article will explain in detail the general solution of Android multi-sub-view nesting in the UI series. The content of the article is of high quality, so the editor shares it for you to do a reference. I hope you will have a certain understanding of the relevant knowledge after reading this article.

1. Multi-child view nesting application background

Baidu App has implemented 2 sub-view nested scrolls in the 17-year version for Feed landing pages (webview presents article details + recycle presents Native comments). The principle is to provide a UI container (what we call a "ganged container") on the outer layer to handle WebView and Recyclerview consecutive nested scrolling.

At that time, the linkage container had a large restriction on sub-view, so it only supported WebView and Recyclerview for linkage scrolling, and the number only supported 2 sub-View.

With the advance of the component process, in order to facilitate the decoupling of various services, higher requirements are put forward for the linkage container, which needs to support any type and any number of sub-view for linkage scrolling, which is the general solution of multi-sub-view nested rolling described in this paper.

First, intuitively feel the Demo effect of nested scrolling of linked containers:

two。 Principle of nesting implementation of multi-child view

Like most custom controls, the linkage container also needs to handle the measurement, layout, and gesture processing of the sub-view. The measurement and layout are very simple for the scene of the linked container, and the gesture processing is relatively complex.

As can be seen from the demo effect, the linkage container needs to deal with the problem of nested sliding with sub-view. There are two ways to deal with nested sliding

Implementation of nested sliding based on NestedScrolling Mechanism of Google

Is the logic handled internally by the linkage container and the sub-view nesting sliding.

The linkage container in the earlier version of Baidu App is implemented in solution 2. The following figure shows the gesture processing flow of the linkage container in solution 2:

The author of the program 2 linkage container implementation code to do open source, interested students can refer to: https://github.com/baiduapp-tec/LinkageScrollLayout.

The realization of multi-child view nesting based on google NestedScrolling can save a lot of development, so the author adopts the first scheme to realize multi-child view nesting.

3. Core logic 3.1 Google nested sliding mechanism

Google introduced a set of NestedScrolling mechanism in Android 5.0.This mechanism breaks the understanding of the traditional event handling of Android, and handles nested scrolling according to the reverse event passing mechanism, which can be seen in the following figure:

There are many articles about NestedScrolling on the Internet. If you have not come into contact with NestedScrolling, you can refer to this article by Zhang Hongyang: https://blog.csdn.net/lmj623565791/article/details/52204039

3.2 Interface Design

In order to ensure the arbitrariness of the neutron view of the linkage container, the linkage container needs to provide a perfect interface abstraction for the sub-view to implement. The following figure shows the interface class diagram exposed by the associated container:

ILinkageScroll is the interface that must be implemented by the sub-view placed in the linkage container. If the linkage container finds that a sub-view does not implement the interface during initialization, it will throw an exception.

Two more interfaces will be involved in ILinkageScroll: LinkageScrollHandler and ChildLinkageEvent.

The method linkage container in the LinkageScrollHandler API is called actively when needed to notify the sub-view to complete some functions, such as whether the sub-view can be scrollable or the data related to the sub-view scroll bar.

The ChildLinkageEvent interface defines some event information for the sub-view, such as scrolling to the top or bottom of the sub-view. When these events occur, the sub-view actively calls the corresponding method, so that the linkage container will respond accordingly after receiving some events of the sub-view to ensure the normal linkage effect.

The above only briefly explains the function of the next interface. For students who want to know more about it, please refer to: https://github.com/baiduapp-tec/ELinkageScroll

Next, we analyze the details of gesture processing in the linkage container in detail. According to the type of gesture, the nested sliding is divided into two cases: 1. Scroll gesture; 2. Fling gesture

3.3 scroll gesture

First, the core code of scroll gesture processing is given:

The onNestedPreScroll () callback is a method in the NestedScrollingParent interface of the google nested sliding mechanism. When the child view scrolls, it first asks the parent view whether to consume the scrolling distance. The parent view decides whether and how much the scrolling distance is consumed according to its own situation, and puts the consumed distance into the array consumed, and the child view then determines its scrolling distance according to the contents of the array.

The code comments are more detailed, here is another overall explanation: by comparing the upper edge threshold of the sub-view and the scrollY of the linkage container, we deal with three kinds of scrolling cases under case.

Line 10, when scrollY = = topEdge, as long as the sub-view is not scrolled to the top or bottom, the sub-view consumes the scrolling distance normally, otherwise the linkage container consumes the scrolling distance, and notifies the sub-view of the consumed distance through the consumed variable, and the sub-view will determine its sliding distance according to the contents of the consumed variable.

Line 17, when scrollY > topEdge, that is to say, when the touching sub-view head has slipped out of the linkage container, if the finger slides up, the sliding distance is all consumed by the linkage container, and if the hand points down, the linkage container will consume part of the distance first, and when the scrollY of the linkage container reaches topEdge, the remaining sliding distance will be continued by the sub-view.

Line 32, when scrollY < topEdge is similar to the previous line 17 judgment, there is not much explanation here. The flow chart of scroll gesture processing is as follows:

3.4 fling gesture

The general idea of the linkage container to deal with the fling gesture is as follows: if the scrollY of the linkage container is equal to the top coordinates of the sub-view, the fling gesture is processed by the sub-view itself, otherwise the fling gesture is processed by the linkage container.

And in a complete fling cycle, the linkage container and each sub-view will alternately complete the sliding behavior until the speed drops to zero. The linkage container needs to deal with the speed convergence during alternating sliding to ensure the smooth running of the whole fling. Next, take a look at the detailed implementation:

The onNestedPreFling () callback is a method in the NestedScrollingParent interface of the google nested sliding mechanism. When the fling behavior occurs in the child view, it will first ask the parent view whether to consume the fling gesture. If true is returned, the parent view will consume the fling gesture, otherwise it will not.

Line 6 records the direction of this velocityY according to the positive and negative values of fling.

In line 7, when the scrollY value of the linkage container is equal to the top value of the touch sub-view, the fling gesture is processed by the sub-view. At the same time, the linkage container tracks the speed of the fling gesture, so that when the sub-view content rolls to the top or bottom, the remaining speed can be obtained to allow the linkage container to continue fling.

Line 12, the linkage container consumes the fling gesture. Let's take a look at the details of the alternating fling between the linkage container and the sub-view:

The speed transfer of fling is as follows:

Transfer from linkage container to sub-view; 2. Passed from the child view to the ganged container.

First look at the speed transfer from the linkage container to the sub-view. The core code is in the computeScroll () callback method. Line 9, get the next scroll boundary value of the driven container. If the next rolling boundary value is reached, the linked container needs to pass the remaining speed to the next sub-view to continue scrolling.

Line 46, the getNextEdge () method's internal overall logic: traverses all the child view, comparing the current scrollY of the ganged container with the top/bottom of the child view to get the next sliding boundary.

In line 34, when the ganged container detects sliding to the next boundary, it calls ILinkageScroll.flingContent () to let the child view continue scrolling based on the remaining speed.

If you look at the speed passed from the sub-view to the linkage container, the core code is on line 76. When the sub-view content scrolls to the top or bottom, the onContentScrollToTop () method or onContentScrollToBottom () method is called back. After receiving the callback, the linkage container continues to perform subsequent scrolling on lines 86 and 98. The flow chart of fling gesture processing is as follows:

4. Scroll Bar 4.1 ScrollBar for Android system

For scrollable pages, ScrollBar is an indispensable UI component, so ScrollBar is also a function that must be implemented by the linkage container.

Fortunately, the Android system is very friendly to the abstraction of the scroll bar, custom controls only need to rewrite a few methods in View, the Android system can help you draw the scroll bar correctly. Let's first take a look at the relevant methods in View:

For vertical Scrollbar, we only need to override the three methods computeVerticalScrollOffset (), computeVerticalScrollExtent (), and computeVerticalScrollRange (). Android has commented on these three methods in great detail, so let's briefly explain them here:

ComputeVerticalScrollOffset () represents the offset value of the current page content scrolling, which is used to control the position of the Scrollbar. The default value is the scroll value in the Y direction of the current page.

ComputeVerticalScrollExtent () represents the range of the scroll bar, that is, the maximum limit that the scroll bar can reach vertically, and this value is also used by the system to calculate the length of the scroll bar. The default is the actual height of the View.

ComputeVerticalScrollRange () represents the scrollable range of values for the entire page content, and the default value is the actual height of the View.

It is important to note that the three values of offset,extent,range must be consistent in units.

4.2 Linkage container to implement ScrollBar

The linkage container is composed of scrollable sub-view in the system, and these sub-view (ListView, RecyclerView, WebView) must all implement the ScrollBar function, so it is very easy for the linkage container to implement ScrollBar. The linkage container only needs to get the offset,extent and range values of all the sub-view, and then convert these values of all the sub-view into the corresponding offset,extent,range of the linkage container according to the sliding logic of the linkage container. The design of the interface is as follows:

The LinkageScrollHandler interface is explained in section 3.2, and I won't repeat it here. These three methods are implemented by the sub-view, and the linkage container will obtain the values related to the scrollbar of the sub-view through these three methods. Let's take a look at the detailed logic about ScrollBar in the ganged container:

The above is the core code of the linkage container to implement ScrollBar, and the comments are also very detailed. Here we emphasize a few more points:

In order to improve efficiency, ViewGroup does not call the onDraw () method by default, so it does not follow the drawing logic of ScrollBar. So in line 6, you need to call setWillNotDraw (false) to open the ViewGroup drawing process

Line 16, receive the scrolling callback of the child view, and call awakenScrollBars () to trigger the drawing of the scroll bar

For extent, directly use the default extent, that is, the height of the ganged container

For range, the range of all the sub-view is summed up, and the final value is the range of the linkage container.

For offset, the offset of all sub-view is also summed first, and then the scrolly value of the linkage container itself needs to be added, and the final value is the offset of the linkage container.

You can go back to the beginning of the article and take a look at the effect of the scroll bar in Demo. Compared with other App that use similar linkage technology on the market, the implementation of scroll bar in this article is very close to the native.

5. Matters needing attention

When the linkage container performs the fling operation, it is completed with the help of the OverScroller tool class. The code is as follows:

With the help of the OverScroller.fling () method to complete the fling behavior of the linkage container, this code will have a problem running on the Xiaomi phone, and mScroller.getCurrVelocity () has always been 0.

The reason is that the Rom of Xiaomi mobile phone rewrites OverScroller. When the third parameter of fling () method passes 0, OverScroller.mCurrVelocity is always NaN, which makes it impossible to calculate the correct residual speed.

In order to solve the problem of Xiaomi mobile phone, we need to pass the third parameter a non-zero value, which can be given to 1 here.

The principle of multi-child view nesting is not complicated, and the boundary conditions of gesture processing are trivial, which need to be debugged and improved.

This is the end of the general solution for the nesting of Android multi-child view in the UI series. I hope the above content can be helpful to you and learn more knowledge. If you think the article is good, you can share it for more people to see.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Servers

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report