实现谷歌日历图像视图"视差"影响

时间:2014-11-21 16:03:24

标签: android imageview android-imageview parallax

也许有些人在材料设计中尝试过新的Google日历。我正在寻找的是“效果”或使图像视图遵循滚动的方式。它看起来像一个视差效果,但我能找到的只是在标题视图上具有视差效应的库。有人能指出我正确的方向吗?谢谢!

1 个答案:

答案 0 :(得分:1)

AFAIK没有图书馆可以做到这一点,但几个月前我做了类似的事情,但它非常简陋,根本没有动态。

首先,您需要扩展ScrollView,以便获得仅适用于scrollview类的所有滚动位置。

类似这样的事情

    public class TestScrollView extends ScrollView {

        private ScrollViewListener scrollViewListener = null;

        public interface ScrollViewListener {

            public void onScrollChanged(TestScrollView scrollView, int x, int y, int oldx, int oldy);

        }

        public TestScrollView(Context context) {
            super(context);
        }

        public TestScrollView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }

        public TestScrollView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }

        public void setScrollViewListener(ScrollViewListener scrollViewListener) {
            this.scrollViewListener = scrollViewListener;
        }

        @Override
        protected void onScrollChanged(int x, int y, int oldx, int oldy) {
            super.onScrollChanged(x, y, oldx, oldy);
            if(scrollViewListener != null) {
                scrollViewListener.onScrollChanged(this, x, y, oldx, oldy);
            }
        }
    }

接下来,您必须扩展ImageView以执行所有视差操作。这可能对你有用,也可能不对你有用,我不知道这是针对特定情况而做的

public class ParallaxImageView extends ImageView {

    public static final float PARALLAX_COEFFICIENT = 0.65F;
    public static final float PROPERTY_IMAGE_INV_RATIO = 0.6666667F;
    private int intrinsicHeight = -1;
    Context context;

    public ParallaxImageView(Context context) {
        super(context);
        this.context = context;
        init();
    }

    public ParallaxImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        init();
    }

    public ParallaxImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        this.context = context;
        init();
    }

    private void init(){
        post(new Runnable(){

            @Override
            public void run() {
                int i = (int)(PARALLAX_COEFFICIENT * (PROPERTY_IMAGE_INV_RATIO * getWidth()));
                getLayoutParams().height = i;
            }
        });
    }

    public void updateParallaxState()
    {
        int i = this.intrinsicHeight - getHeight();

        if (i == 0){
            return;
        }

        Rect localRect = getScreenLocation(this);
        int height = getHeight();
//        int j = getScreenSize().y + height;
//        float min = Math.min(1.0F, (localRect.top + height) / j);
//        float max = Math.max(min, 0.0F);
//        setScrollY((int)((max - 0.5F) * i));

        setScrollY((localRect.top-height-380)/8);
    }

    private Rect getScreenLocation(View paramView)
    {
        Rect localRect = new Rect();
        int[] arrayOfInt = new int[2];
        paramView.getLocationOnScreen(arrayOfInt);
        int i = getStatusbarHeight(paramView);
        localRect.set(arrayOfInt[0], arrayOfInt[1], arrayOfInt[0] + paramView.getWidth(), arrayOfInt[1] + paramView.getHeight());
        return localRect;
    }

    private int getStatusbarHeight(View paramView)
    {
        Rect localRect = new Rect();
        ((Activity)paramView.getContext()).getWindow().getDecorView().getWindowVisibleDisplayFrame(localRect);
        return localRect.top;
    }
}

然后在你的活动中实现scrolllistener和views

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    TestScrollView scroll = (TestScrollView)findViewById(R.id.scroll);
    scroll.setScrollViewListener(this);

    i1 = (ParallaxImageView)findViewById(R.id.image1);
    i2 = (ParallaxImageView)findViewById(R.id.image2);
}

@Override
public void onScrollChanged(TestScrollView scrollView, int x, int y, int oldx, int oldy) {
    i1.updateParallaxState();
    i2.updateParallaxState();
}

然后您的布局看起来像这样

<com.example.parallaximageview.app.TestScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/scroll">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

         //other views

        <com.example.parallaximageview.app.ParallaxImageView
            android:layout_width="match_parent"
            android:layout_height="300dp"
            android:src="@drawable/camera_phone"
            android:scaleType="centerCrop"
            android:id="@+id/image2"/>

        //other views

    </LinearLayout>

</com.example.parallaximageview.app.TestScrollView>