一个可以一直滚动的ImageView(可做视差效果)

[img]http://dl2.iteye.com/upload/attachment/0110/7970/5eb03d27-4b2b-300b-bfdf-a5275b089243.gif[/img]



import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;

import static java.lang.Math.abs;
import static java.lang.Math.floor;

/**
* Created by thijs on 08-06-15.
*/
public class ScrollingImageView extends View {
private final int speed;
private final Bitmap bitmap;

private Rect clipBounds = new Rect();
private int offset = 0;

private boolean isStarted;

public ScrollingImageView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.ParallaxView, 0, 0);
try {
speed = ta.getDimensionPixelSize(R.styleable.ParallaxView_speed, 10);
bitmap = BitmapFactory.decodeResource(getResources(), ta.getResourceId(R.styleable.ParallaxView_src, 0));
} finally {
ta.recycle();
}
start();
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), bitmap.getHeight());
}

@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (canvas == null) {
return;
}

canvas.getClipBounds(clipBounds);

int normalizedOffset = offset;
int layerWidth = bitmap.getWidth();
if (offset < -layerWidth) {
offset += (int) (floor(abs(normalizedOffset) / (float) layerWidth) * layerWidth);
}

int left = offset;
while (left < clipBounds.width()) {
canvas.drawBitmap(bitmap, getBitmapLeft(layerWidth, left), 0, null);
left += layerWidth;
}

if (isStarted) {
offset -= speed;
postInvalidateOnAnimation();
}
}

private float getBitmapLeft(int layerWidth, int left) {
float bitmapLeft = left;
if (speed < 0) {
bitmapLeft = clipBounds.width() - layerWidth - left;
}
return bitmapLeft;
}

/**
* Start the animation
*/
public void start() {
if (!isStarted) {
isStarted = true;
postInvalidateOnAnimation();
}
}

/**
* Stop the animation
*/
public void stop() {
if (isStarted) {
isStarted = false;
invalidate();
}
}
}



attr.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="ParallaxView">
<attr name="speed" format="dimension" />
<attr name="src" format="reference" />
</declare-styleable>
</resources>


usage:
<com.....ScrollingImageView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/scrolling_background"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:speed="1dp"
app:src="@drawable/scrolling_background" />



ScrollingImageView scrollingBackground = (ScrollingImageView) loader.findViewById(R.id.scrolling_background);
scrollingBackground.stop();
scrollingBackground.start();


Parallax effect:
只要设置不同的滚动背景速率就可以达到视差效果

<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">

<com......ScrollingImageView
android:id="@+id/scrolling_background"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:speed="1dp"
app:src="@drawable/scrolling_background" />

<com.....ScrollingImageView
android:id="@+id/scrolling_foreground"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:speed="2.5dp"
app:src="@drawable/scrolling_foreground" />
</FrameLayout>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值