寺库app的广告,最近在地铁满天飞,打开app看了看,有个页面比较炫,遂拿来模仿一番,先来简单看看
寺库实现的效果。
这个是模仿的效果,因为喜欢海贼王,所以素材当然是我草帽海贼团全员。
实现原理:
1、自定义imageView,添加doTranslate方法。
2、抽象类ParallaxViewHolder并实现接口ParallaxImageListener,暴露方法animateImage,实时调用doTranslate方法。
3、自定义RecycleView,添加滚动监听addOnScrollListener,滚动监听触发时会调用animateImage不断改变imagView的显示范围。
核心:
代码已经提交github,具体实现细节可以参考demo中的代码。这里只列出核心代码。
github地址:https://github.com/daimaXZ/sicooDemo
demo下载地址:http://fir.im/sicoo
自定义ImageView
//doTranslate中调用getValues获取单个item和RecycleView的高度及坐标点
private boolean getValues() {
int[] values = getListener().requireValuesForTranslate();
if (values == null)
return false;
this.rowHeight = values[0];
this.rowYPos = values[1];
this.recyclerViewHeight = values[2];
this.recyclerViewYPos = values[3];
return true;
}
private void calculateAndMove() {
//item rowYPos距离中间点的位置
float distanceFromCenter = (recyclerViewYPos + recyclerViewHeight) / 2 - rowYPos;
//图片单位像素值
int imageHeight = getDrawable().getIntrinsicHeight();
float scale = 1;
if (shouldCenterCrop) {
scale = recomputeImageMatrix();
imageHeight *= scale;
//centerCrop之后图片的高度
}
//图片可以滑动的距离范围
float difference = imageHeight - rowHeight;
//item在recyclerView中的滚动距离
float move = (distanceFromCenter / recyclerViewHeight) * difference * parallaxValue;
//ImageView需要移动到位置
float translate = (move - difference)/ 2;
//以上两行代码,如果有能解释清楚地,欢迎评论!
moveTo(translate, scale);
}
/**
*计算scale值
* @return
*/
private float recomputeImageMatrix() {
float scale;
final int viewWidth = getWidth() - getPaddingLeft() - getPaddingRight();
final int viewHeight = getHeight() - getPaddingTop() - getPaddingBottom();
final int drawableWidth = getDrawable().getIntrinsicWidth();
final int drawableHeight = getDrawable().getIntrinsicHeight();
if (drawableWidth * viewHeight > drawableHeight * viewWidth) {
scale = (float) viewHeight / (float) drawableHeight;
} else {
scale = (float) viewWidth / (float) drawableWidth;
}
return scale;
}
private void moveTo(float move, float scale) {
//利用矩阵进行图片的缩放和位移
Matrix imageMatrix = getImageMatrix();
if (scale != 1) {
// 先对图片进行比例缩放
imageMatrix.setScale(scale, scale);
}
float[] matrixValues = new float[9];
imageMatrix.getValues(matrixValues);
float current = matrixValues[Matrix.MTRANS_Y];
// 图片水平垂直移动
imageMatrix.postTranslate(0, move - current);
setImageMatrix(imageMatrix);
invalidate();
}
另外还写了一个viewpager的滑动视差,和开眼视频还有最近腾讯新出的一款本地音乐app(轻听)一样的效果。有兴趣的朋友,也就可以去看看:
github地址: https://github.com/daimaXZ/ParallaxDemo
demo下载地址:http://fir.im/ParallaxDemo
效果图:
以上!希望各位大大喜欢!
Thanks yayaa!