github地址(完整Demo,欢迎下载)
https://github.com/zhouxu88/ScrollViewTextGradual
最近项目需要,电商项目,需要仿淘宝商品详情页的标题栏渐变的效果。
效果图:
实现
分析:标题栏渐变,文字渐变隐藏 透明通知栏,这是通过ScrollView来做的,我们只需要在ScrollView的滑动监听事件中根据滑动的距离,手指向上还是向下滑动来做相应的透明和显示操作就可以完成这种效果了。
1、ScrollView滑动监听:
Google并没有给我们提供ScrollView的滑动距离、是否滑动到布局底部、顶部的方法,但是提供了一个onScrollChanged方法:
@Override
protected void onScrollChanged(int x, int y, int oldx, int oldy) {
super.onScrollChanged(x, y, oldx, oldy);
}
}
参数说明
- x :当前横向滑动距离
- y: 当前纵向滑动距离
- oldx: 之前横向滑动距离
- oldy :之前纵向滑动距离
但是很遗憾这个方法我们不可以调用,所以我们不得不重写ScrollView暴露该方法:
/**
* 带滚动监听的scrollview
*
*/
public class GradationScrollView extends ScrollView {
public interface ScrollViewListener {
void onScrollChanged(GradationScrollView scrollView, int x, int y,
int oldx, int oldy);
}
private ScrollViewListener scrollViewListener = null;
public GradationScrollView(Context context) {
super(context);
}
public GradationScrollView(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
}
public GradationScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void setScrollViewListener(ScrollViewListener scrollViewListener) {
this.scrollViewListener = scrollViewListener;
}
@Override
protected void onScrollChanged(int x, int y, int oldx, int oldy) {
super.onScrollChanged(x, y, oldx, oldy);
if (scrollViewListener != null) {
scrollViewListener.onScrollChanged(this, x, y, oldx, oldy);
}
}
}
然后我们需要获取图片的高度,并且设置滚动监听,随着滚动的距离来设置标题栏的颜色透明度和字体颜色的透明度
private void initListener() {
// 获取顶部图片高度后,设置滚动监听
ViewTreeObserver treeObserver = headerIv.getViewTreeObserver();
treeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
headerIv.getViewTreeObserver().removeGlobalOnLayoutListener(this);
imageHeight = headerIv.getHeight();
Log.i(TAG, "imageHeight:-------->" + imageHeight);
scrollView.setScrollViewListener(MainActivity.this);
}
});
}
ScrollView的滑动监听
分析:y <= 0,还没有滑动或者手指先向上滑动一会儿滑又向下滑动值到顶部不能再滑动位置,y > 0 && y <= imageHeight,表示滑动的距离在这个头部的banner图的高度范围之内,也就是说距离是小于banner图的高度,这种情况又分为2种,手指向上滑和向下滑,当手指向上滑动,屏幕内容下滑时,3张图片是从透明渐变变成不透明,当手指向下滑动,屏幕内容上滑,3张图片是不透明渐变成透明
@Override
public void onScrollChanged(GradationScrollView scrollView, int x, int y, int oldx, int oldy) {
Log.i(TAG, "y:-------->" + y);
Log.i(TAG, "oldy:-------->" + oldy);
if (y <= 0) {
//设置渐变的头部的背景颜色
Log.i(TAG, "y <= 0:----------->");
headLayout.setBackgroundColor(Color.argb((int) 0, 255, 255, 255));
tv1.setTextColor(Color.TRANSPARENT);
tv2.setTextColor(Color.TRANSPARENT);
tv3.setTextColor(Color.TRANSPARENT);
tv4.setTextColor(Color.TRANSPARENT);
dividerView.setVisibility(View.GONE);
} else if (y > 0 && y <= imageHeight) {
//滑动距离小于banner图的高度时,设置背景和字体颜色颜色透明度渐变
Log.i(TAG, "滑动距离小于banner图的高度---->" + imageHeight);
float scale = (float) y / imageHeight;
int alpha = (int) (scale * 255);
headLayout.setBackgroundColor(Color.argb((int) alpha, 255, 255, 255));
tv1.setTextColor(Color.argb(alpha, 1, 24, 28));
tv2.setTextColor(Color.argb(alpha, 1, 24, 28));
tv3.setTextColor(Color.argb(alpha, 1, 24, 28));
tv4.setTextColor(Color.argb(alpha, 1, 24, 28));
backIv.getBackground().setAlpha(255 - alpha);
shopCartIv.getBackground().setAlpha(255 - alpha);
moreIv.getBackground().setAlpha(255 - alpha);
if (oldy < y) {
// 手指向上滑动,屏幕内容下滑
backIv.setImageResource(R.mipmap.ic_back_dark);
shopCartIv.setImageResource(R.mipmap.ic_shopping_dark);
moreIv.setImageResource(R.mipmap.ic_more_dark);
} else if (oldy > y) {
// 手指向下滑动,屏幕内容上滑
backIv.setImageResource(R.mipmap.ic_back);
shopCartIv.setImageResource(R.mipmap.ic_shopping_cart);
moreIv.setImageResource(R.mipmap.ic_more);
}
} else {
//滑动到banner下面设置普通颜色
Log.i(TAG, "滑动到banner下面---->" + imageHeight);
headLayout.setBackgroundColor(Color.WHITE);
tv1.setTextColor(Color.BLACK);
tv2.setTextColor(Color.BLACK);
tv3.setTextColor(Color.BLACK);
tv4.setTextColor(Color.BLACK);
dividerView.setVisibility(View.VISIBLE);
}
}