ScrollView使用技巧之实现滑动遮盖ImageView(View)

前言:
前几天一个小伙伴拿着他的iphone6 plus给我展示了一个效果,因效果为iOS上,我没有效果原图,就贴上实现之后的效果图。

ScrollView使用技巧之实现滑动遮盖ImageView(View)_第1张图片

分析:
可以从动图中看到,顶部的ImageView在ScrollView滑动的时候被遮盖或重现,一开始我以为这种效果实现起来会很复杂,分析许久无果,突然想到ScrollView滑动的过程,其实是在不断修改坐标值(也就是坐标系Y值),那么实现这个效果imageView的Y值必须也要改变了。从图中可以看出imageView和ScrollView的Y值都在改变,并且可以看出ImageView的Y值改变的速率要比ScrollView的慢、ImageView是随着ScrollView变动而变动的,所以ImageView要以ScrollView为参照物。因此实现步骤:

  • 通过onScrollChanged(int l, int t, int oldl, int oldt)获得ScrollView变动的Y值
  • 通过View.setTranslationY()方法改变ImageView的Y值

实现:

一、通过onScrollChanged(int l, int t, int oldl, int oldt)获得ScrollView变动的Y值

要想通过onScrollChanged(int l, int t, int oldl, int oldt)获得ScrollView变动的Y值并且暴露出来(传递出来),那我们得自己定义一个ScrollView了,下面是自定义的ScrollVIew,取名CoverScrollView。

1、自定义CoverScrollView:

public class CoverScrollView extends ScrollView {

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

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

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        if (scrollViewListener != null) {
            scrollViewListener.onScrollChanged(this, l, t, oldl, oldt);
        }
    }

    private ScrollViewListener scrollViewListener;

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

    public interface ScrollViewListener {

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

    }

}

是不是很简单,通过接口把onScrollChanged()方法得到的参数暴露出去,至于为什么通过onScrollChanged()得到这些参数,有兴趣的同学可以深入跟踪了解ScrollView和View相关源码。

2、相关xml文件:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/white" >

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@null" >

        <ImageView
            android:id="@+id/img_head"
            android:layout_width="match_parent"
            android:layout_height="300dp"
            android:background="@drawable/head"
            android:contentDescription="@null" />

        <com.skycracks.coverscrollview.CoverScrollView
            android:id="@+id/cover_scrollview"
            android:layout_width="match_parent"
            android:layout_height="match_parent" >

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@null"
                android:orientation="vertical" >

                <View
                    android:layout_width="match_parent"
                    android:layout_height="300dp"
                    android:background="@android:color/transparent"                             />

              <--! ScrollView中的填充内容,效果图中填充区域就是View设置固定高度和颜色--> 
            LinearLayout>
        com.skycracks.coverscrollview.CoverScrollView>

    RelativeLayout>

RelativeLayout>

在xml布局中我们要注意ImageView的高度设置为300dp,那么为什么ScrollView中为什么还有一个View高度也是300dp并且背景色设置的透明呢?没错,关键就在这里了。效果图中ImageView看上去是在ScrollView中,但是我们把ImageView真正的放入ScrollView是达不到效果图不同的滑动速率的(速率不同时,ImageView和ScrollView之间会出现白色空白区域),因此我们要造成一种假象ImageView在ScrollView中。我们知道RelativeLayout不设置相对关系(如toleft、toright、above、below)的效果和Framement布局的效果类似(你可以把RelativeLayout换成Framement试试),这个时候就相当于把ScrollView”贴在”ImageView上,为了将ImageView与ScrollView中的内容区分开来,通过设置一个高度与ImageView高度相同并且背景透明View来达到ScrolView设置android:layout_below=”@+id/img_head”的视觉效果。

二、通过View.setTranslationY()方法改变ImageView的Y值

我们在Activity中通过监听ScrollViewListener获取到ScrollView变动的Y值,从而给ImageView调用setTranslationY()改变Y值。

public class MainActivity extends Activity {

    private ImageView headImageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
       headImageView = (ImageView) findViewById(R.id.img_head);
       CoverScrollView mCoverScrollView =  (CoverScrollView) findViewById(R.id.cover_scrollview);
       mCoverScrollView.setonScrollViewListener(new ScrollViewListener() {

        @Override
        public void onScrollChanged(CoverScrollView scrollView, int x, int y,
                int oldx, int oldy) {
                //坐标系往上为负值
            headImageView.setTranslationY(-y/2);
        }
    });
    }

}

在调用setTranslationY的时候,值在上面代码设置为ScrollView滑动速率的一半,当然你也可以随便改变,但是不要造成视觉效果混乱或背离要实现的效果。

总结:

看完文章,你会发现实现这个功能不算难,甚至可以说非常容易,简简单单几十行代码加上对xml的布局的熟练就能实现。由此当我们看到一个效果、可能会很炫酷,不要一开始就觉得实现很难,静下心分析,其实没有你想象中的那么难。

Don’t act, you will never succeed.

你可能感兴趣的:(视图效果)