最新因为有一个项目需求是滑动悬浮效果,很多电商都可能用到的场景,话不多说,直接上图:
其实这个很容易做:最近老加班,脑子有点转不过来了。
布局比较复杂,刚开始想的是用自定义ScrollView嵌套TabLayout+ ViewPager + RecyclerView做,ViewPager是用自包裹做的,但是做出来后发现滑多了以后再切换ViewPager发现很卡顿,我认为是RecyclerView里面的元素没有被复用导致的。因为ViewPager是自包裹的嘛,而且还发现一个问题就是切换后面的tab的时候ViewPager的高度算的不对,下面是计算ViewPager的高度的方法:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int height = 0;
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
int h = child.getMeasuredHeight();
maps.put(i, h);
if (getChildCount() > 0 ) {
height = getChildAt(position).getMeasuredHeight();
heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
}
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
但是发现ChildCount数量最多到8,这个跟你的fragment数量有一定关系,但不是fragment的数量,后来一查,是说ChildCount指的是ViewPager的缓存数量,并不等于ViewPager的itemCount,网上的demo的tab刚好都小于8,超过8后切换到后面的tab项的时候ViewPager的高度都算的不对。
于是想着使用外部拦截法,把ViewPager的高度固定,通过滑动到临界值的方式去交换滑动事件。想法是好的,但是把滑动事件交给了外部的ScrollView去控制,这里又挖坑了,遇到了一个棘手的问题,慢滑到临界值的时候,事件交换不过来,导致有时候会滑不动, 必须快速的滑过去,很影响用户体验啊0.0...
于是又弃坑了,换了个思路:内部拦截的方式,于是又在埋坑的路上继续前行了... 后来发现RecyclerView的item显示有问题,外面根本滑不动,滑动事件没有传递到ScrollView,应该是被ViewPager消费了,后来尝试修改ViewPager的拦截,发现没什么用,有哪位大神做出来的可以指点一二。
后来想了想觉得不用ScrollView了,为什么一定要用ScrollView呢,脑子糊涂了~,用CoordinateLayout + AppBarLayout + ViewPager + RecyclerView其实就可以了。而且这个联动还是挺简单的,不需要自定义behavior。
下面附上布局:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/COLOR_WHITE"
android:orientation="vertical">
<android.support.design.widget.CoordinatorLayout
android:id="@+id/coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/COLOR_WHITE">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="-76dp"
android:orientation="vertical"
app:layout_scrollFlags="scroll|enterAlwaysCollapsed">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.youth.banner.Banner
android:id="@+id/banner"
android:layout_width="match_parent"
android:layout_height="@dimen/dip240"
app:image_scale_type="fit_xy">
</com.youth.banner.Banner>
<ImageView
android:layout_width="match_parent"
android:layout_height="@dimen/dip36"
android:layout_alignParentBottom="true"
android:contentDescription="@null"
android:scaleType="fitXY"
android:src="@drawable/audition_banner_cover_img" />
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="-30dp">
<LinearLayout
android:id="@+id/ll_super_withdraw_card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/iv_super_withdraw_card"
android:layout_marginLeft="@dimen/dip16"
android:layout_marginRight="@dimen/dip16"
android:layout_marginTop="-17dp"
android:background="@drawable/bg_gradient_r27"
android:gravity="center"
android:paddingBottom="@dimen/dip12"
android:paddingTop="@dimen/dip12">
<LinearLayout
android:id="@+id/ll_dwc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="本日剩余额度:"
android:textColor="@color/COLOR_WHITE"
android:textSize="@dimen/font12" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/rmb"
android:textColor="@color/COLOR_YELLOW"
android:textSize="@dimen/font12" />
<TextView
android:id="@+id/tv_dwc_amount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
android:textColor="@color/COLOR_YELLOW"
android:textSize="@dimen/font18" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/dip15"
android:text="无门槛提现"
android:textColor="@color/COLOR_WHITE"
android:textSize="@dimen/font12" />
</LinearLayout>
<ImageView
android:id="@+id/iv_help"
android:layout_width="@dimen/dip22"
android:layout_height="@dimen/dip22"
android:layout_marginLeft="@dimen/dip8"
android:contentDescription="@null"
android:src="@drawable/audition_diamond_help_img" />
</LinearLayout>
<ImageView
android:id="@+id/iv_super_withdraw_card"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:contentDescription="@null"
android:src="@drawable/accumulate_super_withdraw_card_bg_img" />
</RelativeLayout>
<!--拼多多、淘宝专栏-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/dip16">
<RelativeLayout
android:id="@+id/rl_tb"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginEnd="@dimen/dip4"
android:layout_marginRight="@dimen/dip4"
android:background="@drawable/bg_soild_r8_ff8a3d">
<ImageView
android:id="@+id/iv_tb"
android:layout_width="@dimen/dip56"
android:layout_height="@dimen/dip56"
android:layout_marginBottom="@dimen/dip17"
android:layout_marginLeft="@dimen/dip10"
android:layout_marginStart="@dimen/dip10"
android:layout_marginTop="@dimen/dip17"
android:contentDescription="@null"
android:src="@drawable/audition_home_tb_img" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_toRightOf="@+id/iv_tb"
android:gravity="center"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="淘宝专区"
android:textColor="@color/COLOR_WHITE"
android:textSize="@dimen/font15"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="海量优惠券"
android:textColor="@color/COLOR_WHITE"
android:textSize="@dimen/font12"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dip4"
android:background="@drawable/bg_solid_r10_000000"
android:paddingBottom="@dimen/dip2"
android:paddingLeft="@dimen/dip10"
android:paddingRight="@dimen/dip10"
android:paddingTop="@dimen/dip2"
android:text=" 逛淘宝 "
android:textColor="@color/COLOR_FF5E5E"
android:textSize="@dimen/font11"/>
</LinearLayout>
</RelativeLayout>
<RelativeLayout
android:id="@+id/rl_pdd"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/dip4"
android:layout_marginStart="@dimen/dip4"
android:layout_weight="1"
android:background="@drawable/bg_soild_r8_ff5e5e">
<ImageView
android:id="@+id/iv_pdd"
android:layout_width="@dimen/dip56"
android:layout_height="@dimen/dip56"
android:layout_marginBottom="@dimen/dip17"
android:layout_marginLeft="@dimen/dip10"
android:layout_marginStart="@dimen/dip10"
android:layout_marginTop="@dimen/dip17"
android:contentDescription="@null"
android:src="@drawable/audition_home_pdd_img" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_toRightOf="@+id/iv_pdd"
android:gravity="center"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="拼多多专区"
android:textColor="@color/COLOR_WHITE"
android:textSize="@dimen/font15"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="9.9全网最低"
android:textColor="@color/COLOR_WHITE"
android:textSize="@dimen/font12"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dip4"
android:background="@drawable/bg_solid_r10_000000"
android:paddingBottom="@dimen/dip2"
android:paddingLeft="@dimen/dip10"
android:paddingRight="@dimen/dip10"
android:paddingTop="@dimen/dip2"
android:text="逛拼多多"
android:textColor="@color/COLOR_FF5E5E"
android:textSize="@dimen/font11"/>
</LinearLayout>
</RelativeLayout>
</LinearLayout>
</LinearLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="75dp" />
<!--tab-->
<com.billionstech.grassbook.widget.tablayout.TabLayout
android:id="@+id/tab_find"
android:layout_width="match_parent"
android:layout_height="@dimen/dip40"
android:background="@color/COLOR_WHITE"
android:textStyle="bold"
app:tabBackground="@color/COLOR_WHITE"
app:tabGravity="fill"
app:tabIndicatorColor="@color/COLOR_FFCC00"
app:tabIndicatorHeight="3dp"
app:tabLineOffset="@dimen/dip12"
app:tabMinWidth="30dp"
app:tabMode="scrollable"
app:tabTextAppearance="@style/TabLayoutTextStyle" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
<!--顶部-->
<LinearLayout
android:id="@+id/ll_top"
android:layout_width="match_parent"
android:layout_height="@dimen/dip75"
android:gravity="center_vertical"
android:paddingTop="@dimen/dip15"
android:visibility="visible">
<!--搜索-->
<RelativeLayout
android:id="@+id/rl_search"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/dip10"
android:layout_marginLeft="@dimen/dip15"
android:layout_marginStart="@dimen/dip15"
android:layout_marginTop="@dimen/dip10"
android:layout_weight="1"
android:background="@drawable/bg_solid_stroke_r20_000000_eeeeee"
android:paddingBottom="@dimen/dip9"
android:paddingEnd="@dimen/dip12"
android:paddingLeft="@dimen/dip12"
android:paddingRight="@dimen/dip12"
android:paddingStart="@dimen/dip12"
android:paddingTop="@dimen/dip9">
<ImageView
android:id="@+id/iv_search"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:contentDescription="@null"
android:scaleType="fitXY"
android:src="@drawable/auditions_search_img" />
<TextView
android:id="@+id/et_search"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginLeft="@dimen/dip14"
android:layout_marginStart="@dimen/dip14"
android:layout_toEndOf="@+id/iv_search"
android:layout_toRightOf="@+id/iv_search"
android:background="@null"
android:text="你想买啥"
android:textColor="@color/COLOR_999999" />
</RelativeLayout>
<!--通知-->
<RelativeLayout
android:id="@+id/rl_notify"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:paddingEnd="@dimen/dip23"
android:paddingLeft="@dimen/dip26"
android:paddingRight="@dimen/dip23"
android:paddingStart="@dimen/dip26">
<ImageView
android:id="@+id/iv_notify"
android:layout_width="@dimen/dip22"
android:layout_height="@dimen/dip22"
android:layout_below="@+id/iv_un_read"
android:layout_marginTop="-4dp"
android:contentDescription="@null"
android:src="@drawable/auditions_notify_img" />
<ImageView
android:id="@+id/iv_un_read"
android:layout_width="8dp"
android:layout_height="8dp"
android:layout_marginLeft="-7dp"
android:layout_toRightOf="@+id/iv_notify"
android:src="@drawable/mine_un_read_img"
android:visibility="invisible" />
</RelativeLayout>
</LinearLayout>
</RelativeLayout>
不明白CoordinateLayout用法的,可以看看这篇博文:https://blog.youkuaiyun.com/kilotwo/article/details/79197498,
如果需要做更复杂的联动,可以考虑自定义behavior。
所以,前面一顿操作猛如虎,没什么卵用,不过踩了一些坑也,涨见识了,哈哈~
Ps:万一产品提一个很变态的需求,你又没什么想法的时候,可以研究一下竞品是怎么做的。打开竞品的app的当前页,
运行 adb shell dumpsys activity top,你就能看到他们写的布局了,可以做参考,给自己提供一下思路。