The cause of
I recently received a request for a style similar to the one shown below (some details are omitted, so it is not affected).
This is a video play page + details page, considering the simple and quick, I thought of a ViewPager2 can be implemented, simple and quick, like yourself. Think of so easy, instantaneous laugh out of the pig call. Of course, RecyclerView can also use a LayoutManager that mimics Douyin, but why not, because it involves video playback, manual to deal with some life cycles and lazy loading, is always very troublesome, And ViewPager2 itself is based on RecyclerView, so why not?
Of course, as some of you might say, this thing is just a custom sliding ViewGroup, and so is this one. But first you have to consider a lot of things, if the video details page is more than one screen, that is, internal use of RecyclerView or NestedScrollView, is it also need to deal with sliding conflicts, of course, this is not very difficult, internal interception can be done. Then, after writing, the corresponding load callback would have to manually define an interface to forge it. Things like invisibility, page loading, the whole thing is not that easy.
Just when I thought I could do it again with a ViewPager2. Suddenly, the product students sent new instructions, subconsciously foreboding bad.
Product: need to add a prompt when using for the first time, otherwise users will not know the page can slide? Effect I send you, you see:
The following is a simple style that I have implemented.
(ViewPager2 has a fakeDragBy() method to set the offset). This is a bit of a hassle and I have to think about it.
Next do not know that they want to open a slap face moment, full of joy, too easy ah, ViewPager2 really sweet 🤣!
Face time
So skilled open branches, cut branches, write demo, call methods, go!
So let’s look at this method.
fakeDragBy()
BeginFakeDrag () is used to simulate the drag effect of a finger, which needs to be started by calling beginFakeDrag(), and then closed by calling endFakeDrag().
Since there is this method, it is very simple, the pseudo-code is as follows:
The result is as follows:
The sample | |
---|---|
I cracked 😨, why so, I on the properties of animation tune once just, to take a look at the source.
ViewPager2.fakeDragBy(x)
It ended up using scrollBy() of RecyclerView, which is a relative slide.
The solution
In this case, ViewPager2 is based on RecyclerView, so I can use RecyclerView to scroll.
- ViewPager2-> RecyclerView, RecyclerView is private by default and can be passed
reflection
orgetChildAt(0)To obtain - RecyclerView does not supportscrollTo(), can be accessed through
LinearLayouManager
To scroll - LinearLayoutManager-
scrollToPositionWithOffset()
Supports scrolling to offset position
The pseudocode is as follows:
val layoutManager = (getChildAt(0) as? RecyclerView ? :return@apply).layoutManager as? LinearLayoutManager ? :return@apply
val oneAnimator = ValueAnimator.ofFloat(0f, -450f).apply {
duration = 500
}
oneAnimator.addUpdateListener {
layoutManager.scrollToPositionWithOffset(0, it.animatedValue as Int)
}
oneAnimator.start()
Copy the code
The effect is as shown in the example GIF above, which solves the viewPager2-Item dynamic scrolling problem.
Points to be aware of
As I explained at the beginning of the analysis above, if the detail page is slippable, then you have to deal with slippable conflicts by using an internal interception method that gives the sliding View priority over the event and then returns the event to the parent View when it is at the top of the sliding View.
subsequent
Of course, using ViewPager2 is still a bit of a stretch, since there are only two items, so it’s still better to use a custom sliding ViewGroup implementation, so I’ll tackle this in a custom way in the next blog post.