近期產品看到火球買手的圖片隨列表控件(recyclerview)滾動而滾動的效果,就決定要應用在本身的電商平臺 的商品列表上git
效果以下: 圖片隨之滾動github
能夠看到 圖片控件 隨着 列表的滾動 是會 小幅度的 滾動的bash
代碼以下:app
/**
* @author 馮旭 876111689@qq.com
* url:https://github.com/FX19970117
*/
public class ScrollingImageView extends RoundedImageView {
private float yPercent = 0.5f;
private ScrollType mScrollType;
public enum ScrollType {
/**
* View從開始到結束,一直在滑動
*/
SCROLL_WHOLE (0),
/**
* View只當在完整顯示時纔開始滾動
*/
SCROLL_MIDDLE (1);
ScrollType(int ni) {
nativeInt = ni;
}
final int nativeInt;
}
private static final ScrollType[] mScrollTypeArray = {
ScrollType.SCROLL_WHOLE,
ScrollType.SCROLL_MIDDLE,
};
public ScrollingImageView(Context context) {
super(context);
setup();
}
public ScrollingImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ScrollingImageView(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
TypedArray a = context.getTheme().obtainStyledAttributes(
attrs,
R.styleable.ScrollingImageView,
0, 0);
try {
int index = a.getInteger(R.styleable.ScrollingImageView_scrollType, 0);
setScrollType(mScrollTypeArray[index]);
} finally {
a.recycle();
}
RecyclerView temp = getRecyclerView((ViewGroup) this.getParent());
System.out.println("temp: " + temp);
setup();
}
private RecyclerView getRecyclerView(ViewGroup v) {
if (v == null) {
return null;
}
if (v instanceof RecyclerView) {
return (RecyclerView) v;
}
return getRecyclerView((ViewGroup) v.getParent());
}
private void setup() {
// 設置ImageView的必須ScaleType
setScaleType(ScaleType.MATRIX);
}
public void setScrollType(ScrollType scrollType) {
if (mScrollType != scrollType) {
mScrollType = scrollType;
// todo 好像要作點什麼。。
}
}
public ScrollType getScrollType() {
return mScrollType;
}
public void setyPercent(float yPercent) {
this.yPercent = yPercent;
requestLayout();
// 因爲在setFrame中的setImageMatrix中調用了invalidate。因此這裏沒必要再調用了
// invalidate();
}
private int getViewHeight() {
return getMeasuredHeight() - getPaddingTop() - getPaddingBottom();
}
@Override
protected boolean setFrame(int l, int t, int r, int b) {
if (getDrawable() == null) {
return super.setFrame(l, t, r, b);
}
Matrix matrix = getImageMatrix();
float scale;
float dx = 0, dy = 0;
int viewWidth = getMeasuredWidth() - getPaddingLeft() - getPaddingRight();
int viewHeight = getMeasuredHeight() - getPaddingTop() - getPaddingBottom();
int drawableWidth = getDrawable().getIntrinsicWidth();
int drawableHeight = getDrawable().getIntrinsicHeight();
// Get the scale
if (drawableWidth * viewHeight > drawableHeight * viewWidth) {
scale = (float) viewHeight / (float) drawableHeight;
dx = (viewWidth - drawableWidth * scale) * 0.5f;
} else {
scale = (float) viewWidth / (float) drawableWidth;
// 兩種不一樣的滾動方式
if (mScrollType == ScrollType.SCROLL_WHOLE) {
dy = viewHeight - (viewHeight + drawableHeight * scale) * yPercent;
} else if (mScrollType == ScrollType.SCROLL_MIDDLE) {
dy = (viewHeight - drawableHeight * scale) * yPercent;
}
}
matrix.setScale(scale, scale);
matrix.postTranslate(Math.round(dx), Math.round(dy));
setImageMatrix(matrix);
return super.setFrame(l, t, r, b);
}
public static class ScrollListener extends RecyclerView.OnScrollListener {
int ydy = 0;
private RecyclerView.LayoutManager layoutManager;
private int id;
private int index;
public ScrollListener(RecyclerView.LayoutManager layoutManager, int id, int index) {
this.layoutManager = layoutManager;
this.id = id;
this.index = index;
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
ydy += dy;
System.out.println(ydy);
View item = layoutManager.findViewByPosition(index);
if (item != null) {
float Offset = item.getTop();
ScrollingImageView image = item.findViewById(id);
int viewHeight = image.getViewHeight();
int recyclerViewHeight = recyclerView.getHeight();
// System.out.println("Height: " + recyclerViewHeight);
// System.out.println("Offset: " + Offset);
final double bottomDelta = recyclerViewHeight - viewHeight;
if (image.getScrollType() == ScrollType.SCROLL_WHOLE) {
float ratio = (Offset + viewHeight) / 1.0f / (recyclerViewHeight + viewHeight);
image.setyPercent(ratio);
} else if (image.getScrollType() == ScrollType.SCROLL_MIDDLE) {
if (Offset > bottomDelta) {
image.setyPercent(1);
} else if (Offset <= 0) {
image.setyPercent(0);
} else {
image.setyPercent((float) (Offset / bottomDelta));
}
}
}
}
}
}
複製代碼
在類中調用: 在recyclerview 更新數據源,如接口拿到列表數據時,ide
for (int i = 0; i < dataAllList.size(); i++) {
rclGoodsList.addOnScrollListener(new ScrollingImageView.ScrollListener(manager, i + 1 }
複製代碼