【Android】这效果,我没法描述

移动开发 Android
最近接到一个需求,这需求让我表示很尴尬。要求的效果是这样的,顶部有部分悬浮,接着是一些布局,在下面是几个可切换的Tab页面,然后滚动的时候.....听到要实现这样的效果,我抽屉那把砍产品专用菜刀已经蠢蠢欲动了。

前言

最近接到一个需求,这需求让我表示很尴尬。(下面是一些废话)

要求的效果是这样的,顶部有部分悬浮,接着是一些布局,在下面是几个可切换的Tab页面,然后滚动的时候~~吧啦吧啦吧啦吧啦~~ 还是直接看图吧

【Android】这效果,我没法描述

主要就是顶部和Tab的悬浮,还有就是被顶掉的那个效果。

[[209268]]

听到要实现这样的效果,我抽屉那把砍产品专用菜刀已经蠢蠢欲动了。

思路

先说说实现的思路吧,上面的效果大致可以分成两个部分:

1、Tab向上滚动到顶部时悬浮

Tab滚动后悬浮在顶部嘛~~ 这效果使用CoordinatorLayout + AppBarLayout就能轻松实现。(什么?你还不懂这两个控件怎么使用?额,应该可以勉强看懂后面的内容)

2、顶部悬浮以及“被顶走”的效果

只要在CoordinatorLayout外面套一层FrameLayout,然后把这个顶部的布局改在上面。接着监听AppBarLayout的滚动,利用topMargin实现被“顶上去”的效果

拆分完毕,接下来就是实现了

实现

  • Tab的悬浮效果

利用CoordinatorLayout、AppBarLayout、TabLayout、ViewPager来实现Tab的悬浮效果

  1. <br> 

LinearLayout中设置app:layout_scrollFlags="scroll|exitUntilCollapsed" 而 TabLayout 不设置app:layout_scrollFlags属性

ViewPager中使用app:layout_behavior="@string/appbar_scrolling_view_behavior"

layout_scrollFlags:AppBarLayout供Children View使用的属性,一共有五种值:scroll,enterAlways,enterAlwaysCollapsed,snap,exitUntilCollapsed。具体的使用可以参考Android 详细分析AppBarLayout的五种ScrollFlags

(CoordinatorLayout、AppBarLayout的详细用法我就不多说了)

然后,只要在Java代码中为ViewPager添加几个列表Fragment就能看到以下的效果(注意:列表不可以是ListView,需要用RecyclerView)

【Android】这效果,我没法描述

到目前为止,效果已经实现了大半。最后值需要实现“被顶走”的效果就好了。

  • 顶部“被顶走”的效果

这时候,布局稍微改变下。

  1. <br> 

在原有的基础上,套了个FrameLayout,顶部的悬浮部分可以通过FrameLayout来实现。这样也导致下面的布局被盖住了一部分,因此在LinearLayout中加了与悬浮部分相同高度的空View。

布局是完成了,那个“被顶走”的效果怎么实现呢?这时候只要在MainActivity中对AppBarLayout的滚动进行监听即可。

 

  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.                 //头部高度(除去被顶部覆盖的部分) 
  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.         }); 

这里通过AppBarLayout滚动的进行监听(向上滚动时,verticalOffset值的变化为:0、-1 、-2 ... -n-1、-n)来计算margin值。通过改变topMargin,实现“被顶走”的效果。

再看一眼效果:

【Android】这效果,我没法描述

敲到这里,我才默默的收起了那把砍产品专用菜刀。

Tips

问题:使用CoordinatorLayout时,滚动不流畅问题

解决方案:可以写个Behavior添加到AppBarLayout中。具体的解决方案

问题:如果你在想要刷新功能,在CoordinatorLayout外面套了一个SwipeRefreshLayout,一不小心就触发了刷新~~(自己体会)

解决方案:这个问题可以通过对AppBarLayout的监听,设置swipeLayout的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. }); 
责任编辑:未丽燕 来源: 带心情去旅行
相关推荐

2023-02-15 08:30:05

2021-06-11 06:45:32

SQL结构化语言

2021-02-28 13:54:53

加密货币比特币货币

2013-07-17 09:13:19

2020-04-29 14:50:40

代码对比工具

2010-02-05 16:58:18

Android服务

2010-02-07 15:20:05

Android

2018-02-02 12:49:09

库克iPhone乔布斯

2021-04-27 10:02:40

股票数组代码

2009-07-22 11:02:54

2017-03-07 10:07:25

PythonIDE

2019-06-14 08:48:46

Tomcat日志SpringBoot

2021-05-11 09:27:54

装饰器模式代码开发

2020-03-30 09:57:05

Android分屏模式

2013-07-05 10:26:40

Android

2020-12-25 09:38:07

Vue前端代码

2024-04-17 08:21:44

2018-04-18 09:12:17

Android中兴谷歌

2013-05-14 10:33:57

AIR Android应用程序描述文件

2009-03-24 08:35:57

AndroidGoogle移动os
点赞
收藏

51CTO技术栈公众号