内容简介:又到了金三银四的季节了,忙的人特别忙,面试啊,加班啊,闲的人也是特别闲吧,就比如我,天天划水,闲的写文章,做动画,同时呢各种新技术在不断的涌进,推动者软件行业的发展,不要焦虑,不要着急,学好本分,再扩展技能。不多说了,给大家看看做的效果吧。这个是原生的效果这个是做出来的效果
又到了金三银四的季节了,忙的人特别忙,面试啊,加班啊,闲的人也是特别闲吧,就比如我,天天划水,闲的写文章,做动画,同时呢各种新技术在不断的涌进,推动者软件行业的发展,不要焦虑,不要着急,学好本分,再扩展技能。不多说了,给大家看看做的效果吧。
这个是原生的效果
这个是做出来的效果
动画分解
动画分解其实很重要,如果说想模仿一个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事件 @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视频 拖拽动画效果》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
精通CSS与HTML设计模式
Michael Bowers / 刘申 朱瑜敏 鲁奇 / 人民邮电出版社 / 2008-9 / 69.00元
本书是一部非常实用的CSS 与HTML(XHTML)解决方案手册。书中包含了350 多种可以立即使用的设计模式(涉及文本、背景、边框、图片、表格、布局等多方面),并介绍了每种模式的原理和使用。每种设计模式、示例和源代码都经过了精心设计,易于实现和使用。通过阅读此书,可大大提高读者在 Web 设计和开发中的效率和创造力。 本书结构清晰,示例丰富,实践性强,适用于所有Web 开发和设计人员......一起来看看 《精通CSS与HTML设计模式》 这本书的介绍吧!