`

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

阅读更多




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>
  • 大小: 1.3 MB
分享到:
评论

相关推荐

    Android-在滚动的androidImageView上创建视差和任何其他转换效果

    在Android开发中,为ImageView添加视差效果以及各种转换效果是一种增强用户体验的流行技术。视差效果是指背景图像相对于前景元素以不同的速度移动,这种视觉错觉在滚动时能为用户带来深度感和动态感。在滚动的...

    Android代码-在滚动的android ImageView上创建视差和任何其他转换效果

    on android ImageView when it's being vertically or horizontally scrolled (moving) on the screen. I wrote an article explaining how this works and implemented, please check it out ...

    Android代码-滚动时图片产生视差效果的ImageView

    ScrollParallaxImageView extends ImageView, and provides parallax effects when it scrolls in the screen.It can be use in any view which can scroll its content, like ListView, RecyclerView, ScrollView, ...

    Listview+Image实现视差效果

    2. **布局设计**:在item的布局文件中,我们可以将背景图片设置为一个固定大小的ImageView,而前景图片则可以设置为可滚动的ImageView。通过这种方式,当ListView滚动时,背景图片的移动速度会比前景图片慢,从而...

    基于ListView实现头部、底部视差效果

    头部视差效果通常会用到一个比实际高度更大的ImageView或者其他视图,当ListView向上滚动时,这个视图会以较慢的速度逐渐露出。同样,底部视差效果也可以通过类似的方式实现,只是方向相反。 ```xml &lt;!-- header....

    利用Android实现discrollview视差滚动.rar

    视差滚动通常涉及到多个层级的布局,例如一个背景ImageView和一个可滚动的RecyclerView或ScrollView。 在本压缩包文件"利用Android实现discrollview视差滚动.rar"中,可能包含了一个自定义的`DiscrollView`类,这个...

    ParallaxImageView:在滚动android ImageView上创建视差和任何其他变换效果

    Android视差图像视图 当它在屏幕上垂直或水平滚动(移动)时,在android ImageView上创建诸如垂直视差,水平视差等效果。 参考: 截屏设置步骤1将存储库添加到根build.gradle allprojects { repositories { .. . ...

    swift-一个轻量级的iOS3D线性旋转视差效果

    总之,"swift-一个轻量级的iOS 3D线性旋转视差效果" 是Swift开发中的一种高级技巧,通过巧妙地使用Core Animation和自定义视图组件,可以在iOS应用中创造出引人入胜的3D视差滚动体验。对于希望提升应用视觉效果的...

    视差视图的工程图片

    在描述中提到的“放在imageView上滚动的图片”,这可能是指将图片作为背景放置在一个可滚动视图(如`UIScrollView`)内,然后通过调整图片的滚动速度来实现视差效果。在实际操作中,可以创建一个`UIImageView`作为...

    AKParallax-Android,滚动视图.zip

    AKParallax-Android是由开发者创建的一个库项目,其主要目的是为Android应用中的滚动视图(ScrollView)或列表视图(ListView)添加视差滚动效果。通过这个库,开发者可以轻松地为ImageView添加视差动画,使图片在...

    ListView - 视差特效

    1. **创建视差背景**:首先,你需要一个背景元素,它可以是ImageView、ViewGroup或者其他自定义视图。这个元素的大小应超出ListView的可见区域,以便在滚动时有足够空间进行移动。 2. **监听ListView滚动**:在...

    Android微信朋友圈视差特效

    在Android开发中,微信朋友圈视差特效是一种常见的高级UI设计,它可以为用户带来更丰富的视觉体验。这种特效通常应用于滚动视图,特别是顶部大图,当用户上下滑动时,图片会产生一种深度感,仿佛背景图像相对于前景...

    头部视差动画用Scrollview写的

    开发者可以将各种视图(如TextView、ImageView等)放入ScrollView,以实现可滚动的界面。 2. **视差效果**:视差是指当观察者移动时,远处和近处的物体移动速度不同,这种现象在3D图形和动画中被广泛应用。在头部...

    parallax.zip

    因此,我们需要创建一个继承自LinearLayoutManager或GridLayoutManager的自定义布局管理器,重写其`onScrolled()`方法,根据滚动距离调整每个item的视差效果。 2. **自定义动画效果**:对RecyclerView的...

    视差特效,侧滑删除,粘性控件

    此外,还可以通过`RecyclerView`的`ItemDecoration`类来自定义滚动中的视差效果,使得每个item在滚动时有不同的移动速度。 **侧滑删除** 侧滑删除通常用于列表或网格视图中,用户可以通过向左或向右滑动条目来触发...

    Android实现有视差效果的ListView

    在Android开发中,视差效果是一种...通过以上步骤,你就可以为你的Android应用增添一种引人入胜的视差滚动效果,提升用户体验。记住,良好的动画效果是提高用户满意度的关键因素之一,因此花时间优化这些细节是值得的。

    仿G+个人资料滑动时头像背景滚动变化

    这个效果在Google+应用中被广泛使用,其核心是通过滚动视差(Parallax Scrolling)来实现背景图片随用户手指滑动而缓慢滚动,从而营造出深度感和层次感。以下将详细解析这一功能的实现原理及步骤。 首先,我们需要...

    Parallax效果的ScrollerView

    ScrollerView是Android中一种自定义视图组件,它允许开发者实现滚动时元素以不同速度移动的效果,就像视差滚动。这种效果在很多应用的头部或者背景中常见,比如滚动时背景图片缓慢移动,而前景内容快速移动,从而...

    Android通过overScrollBy实现下拉视差特效

    在Android开发中,实现下拉视差特效是一种常见的交互设计,它可以提升用户体验,让用户感受到更生动、丰富的界面动态效果。视差滚动通常在列表视图(ListView)或滚动视图(ScrollView)中应用,当用户下拉时,背景...

Global site tag (gtag.js) - Google Analytics