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

来源:互联网 发布:云镜安卓限制安装软件 编辑:程序博客网 时间:2024/04/27 18:53




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.....ScrollingImageViewxmlns: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>
原创粉丝点击