Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android-欢迎页联动动画设计 #24

Open
jeffrey1995 opened this issue Nov 12, 2017 · 0 comments
Open

Android-欢迎页联动动画设计 #24

jeffrey1995 opened this issue Nov 12, 2017 · 0 comments

Comments

@jeffrey1995
Copy link
Owner

jeffrey1995 commented Nov 12, 2017

前言:博客还是要坚持写的,之前弄过一个欢迎页的联动效果,不是很复杂,其中包括两个点:一个是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源码

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant