【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

Apple's secret to success: Don't be the first to strike back

[[137238]] Apple sold more than 61 million iPhone...

New evidence of extraterrestrial life was discovered on this planet!

A team led by scientists from the Southwest Resea...

How to plan an event well? 4 key actions!

When it comes to event planning , perhaps in many...

Help you optimize mobile page performance from four aspects

With the development of mobile Internet, we need ...

Is your language betraying your character?

How can language reflect people's character? ...

Waymo to bring driverless cars to Detroit Auto Show

According to foreign media reports recently, Waym...

"Autumn comes overnight", the temperature drop in Chongqing is heart-pounding!

On the eve of National Day, Chongqing finally exp...

Beidou is officially launched. Why do we build Beidou?

Beidou officially launched Today (July 31), the c...

3 mind maps to help you learn how to plan and operate community programs!

This is a simple mind map of paid community plann...