当前位置: 首页 > 科技观察

[Android]无法描述这个

时间:2023-03-14 08:27:08 科技观察

序言的效果最近收到一个请求,让我觉得很尴尬。(下面是一些废话)需要的效果是这样的,上面有一部分悬浮,后面是一些布局,下面还有几个可以切换的Tab页,滚动的时候~~blahblahblahblahblahblahblah我们直接看图吧。主要是顶部和Tab的悬浮,以及被推下的效果。听说要达到这样的效果,我抽屉里那把切割产品的专用菜刀已经准备好了。思路先说说实现的思路。上面的效果大致可以分为两部分:1.当Tab滚动到顶部时,当Tab滚动时浮动,然后浮动到顶部~~使用CoordinatorLayout+AppBarLayout可以轻松实现这个效果。(什么?你还不明白这两个控件怎么用?嗯,后面的内容你应该能勉强看懂)2、顶部悬浮和“被推开”的效果,放一层FrameLayout就可以了在CoordinatorLayout外面,然后把top上面变化的布局。然后监听AppBarLayout的滚动,使用topMargin实现被“置顶”的效果。app:layout_scrollFlags="scroll|exitUntilCollapsed"而TabLayout没有设置app:layout_scrollFlags属性app:layout_behavior="@string/appbar_scrolling_view_behavior"layout_scrollFlags:ChildrenView的AppBarLayout属性,一共有五个值:scroll,enterAlways,enterAlwaysCollapsed,snap,exitUntilCollapsed。具体使用可以参考Android详解AppBarLayout的五个ScrollFlags(CoordinatorLayout和AppBarLayout的详细用法我就不多说了)。然后,只要在Java代码中给ViewPager添加几个列表Fragment,就可以看到如下效果(注意:列表不能是ListView,需要使用RecyclerView)至此,大部分效果已经实现。最终的值需要达到“被推开”的效果。顶部“被推开”的效果此时布局略有变化。
在原来的基础上,设置了一个FrameLayout,顶部的浮动部分可以通过FrameLayout来实现。这也导致下面的部分布局被覆盖,所以在LinearLayout中添加了一个与浮动部分高度相同的空View。布局完成,如何实现“被推开”的效果?这个时候只要在MainActivity中监听AppBarLayout的滚动即可。@BindView(R.id.app_bar)AppBarLayoutmAppBar;@BindView(R.id.sticky_view)ViewmStickyView;@BindView(R.id.header)ViewmHeader;privatevoidsetAppBarListener(){mAppBar.addOnOffsetChangedListener(newAppBarLayout.OnOffsetChangedListener(){@OverridepublicvoidonOffsetAppBarLayoutappBarLayout,intverticalOffset){//头部高度(被顶部覆盖的部分除外)intminScrollHeight=mHeader.getMeasuredHeight();intmargin=minScrollHeight+verticalOffset;margin=margin>0?0:margin;FrameLayout.LayoutParamslayoutParams=(FrameLayout.LayoutParams)mStickyView.getLayoutParams();layoutParams.topMargin=margin;mStickyView.setLayoutParams(layoutParams);}});}这里,通过AppBarLayout滚动监听(向上滚动时,verticalOffset值变化:0,-1,-2...-n-1,-n)来计算保证金值。通过改变topMargin,实现“被推开”的效果。再看看效果:我敲了这里,我默默收起了砍品专用菜刀。提示问题:使用CoordinatorLayout时,滚动不流畅。解决方案:可以写一个Behavior添加到AppBarLayout中。具体解决问题:如果要刷新功能,在CoordinatorLayout外面设置一个SwipeRefreshLayout,不小心触发了刷新~~(自己体会)解决:这个问题可以通过监听AppBarLayout,设置swipeLayoutEnabled来处理mAblAppBar。addOnOffsetChangedListener((appBarLayout,verticalOffset)->{if(verticalOffset==0){swipeLayout.setEnabled(true);}else{if(!swipeLayout.isRefreshing()){swipeLayout.setEnabled(false);}}});