手把手教你撸最新Youtube视频 拖拽动画效果

栏目: IOS · Android · 发布时间: 5年前

内容简介:又到了金三银四的季节了,忙的人特别忙,面试啊,加班啊,闲的人也是特别闲吧,就比如我,天天划水,闲的写文章,做动画,同时呢各种新技术在不断的涌进,推动者软件行业的发展,不要焦虑,不要着急,学好本分,再扩展技能。不多说了,给大家看看做的效果吧。这个是原生的效果这个是做出来的效果

又到了金三银四的季节了,忙的人特别忙,面试啊,加班啊,闲的人也是特别闲吧,就比如我,天天划水,闲的写文章,做动画,同时呢各种新技术在不断的涌进,推动者软件行业的发展,不要焦虑,不要着急,学好本分,再扩展技能。不多说了,给大家看看做的效果吧。

手把手教你撸最新Youtube视频 拖拽动画效果

这个是原生的效果

手把手教你撸最新Youtube视频 拖拽动画效果

这个是做出来的效果

动画分解

动画分解其实很重要,如果说想模仿一个App的动画及交互效果,一定要仔细的观察他在交互细到放慢每一个操作,然后在根据这个动态来写代码。不然最后实现的效果不一样,那岂不是白费了。废话不多说,上代码看步骤。

第一步视频原始状态分析

可以看到,视频最初始的状态是由一个VideoView(可以是surfaceview都行),加上一个list吧,上下布局,但是VideoView呢,他是根据视频尺寸大小动态的调整宽高的,而不是固定的,我们来分析这个过程

  1. 第一种下拉的时候如果视频的高度没有达到原生高度,这时候下面的listview 不能消费touch事件,由videoview来消费这个事件,根据当前的下滑Y值进行调整视频宽高比
  2. 第二种情况是如果listview已经滑动了一部分这时候进行下拉,但是viewvideo还没有到达真是高度,这时候touch事件还是由listview消费,当他滑动到顶部的时候进行拦截touch 然后传递给videoview
  3. 第三中情况,当listview 向下快速滑动的时候会有个惯性的过程,即使手离开手机了 listview还是在滑动,我们称为惯性滑动,到惯性滑动到顶部的时候,如果视频高度没有达到原生高度,这时候要根据这个惯性值来调整调整视频高度。

第二步 视频下滑过程分析

由上图可以看到当我们在下拉视频的时候,视频的顶部 左右边距 机listview 都发生改变,同时videoview高度也发生了变化。

  1. 下拉的时候margin的 left right top bottom值都在发生改变,videoview 的高度也在发送改变,同时listview 渐渐消失,变成白色的背景,listview的高度在逐渐变小,同时可以看到在Z轴也发生了改变。可能图片不清晰,看不出Z轴的变换
  2. 下拉到listview消失的时候,这时候videoview的宽度发生改变,同时控制器出现。这时候videoview宽度还是在一直的缩小。
  3. 当达到了最小视频悬浮层的时候,下拉整个视图越来越透明,同时整个布局在根据手势在下滑。

第三步 视频上滑过程分析

上滑过程其实就是把下滑过程反过来而已,这里我就不再过多追溯了。

撸代码

主要的逻辑在上面都有,下面我就简单的对上面的逻辑进行分析一下,整体代码想要的老铁私信我留言都行

如何对listview和videoview进行touch的分发

这里我使用的是一个LinearLayout作为父布局进行组装这两个子view,然后根据viewgroup的dispatchTouchEvent方法里面加判断进行事件的分发。网上这些代码很多我就不详细赘述了,其实我这里还是有很多可以优化的地方,这只是个demo。

  • 和上面动画分解的逻辑一致,一看videoview 是否达到最大值,listview是否在顶部。
  • listview(我这边用的时候recyclerview都一样)是否在顶部可以通过调用addOnScrollListener()来判断是否是第一个可见的item *判断videoview是否达到最大值呢,根据视频的宽高来。可以通过Mediaplayer来获取,
//分发recyclerview和videoview事件
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        y = ev.getY();
        int pointerId = ev.getPointerId(0);
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mDownY = ev.getY();
                Log.i(TAG, "dispatchTouchEvent: ACTION_DOWN " + mDownY);
                if (mVelocityTracker == null) {
                    mVelocityTracker = VelocityTracker.obtain();
                } else {
                    mVelocityTracker.clear();
                }
                mVelocityTracker.addMovement(ev);
                break;
            case MotionEvent.ACTION_MOVE:

                float dDownY = y - mDownY;

                Log.i(TAG, "dispatchTouchEvent: " + mDownY + " " + y);
                mVelocityTracker.addMovement(ev);
                mVelocityTracker.computeCurrentVelocity(1000);


                if ((mDownY >= (layoutPVideo.getHeight() + layoutPVideo.getMarginTop())) && dDownY > 0 && layoutPVideo.getHeight() < originalHeight + 600 && (isList2Top)) {
                    //判断点击的范围,及当前视频尺寸大小。listview是否已经滑到顶部

                    layoutPVideo.setHeight((int) (layoutPVideo.getHeight() + dDownY));
                    Log.i(TAG, "dispatchTouchEvent: xia " + dDownY);
                    mDownY = y;
                    return true;
                } else if ((mDownY >= (layoutPVideo.getHeight() + layoutPVideo.getMarginTop())) && dDownY <= 0 && layoutPVideo.getHeight() >= originalHeight) {
                    //调整视频view 高度
                    layoutPVideo.setHeight((int) (layoutPVideo.getHeight() + dDownY));
                    //可以加个弹性动画显得更流畅
                    Log.i(TAG, "dispatchTouchEvent: shang " + dDownY);
                    mDownY = y;
                    return true;
                }
                break;
            case MotionEvent.ACTION_UP:
                float yVelocity = VelocityTrackerCompat.getYVelocity(mVelocityTracker,
                        pointerId);
                Log.i("VelocityTrackerCompat", "Y velocity: " +
                        yVelocity);
                
                if (yVelocity >= 5685 && layoutPVideo.getHeight() < originalHeight + 600) {
                    //判断惯性加速度根据惯性加速度进行引导视频大小到底部
                    headMoveToMax();
                } else {
                    Log.i(TAG, "headMoveToMax: not come in" + " " + (layoutPVideo.getHeight() < originalHeight + 600));
                }
                break;
            case MotionEvent.ACTION_CANCEL:
                mVelocityTracker.recycle();
                break;
        }


        return super.dispatchTouchEvent(ev);
    }

