手把手教你撸最新Youtube视频 拖拽动画效果
前言
又到了金三银四的季节了,忙的人特别忙,面试啊,加班啊,闲的人也是特别闲吧,就比如我,天天划水,闲的写文章,做动画,同时呢各种新技术在不断的涌进,推动者软件行业的发展,不要焦虑,不要着急,学好本分,再扩展技能。不多说了,给大家看看做的效果吧。
这个是原生的效果
这个是做出来的效果
动画分解
动画分解其实很重要,如果说想模仿一个App的动画及交互效果,一定要仔细的观察他在交互细到放慢每一个操作,然后在根据这个动态来写代码。不然最后实现的效果不一样,那岂不是白费了。废话不多说,上代码看步骤。
第一步视频原始状态分析
可以看到,视频最初始的状态是由一个VideoView(可以是surfaceview都行),加上一个list吧,上下布局,但是VideoView呢,他是根据视频尺寸大小动态的调整宽高的,而不是固定的,我们来分析这个过程
- 第一种下拉的时候如果视频的高度没有达到原生高度,这时候下面的listview 不能消费touch事件,由videoview来消费这个事件,根据当前的下滑Y值进行调整视频宽高比
- 第二种情况是如果listview已经滑动了一部分这时候进行下拉,但是viewvideo还没有到达真是高度,这时候touch事件还是由listview消费,当他滑动到顶部的时候进行拦截touch 然后传递给videoview
- 第三中情况,当listview 向下快速滑动的时候会有个惯性的过程,即使手离开手机了 listview还是在滑动,我们称为惯性滑动,到惯性滑动到顶部的时候,如果视频高度没有达到原生高度,这时候要根据这个惯性值来调整调整视频高度。
第二步 视频下滑过程分析
由上图可以看到当我们在下拉视频的时候,视频的顶部 左右边距 机listview 都发生改变,同时videoview高度也发生了变化。
- 下拉的时候margin的 left right top bottom值都在发生改变,videoview 的高度也在发送改变,同时listview 渐渐消失,变成白色的背景,listview的高度在逐渐变小,同时可以看到在Z轴也发生了改变。可能图片不清晰,看不出Z轴的变换
- 下拉到listview消失的时候,这时候videoview的宽度发生改变,同时控制器出现。这时候videoview宽度还是在一直的缩小。
- 当达到了最小视频悬浮层的时候,下拉整个视图越来越透明,同时整个布局在根据手势在下滑。
第三步 视频上滑过程分析
上滑过程其实就是把下滑过程反过来而已,这里我就不再过多追溯了。
撸代码
主要的逻辑在上面都有,下面我就简单的对上面的逻辑进行分析一下,整体代码想要的老铁私信我留言都行
如何对listview和videoview进行touch的分发
这里我使用的是一个LinearLayout作为父布局进行组装这两个子view,然后根据viewgroup的dispatchTouchEvent方法里面加判断进行事件的分发。网上这些代码很多我就不详细赘述了,其实我这里还是有很多可以优化的地方,这只是个demo。
- 和上面动画分解的逻辑一致,一看videoview 是否达到最大值,listview是否在顶部。
- listview(我这边用的时候recyclerview都一样)是否在顶部可以通过调用addOnScrollListener()来判断是否是第一个可见的item *判断videoview是否达到最大值呢,根据视频的宽高来。可以通过Mediaplayer来获取,
//分发recyclerview和videoview事件@Overridepublic 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 上方的marginlayoutPVideo.setZ(mr / 2);//这个是Z轴的值,悬浮效果}复制代码
ending
花了个把小时写的东西,希望给老铁们带来的是知识的储备而不是时间的浪费。不早了不早了下班了,想要代码的老铁可以私信 留言都行。
手把手教你撸最新Youtube视频 拖拽动画效果相关推荐
- 贝塞尔曲线(Bezier)之 QQ 消息拖拽动画效果
博主声明: 转载请在开头附加本文链接及作者信息,并标记为转载.本文由博主 威威喵 原创,请多支持与指教. 本文首发于此 博主:威威喵 | 博客主页:https://blog.csdn.net/ ...
- 仿炫酷头条小视频拖拽动画
本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布 序言 时光荏苒,又是一年高考季,不知不觉中距离高考已经七年过去了,在我眼中依稀能够嗅到那个夏天的味道,朋友的道别,得知成绩后的苦涩, ...
- 【Three.js】手把手教你在三维场景中实现人物行走动画效果
three.js的官方例程里面有个人物行走的案例,链接如下: three.js官方案例-人物行走 这里简单剖析下人物行走的原理: (1) 首先需要有个动画素材.gltf是可以集成动画的,像行人行走的动 ...
- 手把手教你撸一个Web汇率计算器
手把手教你撸一个Web汇率计算器 前言 前段时间刚接触到前端网页开发,但是对于刚入门的小白而言,像flask.Django等这类稍大型的框架确实不太适合,今天这个Dash是集众家之长于一体的轻量化We ...
- 手把手教你做一个物联网视频监控项目(三)流媒体方案实现
往期文章 手把手教你做一个物联网视频监控项目(一) 介绍 手把手教你做一个物联网视频监控项目(二)MJPG-streamer方案实现 文章目录 前言 一.软硬件准备 二.流媒体方案的实现之FFmpeg ...
- 手把手教你撸Redis
手把手教你撸Redis Redis入门 一. 什么是Redis 二. Redis能干嘛 三. Redis和Memcached区别 四. 为什么使用Redis 五. Redis为什么单线程还这么快 六. ...
- 微信小程序手把手教你实现类似Android中ViewPager控件效果
微信小程序手把手教你实现类似Android中ViewPager控件效果 前言 需求分析 头部TAB 滑动的内容部分 最终版本 尾巴 前言 在做Android开发的时候,ViewPager是开发者使用频 ...
- Range回源和视频拖拽播放
1. Range回源 Range回源是指客户端通知源站服务器只返回部分内容,以及部分内容的范围.这对于较大文件的分发加速有很大帮助.开启Range回源功能,可以减少回源流量消耗,并且提升资源响应时间. ...
- android qq消息数 拖拽动画,史上最详细仿QQ未读消息拖拽粘性效果的实现
好久没写文章了,前段时间由于项目代码重构忙了一段时间,现在终于有点时间了就为大家带来一篇关于动画学习的自定义View:类似QQ消息拖拽的效果. 其实QQ当时更新的时候我还没注意到这个小红点是可以拖拽的 ...
最新文章
- php 7 显示错误信息,PHP 7 错误处理
- 面了个 32+ 岁 Java 大佬,一言难尽......
- 汇总|基于激光雷达的3D目标检测开源项目数据集
- python语法基础知识-python基础必学的语法知识
- Excel中去掉单元格中间的空格
- linux macos 界面对比,GNOME 3与Mac OS X 10.7 (Lion)的纵览模式比较
- 微软总裁比尔.盖茨给即将走出学校、踏入社会的青年一代下列11点忠告
- java获取元素创建时间,java – 动态顺序统计:在恒定时间内获取第k个元素?
- frisby用例动态链
- WEBRTC TURNSERVER配置
- Centos7 自动使用葵花8号卫星图片作为桌面壁纸
- DiffuseBumpCutout‘: invalid subscript ‘boxMax‘ at line 151
- H5标签input标签上传文件(图片)
- 微信小程序自定义picker
- 数学推导+纯Python实现机器学习算法22:EM算法
- Oracle11g新特性之Replay a captured workload 捕获工作负载新环境重放负载测试压力
- Android手机开机动画制作
- 数电课设之一路交通灯
- PMP可以自学报考吗
- 《去哪儿网支付系统架构演进全历程》阅读有感
热门文章
- INS-20802 Windows安装Oracle19c报错解决方案
- 想要专升本你不得不看的全干货_吐血整理_专升本_计算机文化基础(一)
- diskgenius分区教程(diskgenius分区教程)
- 以实验理解交换机原理
- 德鲁克:这4种创新方式,使变化成为机会
- 移动web——学习笔记整理
- Revit 视图范围的知识总结
- PetShop的系统架构设计(转Bruce Zhang(wayfarer) )
- 【 C++入门 】引用
- 【实战案例】分享6种常用的信用卡欺诈检测算法(附 Python 代码)