资源下载(2C币)

逛CSDN的时候,看到几篇写仿今日头条图片滑动退出效果的文章,闲着无聊便想着也给自己项目加上,实现的思路有很多种,本着就近原则选了一篇与自己思路相近的文章结合自己的实践总结一下。

下载原文的Demo用了一下,发现了几点可以优化的地方:

1、图片缩放上不太好使,放大缩小的同时就给你滑出去了

2、没有暴露接口给用户实现更多的透明度变换效果,比如我不仅想要背景透明度在手指移动的时候发生变化,还有文字或者其他内容也跟着发生透明度变化

3、去掉了一些多余代码

实现效果

  1. 在上滑或者下滑时,随着手指的移动,图片区域跟随移动,并且activity的背景和页码逐渐变的透明
  2. 上下滑动距离不超过设定的临界值时,会有回弹效果。
  3. 上下滑动超过设置的临界值时,放开手指,页面滑动退出消失
  4. 图片可以正常放大缩小,页面不跟随手指上下滑动
  5. 页面切换淡入淡出效果

实现原理

实现思路有很多种,这种实现思路对我当前项目改动最小,只是在原来的页面上嵌套了一个中间层,在这个中间层上做手脚,根据Android的事件分发机制,在中间层判断当前手指的移动距离和方向选择是否拦截事件交由自己处理,实现上下滑动退出的效果,并且不影响图片正常的放大缩小和切换。

中间层容器实现过程

重写onInterceptTouchEvent()

这个方法是本次效果实现的核心,用于处理不同的手势操作,处理的好则各种手势不发生冲突。这里返回ture意味着判断当前操作为要退出页面,需要将事件拦截交由自己处理,开始跟随手指的移动发生滑动动画。返回false则不对事件进行拦截,交由下面控件处理,比如切换图片、放大缩小。

上面提到的原Demo中对于图片放大缩小的同时页面发送滑动退出的情况,在这里我加了一个多点触控的判断,当触摸屏幕的点大于一个时认为是对图片进行放缩或者切换,所以直接返回false。当触摸点只有一个时,判断手指在X、Y轴移动的距离更多的是上下滑动还是左右滑动,认定上下滑动时拦截事件进入自己的onTouchEvent()处理动画,左右滑动则不拦截,交由viewPager进行图片切换。