复制代码

如何动态的跳转左右边距及视频宽高

这里我用了一个包装类拿到当前view的layoutParams,然后通过touchEvent 拿到滑动的值来动态的修改当前view 的宽高和margin值,这个代码我就补贴了,就是set get方法。

  • 第一步下滑调整margin的左右上下,及videoview 的高度。
  • 第二步继续下滑调整videoview的宽度
  • 第三步下滑隐藏整体view
private void updateVideoView(int m, int originY) {

        canHide = false;
        if (mDetailView.getHeight() == 0) {
            if (layoutPVideoView.getMarginRight() <= videoWidthPx && 0 < originY) {


                int value = layoutPVideoView.getMarginRight() + originY * 9;//加速缩小
                if (value > videoWidthPx) {
                    value = (int) videoWidthPx;
                }
                float percent = (videoWidthPx - value) / videoWidthPx;
                if (0 > percent) {
                    percent = 0.f;
                }
                int videoHeight = (int) (videoMinHeightPx * (1 - percent));
                int videoMTop = (int) (allMinScrollY * (1 - percent));
                layoutPVideo.setMarginTop((int) (allScrollY + videoMTop));
                layoutPVideo.setHeight((int) (videoHeightPx - videoHeight));
                layoutPVideoView.setMarginRight(value);



                canHide = true;
                Log.i(TAG, "updateVideoView: "+isBottomMax);
                if (layoutPVideoView.getMarginRight() >= videoWidthPx) {
                    if (isBottomMax) {

                        layoutPVideo.setMarginTop(m);
                        float v = m - (allScrollY + allMinScrollY);
                        mVideoView.setAlpha(1.0f - v / swipePx2Dismiss);

                        if (v >= swipePx2Dismiss) {
                            setVisibility(INVISIBLE);
                            mVideoView.setAlpha(1f);
                        }
                    }
                }

                return;
            }//缩小视频右边距


            if (layoutPVideoView.getMarginRight() >= 0 && 0 > originY) {
                int value = layoutPVideoView.getMarginRight() + originY * 9;
//                if (0 > value) {
//                    value = 0;
//                }
                float percent = (videoWidthPx - value) / videoWidthPx;
                if (0 > percent) {
                    percent = 0.f;
                }
                int videoHeight = (int) (videoMinHeightPx * (1 - percent));
                int videoMTop = (int) (allMinScrollY * (1 - percent));
                layoutPVideo.setMarginTop((int) (allScrollY + videoMTop));
                layoutPVideo.setHeight((int) (videoHeightPx - videoHeight));
                layoutPVideoView.setMarginRight(value);
                return;
            }//放大视频右边距

            if (layoutPVideoView.getMarginRight() >= 0 && originY > 0) {

                return;
            }//最小化阶段


        }


        if (layoutPVideo.getMarginTop() <= 0 && originY < 0) {
            m = 0;
        }//最大化阶段

        float percent = (allScrollY - m) / allScrollY;
        if (0 > percent) {
            percent = 0;
            return;

        }

        int videoHeight = (int) (originalHeight - (originalHeight - videoHeightPx) * (1 - percent));
        int listHeight = (int) ((originListHeight) * (percent));
        layoutPVideo.setMarginTop(m);
        layoutPVideo.setHeight(videoHeight);
        layoutPList.setMarginBottom((int) (marginBottomPx * (1 - percent)));
        layoutPList.setHeight(listHeight);
        layoutPCoverView.getView().setAlpha((1 - percent));
        layoutPContainer.setMarginRight((int) (marginRLPx * (1 - percent)));
        layoutPContainer.setMarginLeft((int) (marginRLPx * (1 - percent)));
        int mr = (int) ((1f - percent) * marginPx); //VideoView右边和详情View 上方的margin
        layoutPVideo.setZ(mr / 2);//这个是Z轴的值,悬浮效果

    }

复制代码

ending

花了个把小时写的东西,希望给老铁们带来的是知识的储备而不是时间的浪费。不早了不早了下班了, 想要代码的老铁可以私信 留言都行


以上所述就是小编给大家介绍的《手把手教你撸最新Youtube视频 拖拽动画效果》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Web Design for ROI

Web Design for ROI

Lance Loveday、Sandra Niehaus / New Riders Press / 2007-10-27 / USD 39.99

Your web site is a business--design it like one. Billions of dollars in spending decisions are influenced by web sites. So why aren't businesses laser-focused on designing their sites to maximize thei......一起来看看 《Web Design for ROI》 这本书的介绍吧!

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具