Android-欢迎页联动动画设计

2018-05-23  本文已影响0人  Jeffrey599

前言:博客还是要坚持写的,之前弄过一个欢迎页的联动效果,不是很复杂,其中包括两个点:一个是ViewPager滑动时两层布局的错位效果,另一个页面中View在滑动时的渐隐渐现效果。

以下是我的设计思路:

1.将A,B两个ViewPager放置于同一布局中,屏蔽掉B的内部点击事件,给A设置OnPageChangeListener,在A的监听方法中调用B的scrollTo使B一起滑动,此时可以设置一定比例来制造错位效果。页面进度条的位置也在这里设置。
2.给B设置PageTransformer,可以根据页面移动的位置参数来设置View的透明度、缩放等操作,以此来制造渐隐渐现效果。

以下是具体实现:

1.自定义NotouchLayout布局,复写onInterceptTouchEvent函数将其返回true,事件不会向子控件转发,将布局B放在其中,即屏幕掉了其内部触摸事件。

public class NotouchLayout extends RelativeLayout {
  
    public NotouchLayout(Context context) {
        super(context);  
    }  
  
    public NotouchLayout(Context context, AttributeSet attrs) {
        super(context, attrs);  
    }  
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        return false;
    }
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return true;
    }
}  

2.封装了一个GuidePage布局,以下是布局文件,其他初始化过程不在此展示,重点分析一下setPageTransformer和setOnPageChangeListener两个部分。

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff"
    android:orientation="vertical">

    <android.support.v4.view.ViewPager
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <com.jeffrey.demo.guidedemo.NotouchLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.v4.view.ViewPager
            android:id="@+id/bg_view_pager"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_centerInParent="true"
            android:focusable="false" />
    </com.jeffrey.demo.guidedemo.NotouchLayout>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:id="@+id/progress_bar_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true"
            android:layout_marginBottom="36dp"
            android:orientation="horizontal">

            <View
                android:layout_width="20dp"
                android:layout_height="2dp"
                android:background="#80d7d7d7" />

            <View
                android:layout_width="20dp"
                android:layout_height="2dp"
                android:layout_marginLeft="1dp"
                android:background="#80d7d7d7" />

            <View
                android:layout_width="20dp"
                android:layout_height="2dp"
                android:layout_marginLeft="1dp"
                android:background="#80d7d7d7" />

            <View
                android:layout_width="20dp"
                android:layout_height="2dp"
                android:layout_marginLeft="1dp"
                android:background="#80d7d7d7" />
        </LinearLayout>

        <View
            android:id="@+id/progress_mark_view"
            android:layout_width="20dp"
            android:layout_height="2dp"
            android:layout_alignLeft="@id/progress_bar_view"
            android:layout_alignParentBottom="true"
            android:layout_marginBottom="36dp"
            android:background="#80828282" />

    </RelativeLayout>
</FrameLayout>

布局中包含两个ViewPager,以及下面白色进度条的布局。

mPager.setPageTransformer(true, new DepthPageTransformer()); 
public class DepthPageTransformer implements android.support.v4.view.ViewPager.PageTransformer {
    private static final float MIN_SCALE = 0.75f;

    public void transformPage(View view, float position) {
        int pageWidth = view.getWidth();

        if (position < -1) { // [-Infinity,-1)
            // This page is way off-screen to the left.
            view.setAlpha(0);

        } else if (position <= 0) { // [-1,0]
            // Use the default slide transition when moving to the left page
            view.setAlpha(1 + position);
            view.setTranslationX(7 * pageWidth / 24 * -position);
//                view.setScaleX(1);
//                view.setScaleY(1);

        } else if (position <= 1) { // (0,1]
            // Fade the page out.
            view.setAlpha(1 - position);

            // Counteract the default slide transition
            Log.d("ty", "position:" + position + "Traslation" + pageWidth * position);

            if (position >= 0.5) {
                view.setTranslationX(pageWidth / 2);
            } else {
                view.setTranslationX(pageWidth * position);
            }
            //Scale the page down (between MIN_SCALE and 1) UI缩放的设置
//                float scaleFactor = MIN_SCALE
//                        + (1 - MIN_SCALE) * (1 - Math.abs(position));
//                view.setScaleX(scaleFactor);
//                view.setScaleY(scaleFactor);

        } else { // (1,+Infinity]
            // This page is way off-screen to the right.
            view.setAlpha(0);
        }
    }
}

transformPage方法中的两个参数:ViewPager中当前显示view对象,以及其位置参数position,关于position具体含义可对照下图:为了设置渐变效果,以卡片(page)左边为标准,当处于[-Infinity,-1)区间时不显示,在[-1,0]区间时根据偏移量的增加透明度先增后减,同时根据偏移量来移动view,设置一定比例实现间错效果,当然也可以设置缩放效果(此处没有设置),在 (1,+Infinity]区间也不显示。这样就完成了渐隐渐现和间错效果

image

下面是联动效果,三个参数position代表当前view下标,positionOffset代表偏移量是一个百分比,positionOffsetPixels代表偏移量是像素单位。在这里用setTranslationX设置了下面进度条的滑动,用scrollTo使mFramePager(B)按真实比例滑动,因为之前mPager(A)设置了一定的滑动比例,这样就实现了带间错联动效果。

mPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                //进度条
                view.setTranslationX((view.getWidth() + view.getWidth() / 20f) * (position + positionOffset));
                //设置联动
                float pageOffset = position + positionOffset;
                Log.d("pageOffset", pageOffset + "");
                if (mFramePager != null) {
                    mFramePager.scrollTo((int) (pageOffset * mFramePager.getWidth()), mFramePager.getScrollY());
                }
            }

            @Override
            public void onPageSelected(int position) {

            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });

这样就实现了最终的效果,Demo源码

上一篇下一篇

猜你喜欢

热点阅读