@Overridepublic boolean onInterceptTouchEvent(MotionEvent ev) {//判断几指操作,大于1时认为在对图片进行放大缩小操作,不拦截事件//交由下面控件处理if (ev.getPointerCount() > 1) {return false;} else {final int y = (int) ev.getRawY();final int x = (int) ev.getRawX();switch (ev.getAction()) {case MotionEvent.ACTION_DOWN:previousX = x;previousY = y;break;case MotionEvent.ACTION_MOVE:int diffY = y - previousY;int diffX = x - previousX;//当Y轴移动距离大于X轴50个单位时拦截事件//进入onTouchEvent开始处理上下滑动退出效果if (Math.abs(diffX) + 50 < Math.abs(diffY)) {return true;}break;}return false;}}

重写onTouchEvent()

事件被拦截后就会走这个方法,这里主要是根据手指位移对动画的操作,原Demo中判断方向的代码被我去掉了,因为原代码里的direction永远是UP_DOWN,多余不如去掉。这里我增加了一个回调供外部使用,参数是当前的透明度。

@Overridepublic boolean onTouchEvent(@NonNull MotionEvent ev) {final int y = (int) ev.getRawY();final int x = (int) ev.getRawX();switch (ev.getAction()) {case MotionEvent.ACTION_DOWN:previousX = x;previousY = y;break;case MotionEvent.ACTION_MOVE:int diffY = y - previousY;//判断手指向上还是向下移动,关联手指抬起后的动画位移方向isScrollingUp = diffY <= 0;this.setTranslationY(diffY);if (mBackground != null) {//透明度跟随手指的移动距离发生变化int alpha = (int) (255 * Math.abs(diffY * 1f)) / getHeight();mBackground.setAlpha(255 - alpha);//回调给外面做更多操作mScrollListener.onLayoutScrolling(alpha / 255f);LogUtil.i("alpha is " + alpha);}break;case MotionEvent.ACTION_UP:int height = this.getHeight();//滑动距离超过临界值才执行退出动画,临界值为控件高度1/4if (Math.abs(getTranslationY()) > (height / 4)) {//执行退出动画layoutExitAnim();} else {//执行恢复动画layoutRecoverAnim();}}return true;}

退出动画

这个方法也去掉了一些代码

public void layoutExitAnim() {ObjectAnimator exitAnim;//从手指抬起的位置继续向上或向下的位移动画exitAnim = ObjectAnimator.ofFloat(this, "translationY", getTranslationY(), isScrollingUp ? -getHeight() : getHeight());exitAnim.addListener(new AnimatorListenerAdapter() {@Overridepublic void onAnimationEnd(Animator animation) {//动画结束时将背景置为完全透明if (mBackground != null) {mBackground.setAlpha(0);}//执行回调,退出页面if (mScrollListener != null) {mScrollListener.onLayoutClosed();}}});exitAnim.addUpdateListener(animation -> {if (mBackground != null) {//根据位移计算设置背景透明度int alpha = (int) (255 * Math.abs(getTranslationY() * 1f)) / getHeight();mBackground.setAlpha(255 - alpha);}});exitAnim.setDuration(200);exitAnim.start();}

恢复动画

加了一个回调供外部调用

private void layoutRecoverAnim() {//从手指抬起的地方恢复到原点ObjectAnimator recoverAnim = ObjectAnimator.ofFloat(this, "translationY", this.getTranslationY(), 0);recoverAnim.setDuration(100);recoverAnim.start();if (mBackground != null) {//将背景置为完全不透明mBackground.setAlpha(255);mScrollListener.onLayoutScrollRevocer();}}

接口回调

public interface LayoutScrollListener {//关闭布局void onLayoutClosed();//正在滑动void onLayoutScrolling(float alpha);//滑动结束并且没有触发关闭void onLayoutScrollRevocer();}

使用

布局文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".activity.ImagesActivity"><com.zhicun.tieqi.widget.SlideCloseLayoutandroid:id="@+id/slide_close_layout"android:layout_width="match_parent"android:layout_height="match_parent"><com.luck.picture.lib.widget.PreviewViewPagerandroid:id="@+id/img_viewpager"android:layout_width="match_parent"android:layout_height="match_parent" /></com.zhicun.tieqi.widget.SlideCloseLayout><TextViewandroid:id="@+id/index"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:gravity="center_horizontal"android:padding="10dp"android:textColor="@color/white"tools:text="3/9" />
</RelativeLayout>

Activity

 //设置activity的背景为黑色getWindow().getDecorView().setBackgroundColor(Color.BLACK);
//给控件设置需要渐变的背景。如果没有设置这个,则背景不会变化mSlideCloseLayout.setGradualBackground(getWindow().getDecorView().getBackground());//设置监听,滑动一定距离后让Activity结束mSlideCloseLayout.setLayoutScrollListener(new SlideCloseLayout.LayoutScrollListener() {@Overridepublic void onLayoutClosed() {onBackPressed();}@Overridepublic void onLayoutScrolling(float alpha) {mIndex.setAlpha(1 - (alpha * 5f));}@Overridepublic void onLayoutScrollRevocer() {mIndex.setAlpha(1);}});

重写返回建事件实现淡入淡出切换效果

 @Overridepublic void onBackPressed() {finish();overridePendingTransition(R.anim.fade_in, R.anim.fade_out);}

淡入淡出动画

fade_in

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"android:interpolator="@android:anim/decelerate_interpolator"><alphaandroid:duration="@android:integer/config_mediumAnimTime"android:fromAlpha="0"android:toAlpha="1" />
</set>

fade_out

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"android:interpolator="@android:anim/decelerate_interpolator"><alphaandroid:duration="@android:integer/config_mediumAnimTime"android:fromAlpha="1"android:toAlpha="0" />
</set>

设置Activity主题

<style name="SlideCloseTheme" parent="Theme.AppCompat.Light.NoActionBar"><item name="windowNoTitle">true</item><item name="android:windowIsTranslucent">true</item><item name="android:windowBackground">@android:color/transparent</item><item name="android:windowNoTitle">true</item>
</style>

------------------------------------------------------------------------------------------------------------------------

到此改造就完成啦,效果用起来不错,本次内容的核心理解就是安卓的事件分发机制,如果对它还不了解的,理解了它再来看本片文章就会轻松许多了,对于已经理解并熟练掌握的大佬就当复习一遍知识吧~

Android仿今日头条图片滑动退出效果相关推荐

  1. android 今日头条加载动画,Android 仿今日头条简单的刷新效果实例代码

    点击按钮,先自动进行下拉刷新,也可以手动刷新,刷新完后,最后就多一行数据.有四个选项卡. 前两天导师要求做一个给本科学生预定机房座位的app,出发点来自这里.做着做着遇到很多问题,都解决了.这个效果感 ...

  2. Android 仿今日头条首页标题栏效果

    今天带来的是仿今日头条首页的联动滑动效果,废话不多说,先上效果图: 思路: 做这个我们需要实现的效果有 1.滑动内容区域,标题栏会有变化来显示当前所处的位置. 2.点击标题栏,内容区域也会随着滑动并跳 ...

  3. Android 仿今日头条评论时键盘自动弹出的效果

    Android 仿今日头条评论时键盘自动弹出的效果:当点击评论时,弹出对话框,同时弹出软键盘,当点击返回键时,将对话框关闭,不只是关闭软键盘. 效果图: 对这个对话框设置一个style效果: < ...

  4. 转载 Android仿今日头条详情页实现

    转载自@ice_Anson Android仿今日头条详情页实现 源码地址: Android仿今日头条详情页实现 github源码地址 动态图 最近项目有个需求,需要实现一个和今日头条新闻详情页一样的体 ...

  5. Android仿今日头条首页的顶部标签栏和底部导航栏

    Android仿今日头条首页的顶部标签栏和底部导航栏 先是底部导航栏TextView+ImageView+Fragment: 效果图: activity_main.xml布局: <?xml ve ...

  6. android仿今日头条个人中心页面

    android仿今日头条个人中心页面 效果图 实现步骤: 自定义ScrollView,添加一个反弹的动画 代码: package com.example.administrator.gerenzhon ...

  7. Android 仿今日头条频道管理(下)(GridView之间Item的移动和拖拽)

    前言 上篇博客我们说到了今日头条频道管理的操作交互体验,我也介绍了2个GridView之间Item的相互移动.详情请參考:Android 仿今日头条频道管理(上)(GridView之间Item的移动和 ...

  8. html仿今日头条下拉刷新,小程序 仿今日头条 带滑动切换的文章列表

    小程序 仿今日头条 带滑动切换的文章列表 发布时间:2018-07-19 09:41, 浏览次数:353 拿别人仿今日头条的代码做的改版, 首先感谢前辈.其次,这个代码虽然能用,但是js里还是存在一些 ...

  9. Android仿今日头条的开源项目

    起因 看到众多大神纷纷有了自己的开源项目,于是自己琢磨着也想做一个开源项目来学习下,因为每次无聊必刷的app就是今日头条,评论简直比内容都精彩,所以我打算仿今日头条来练练手,期间也曾放弃过,也遇到很多 ...

最新文章

  1. Android应用程序组件Content Provider的启动过程源代码分析(6)
  2. python 设计模式 原型模式_python设计模式–原型模式
  3. access 一亿条数据_循环运算数据溢出
  4. 关于Strut2内置Json插件的使用
  5. 36条网络安全术语盘点——Vecloud
  6. wxWidgets:wxWebViewEvent类用法
  7. linux 一个超简单的makefile
  8. 区分大小屏幕_第一个Python程序——在屏幕上输出文本
  9. DOM方式解析XML文件实例
  10. 腾讯校园招聘笔试 2019-8-17 第五题
  11. (转载)C#中如何获取当前路径的几种方法
  12. html5中加入音乐怎么弄,H5秀添加音乐和视频的编辑方式
  13. 浅谈如何提高电子海图拼图的正确率
  14. 明御安全网关(IPS)批量导入黑名单IP
  15. 万万没想到,低功耗也会烧毁元器件?
  16. word 插入mathtype公式对象后,默认环绕方式是浮于文字上方,每次插入后都得手动改成嵌入,如何解决?
  17. 如何在Linux上的命令行中设置Google Chrome浏览器的代理设置?
  18. 严厉打击恶意劫持 百度移动搜索推出烽火算法2.0
  19. php 解压文件中有中文,ZipArchive 解压中文文件乱码解决方案和疑惑
  20. java 固定长度的集合

热门文章

  1. 计算机音乐红色彼岸花,《抖音》红色彼岸花花瓣遍地撒是什么歌
  2. 零代码组态:搭建智慧水泥生产工艺流程
  3. 【Datawhale组队学习】机器学习数学基础 - 一元函数微分学的几何应用【Task 04】
  4. pgAdmin4 汉化
  5. 逼自己养成成长型思维模式
  6. 华三模拟器命令(陆续更新)
  7. 计算机一级是几寸的,笔记本电脑尺寸一般是多少(笔记本电脑买几寸的比较合适)...
  8. canvas教程9-线型的属性
  9. 高仿知乎android,Android高仿知乎首页Behavior
  10. TableauBDP,哪个才是最适合中国用户的数据可视化分析工具?