Android高仿京东2020版首页联动效果!
作者:
白玉梁
, 地址:https://juejin.cn/post/7021683773834002446
本篇效果图:
新增效果
(不同于本篇效果的另一种效果,包含在本项目中):
第一张图 通过RecyclerView+Vlayout
多布局实现;第二张具有实战性质的效果图 通过CoordinatorLayout+RecyclerView
实现;
上一篇:高仿京东2020版首页布局及刷新效果,缺点是用了NestedScrollView
嵌套了ViewPager
,效果可以实现,但实际应用中体验似乎还是有点差的,原因可以查看该篇博客尾部说明。
第一版得布局结构图:
起初考虑到TabLayout
和RecyclerView
(ViewPager中)可以一起滑动,所以很容易想到的办法就是用Scrollview
将两者嵌套进去,效果是实现了,但是Scrollview
嵌套Viewpager
的弊端显而易见!
而第二版即本篇博客并不是为了解决Scrollview
嵌套Viewpager的问题,而是换一种思路去实现!
布局结构图,很简单,就两层:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#f7f7f7"
android:focusable="true"
android:focusableInTouchMode="true">
<LinearLayout
android:id="@+id/ll_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<net.lucode.hackware.magicindicator.MagicIndicator
android:id="@+id/magicIndicator"
android:layout_width="match_parent"
android:layout_height="35dp"
android:background="#acddee"
android:visibility="gone" />
<com.byl.jdrefresh.v1.CustomViewPager
android:id="@+id/customViewPager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
<RelativeLayout 搜索栏.../>
</RelativeLayout>
就是将第一版中的第一层和第二层(自定义JdScrollVIew
)放在了Tab1的fragment中:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.byl.jdrefresh.v2.JdScrollView2
android:id="@+id/jdScrollView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
JdScrollView
布局 仅需要将原来布局中的ViewPager
换成RecyclerView
即可,具体可参考源码!
但这样做好像并没有解决TabLayout
和列表一起滑动的效果啊?!
其实,这里取了一个巧,MainActivity
中的有一个TabLayout
,而tab1也就是首页中的Fragment也包含了一个一摸一样的TabLayout
(NestedScrollview
嵌套TabLayout+RecyclerView
),当viewpager的position==0
时,MainActivity中的TabLayout隐藏,其它页面时显示,所有的效果操作由MainActivity转移到了Tab1Fragment中,这样也就避免了使用ScrollView嵌套Viewpager这种模式!
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rl_content"
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:id="@+id/view"
android:layout_width="match_parent"
android:layout_height="180dp"
android:background="#acddee" />
<ImageView
android:id="@+id/iv_ad"
android:layout_width="match_parent"
android:layout_height="1000dp"
android:layout_marginTop="-820dp"
android:scaleType="centerCrop"
android:src="@mipmap/bg_ad" />
<LinearLayout
android:id="@+id/ll_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/tv_refresh_state"
android:layout_width="match_parent"
android:layout_height="40dp"
android:gravity="center"
android:text="下拉刷新"
android:textColor="#dddddd" />
<net.lucode.hackware.magicindicator.MagicIndicator
android:id="@+id/magicIndicator"
android:layout_width="match_parent"
android:layout_height="35dp" />
<com.byl.jdrefresh.v2.CustomRecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginHorizontal="15dp"
android:nestedScrollingEnabled="false" />
</LinearLayout>
</RelativeLayout>
另外,本篇在原来的基础上多加了一个功能,可以参考京东app,即下拉超过一定距离后,背景会自动向下全屏展开,然后自动进入到广告页面:
实现方案,就是在手势抬起(ACTION_UP)时,判断当前下拉的距离,超过某一设定值时,则自动在一定时间内让图片及整体布局处于全屏状态,其实就是依靠ValueAnimator
,不断的设置背景图的marginTop
以及内容的paddingTop
:
case MotionEvent.ACTION_UP:
if (adScrollDistance > 500) {
isInterceptTouch = true;
AnimUtils.start(-(int) (marginTop + adScrollDistance), 500, new AnimUtils.OnAnimListener() {
@Override
public void onUpdate(int value) {
layoutAd(marginTop + adScrollDistance + value);
ll_content.setPadding(0, (int) (paddingTop + adScrollDistance + AD_START_SCROLL_DISTANCE) + value, 0, 0);
}
@Override
public void onEnd() {
context.startActivity(new Intent(context, AdActivity.class));
new Handler().postDelayed(() -> {
tv_refresh_state.setText("下拉刷新");
isInterceptTouch = false;
recyclerView.setRefreshing(false);
isInterceptScroll = false;
REFRESH_STATUS = REFRESH_DONE;
layoutAd(marginTop);
iv_ad.setImageAlpha(0);
if (onPullListener != null) onPullListener.onPull(255);
ll_content.setPadding(0, paddingTop, 0, 0);
reset();
}, 300);
}
});
return true;
}
......
有一点需要注意的是,背景图片的高度,并不是屏幕高度,而是屏幕的高度加上
这一部分的高度:
screenHeight = SysUtils.getScreenHeight(context);
topRemainHeight = SysUtils.Dp2Px(context, imageShowHeight) - StatusBarUtil.getStatusBarHeight(context) - SysUtils.Dp2Px(context, 40);//40是搜索栏高度,是多少就写多少
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, screenHeight + topRemainHeight);
marginTop = -(screenHeight + topRemainHeight - SysUtils.Dp2Px(context, imageShowHeight));
layoutParams.topMargin = marginTop;
iv_ad.setLayoutParams(layoutParams);
这样做的原因是,如果只把背景图设为屏幕高度,则背景图通过不断设置marginTop直至为0完全展开时,红框部分会正好卡在底部,并不会完全隐藏掉,原因其实很简单,如图:
图片到达底部时,由于红框与图片底部是持平的,所以正好漏在了外面,因此,这就需要上面所说的方法,将图片高度在屏幕高度基础上再+红框部分高度,这样在背景图片全屏时,可见内容区就移至了屏幕外,整个屏幕就只有背景图片可见了!
Github地址:https://github.com/baiyuliang/JdRefresh
---END---
更文不易,点个“在看”支持一下👇