【Android】I can’t describe this effect

【Android】I can’t describe this effect

Preface

I recently received a request that made me feel embarrassed. (Here are some nonsense words)

The required effect is like this, there is a floating part at the top, followed by some layouts, and several switchable Tab pages below, and then when you scroll~~blah blah blah blah~~ Let's just look at the picture directly

The main thing is the suspension of the top and Tab, and the effect of being pushed down.

[[209268]]

When I heard that this effect could be achieved, the kitchen knife in my drawer that I used to chop produce started to stir.

Ideas

Let's talk about the idea of ​​implementation first. The above effect can be roughly divided into two parts:

1. Tab is suspended when scrolling up to the top

The Tab will float at the top after scrolling~~ This effect can be easily achieved using CoordinatorLayout + AppBarLayout. (What? You still don’t know how to use these two controls? Well, you should be able to barely understand the following content)

2. Top suspension and the effect of being pushed away

Just wrap a layer of FrameLayout outside the CoordinatorLayout, and then change the top layout to the top. Then monitor the scrolling of AppBarLayout and use topMargin to achieve the effect of being "pushed up"

The split is complete, the next step is to realize

accomplish

  • Tab suspension effect

Use CoordinatorLayout, AppBarLayout, TabLayout, and ViewPager to achieve the floating effect of Tab

  1. <br>

Set app:layout_scrollFlags="scroll|exitUntilCollapsed" in LinearLayout, but do not set app:layout_scrollFlags attribute in TabLayout

Use app:layout_behavior="@string/appbar_scrolling_view_behavior" in ViewPager

layout_scrollFlags: AppBarLayout attributes for Children View, with five values: scroll, enterAlways, enterAlwaysCollapsed, snap, exitUntilCollapsed. For specific usage, please refer to Android Detailed Analysis of AppBarLayout's Five ScrollFlags

(I won’t go into details about the usage of CoordinatorLayout and AppBarLayout)

Then, just add a few list fragments to ViewPager in the Java code to see the following effect (Note: the list cannot be ListView, you need to use RecyclerView)

So far, most of the effects have been achieved. The final value just needs to achieve the effect of being pushed away.

  • The effect of the top being "pushed away"

At this time, the layout changes slightly.

  1. <br>

On the basis of the original, a FrameLayout is set, and the floating part at the top can be realized by FrameLayout. This also causes the layout below to be partially covered, so an empty View with the same height as the floating part is added to the LinearLayout.

The layout is completed, but how to achieve the "pushed away" effect? ​​At this time, just listen to the scrolling of AppBarLayout in MainActivity.

  1. @BindView(R.id.app_bar)
  2. AppBarLayout mAppBar;
  3. @BindView(R.id.sticky_view)
  4. View mStickyView;
  5. @BindView(R.id.header)
  6. View mHeader;
  7. private void setAppBarListener() {
  8. mAppBar.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
  9. @Override
  10. public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
  11. //Head height (excluding the part covered by the top)
  12. int minScrollHeight = mHeader.getMeasuredHeight();
  13. int margin = minScrollHeight + verticalOffset;
  14. margin = margin > 0 ? 0 : margin;
  15. FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) mStickyView.getLayoutParams();
  16. layoutParams.topMargin = margin;
  17. mStickyView.setLayoutParams(layoutParams);
  18. }
  19. });
  20. }

Here, the margin value is calculated by monitoring the scrolling of AppBarLayout (when scrolling up, the verticalOffset value changes to: 0, -1, -2... -n-1, -n). By changing the topMargin, the "pushing away" effect is achieved.

Take another look at the effect:

Having reached this point, I quietly put away the kitchen knife I used to chop produce.

Tips

Problem: Scrolling is not smooth when using CoordinatorLayout

Solution: You can write a Behavior and add it to AppBarLayout. Specific solution

Problem: If you want to refresh the page, and you put a SwipeRefreshLayout outside of CoordinatorLayout, you may accidentally trigger a refresh~~ (experience it yourself)

Solution: This problem can be solved by monitoring AppBarLayout and setting swipeLayout to Enabled.

  1. mAblAppBar.addOnOffsetChangedListener((appBarLayout, verticalOffset) -> {
  2. if (verticalOffset == 0) {
  3. swipeLayout.setEnabled( true );
  4. } else {
  5. if (!swipeLayout.isRefreshing()) {
  6. swipeLayout.setEnabled( false );
  7. }
  8. }
  9. });

<<:  Android solves ListView loading picture flickering

>>:  The fourth issue of the Aiti Tribe live class: How to quickly convert an H5 website into an App?

Recommend

Is it worth buying a BMW just to save a few thousand bucks?

According to official news from BMW Brilliance, f...

If alien life exists, what traces will it leave?

Author: Global Science Are you curious about the ...

3 Case Studies to Help You Implement Growth Models (Part 1)

With the rapid development of the Internet , its ...

Second category e-commerce advertising strategy!

Preface There are two characteristics of the seco...

How to get traffic from Tik Tok live streaming

In this article, we will analyze in detail the me...

The next trend of smart hardware has not yet really appeared

Nowadays, there are too many entrepreneurial proj...

Celebrity X-Files: Alan Turing | Celebrating Turing's 110th Birthday

Alan Turing, a British computer scientist, mathem...

How should operations use data?

How should operations use data? This question ste...

7 ways to play with private domain traffic

Compared with the public domain traffic of WeChat...

Nature: Climate warming may trigger species spread and virus evolution

There are at least 10,000 viruses in nature that ...