当前位置: 首页 > 编程笔记 >

Android实现果冻滑动效果的控件

谷泳
2023-03-14
本文向大家介绍Android实现果冻滑动效果的控件,包括了Android实现果冻滑动效果的控件的使用技巧和注意事项,需要的朋友参考一下

前言

在微信是的处理方法是让用户滑动,但最终还是回滚到最初的地方,这样的效果很生动(毕竟成功还是取决于细节)。那么在安卓我们要怎么弄呢。下面为大家介绍一下JellyScrollView,是我继承ScrollView的一个有阻尼的效果的果冻滑动控件。

下面话不多说了,先来看看效果图

(在虚拟机或者真机跑起来是很流畅,可能是录制视频做成gif的时候有点卡顿。)

实现原理

其实只需要重写下它的拦截方法的逻辑就好了,ScrollView的拦截方法onInterceptTouchEvent一般情况下都默认地返回false,表示不拦截该事件。我们只需要在用户滑动了界面的情况下,拦截下来并移动布局就好了,当用户松开手就恢复布局。很简单

第一步:集成ScrollView重写几个构造方法;

第二步:重写下onFinishInflate方法,获得第一个子view;

第三步:在拦截方法里面处理上面所说的逻辑;

public class JellyScrollView extends ScrollView {
 
 private View inner;// 子View
 
 private float y;// 点击时y坐标
 
 private Rect normal = new Rect();// 矩形(这里只是个形式,只是用于判断是否需要动画.)
 
 private boolean isCount = false;// 是否开始计算
 
 private boolean isMoving = false;// 是否开始移动.
 
 private int top;// 拖动时时高度。
 
 private int mTouchSlop;//系统最少滑动距离
 
 public JellyScrollView(Context context) {
  super(context);
 }
 
 public JellyScrollView(Context context, AttributeSet attrs) {
  super(context, attrs);
 }
 
 public JellyScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
  super(context, attrs, defStyleAttr);
  mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
 }
 
 /***
 * 根据 XML 生成视图工作完成.该函数在生成视图的最后调用,在所有子视图添加完之后. 即使子类覆盖了 onFinishInflate
 * 方法,也应该调用父类的方法,使该方法得以执行.
 */
 @Override
 protected void onFinishInflate() {
  if (getChildCount() > 0) {
   inner = getChildAt(0);
  }
 }
 
 
 /**拦截事件*/
 @Override
 public boolean onInterceptTouchEvent(MotionEvent ev) {
  if (inner != null) {
   int action = ev.getAction();
   switch (action) {
    case MotionEvent.ACTION_DOWN:
     y = ev.getY();
     top = 0;
     break;
 
    case MotionEvent.ACTION_UP:
     // 手指松开.
     isMoving = false;
     if (isNeedAnimation()) {
      animation();
     }
     break;
    /***
    * 排除出第一次移动计算,因为第一次无法得知y坐标, 在MotionEvent.ACTION_DOWN中获取不到,
    * 因为此时是ScrollView的touch事件传递到到了ListView的子item上面.所以从第二次计算开始.
    * 然而我们也要进行初始化,就是第一次移动的时候让滑动距离归0. 之后记录准确了就正常执行.
    */
    case MotionEvent.ACTION_MOVE:
     final float preY = y;// 按下时的y坐标
     float nowY = ev.getY();// 每时刻y坐标
     int deltaY = (int) (nowY - preY);// 滑动距离
     if (!isCount) {
      deltaY = 0; // 在这里要归0.
     }
 
     if (Math.abs(deltaY) < mTouchSlop && top <= 0)
      return true;
 
     // 当滚动到最上或者最下时就不会再滚动,这时移动布局
     isNeedMove();
 
     if (isMoving) {
      // 初始化头部矩形
      if (normal.isEmpty()) {
       // 保存正常的布局位置
       normal.set(inner.getLeft(), inner.getTop(), inner.getRight(), inner.getBottom());
      }
 
      // 移动布局
      inner.layout(inner.getLeft(), inner.getTop() + deltaY / 3, inner.getRight(), inner.getBottom() + deltaY / 3);
 
      top += (deltaY / 6);
     }
 
     isCount = true;
     y = nowY;
     break;
   }
  }
  return super.onInterceptTouchEvent(ev);
 }
 
 
 /***
 * 回缩动画
 */
 public void animation() {
  // 开启移动动画
  TranslateAnimation ta = new TranslateAnimation(0, 0, inner.getTop(), normal.top);
  ta.setDuration(200);
  inner.startAnimation(ta);
 
  // 设置回到正常的布局位置
  inner.layout(normal.left, normal.top, normal.right, normal.bottom);
  normal.setEmpty();
 
  // 手指松开要归0.
  isCount = false;
  y = 0;
 }
 
 // 是否需要开启动画
 public boolean isNeedAnimation() {
  return !normal.isEmpty();
 }
 
 /***
 * 是否需要移动布局
 * inner.getMeasuredHeight():获取的是控件的总高度
 * getHeight():获取的是屏幕的高度
 *
 * @return
 */
 public void isNeedMove() {
  int offset = inner.getMeasuredHeight() - getHeight();
  int scrollY = getScrollY();
  // scrollY == 0是顶部
  // scrollY == offset是底部
if (scrollY == 0 || scrollY == offset) {
 isMoving = true;
}
 }
}

然后在布局里面在最外层就使用我们的JellyScrollView

(为了方便展示,我只是大概写了一部分布局代码)

<?xml version="1.0" encoding="utf-8"?><cn.ichengxi.fang.view.JellyScrollView xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:background="@color/bg"
 android:scrollbars="none">
 
 <LinearLayout  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:orientation="vertical">
  <TextView   android:id="@+id/personal_setting_txt"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:alpha="0.8"
   android:gravity="center_vertical"
   android:text="设置"
   android:textColor="@android:color/black" />
 
 </LinearLayout></cn.ichengxi.fang.view.JellyScrollView>12345678910111213141516171819202122231234567891011121314151617181920212223

总结

好了,这样就可以很优雅的实现了果冻控件的效果啦。以上就是本文的全部内容了,希望这篇文章的内容对大家能有所帮助,如果有疑问大家可以留言交流。

 类似资料:
  • 本文向大家介绍android viewpager实现竖屏滑动效果,包括了android viewpager实现竖屏滑动效果的使用技巧和注意事项,需要的朋友参考一下 Viewpager 横向滑动效果系统就自带了很多种,比如这个 效果 那如果做成竖屏的这种效果呢 。我百度过很多,效果都不是很好,有的代码特别多而且存在很多问题。我结合了以前别人的代码现在来教大家个简单的实现过程。 首先自定义Viewpa

  • 本文向大家介绍Android实现滑动刻度尺效果,包括了Android实现滑动刻度尺效果的使用技巧和注意事项,需要的朋友参考一下 最近群里的开发人员咨询怎样实现刻度尺的滑动效果去选择身高体重等信息。给个横着的效果,自己试着去改编或者修改一下,看看通过自己的能力能不能做出竖着的效果来,过两天我再把竖着的那个滑动选择效果分享出来。废话不多说了,上代码。 效果图如下: 第一步:activity_mian.

  • 本文向大家介绍JavaScript实现滑动门效果,包括了JavaScript实现滑动门效果的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了JavaScript实现滑动门效果的具体代码,供大家参考,具体内容如下 一、什么是滑动门 首先你要了解什么是滑动门。 生活中我们经常看到一些网站或是商城有一些滑动门的效果 那么怎么实现一个简单的滑动门的网页特效呢?下面简单分享一下方法, 二、实现滑

  • 本文向大家介绍Android实现探探图片滑动效果,包括了Android实现探探图片滑动效果的使用技巧和注意事项,需要的朋友参考一下 之前一段时间,在朋友的推荐下,玩了探探这一款软件,初玩的时候,就发现,这款软件与一般的社交软件如陌陌之类的大相径庭,让我耳目一新,特别是探探里关于图片滑动操作让人觉得非常新鲜。所以在下通过网上之前的前辈的经历加上自己的理解,也来涉涉水。下面是网上找的探探的原界面 当时

  • 本文向大家介绍Android实现横向滑动卡片效果,包括了Android实现横向滑动卡片效果的使用技巧和注意事项,需要的朋友参考一下 最近项目上需要实现这样效果的一个页面,本来想找个现成的两下搞定,但是问了半天度娘也没招,索性自己琢磨琢磨(这里边也少不了同事的帮助),先把最终的效果图贴上: 理论上讲,其本质并不复杂,就是一个viewpager,但是第一次实现这样的效果还是要花些时间的,具体的代码如下

  • 本文向大家介绍Android ViewPager实现左右滑动翻页效果,包括了Android ViewPager实现左右滑动翻页效果的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了ViewPager实现左右滑动翻页效果展示的具体代码,供大家参考,具体内容如下 代码如下: 布局文件: 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。

  • 本文向大家介绍Android使用Scroller实现弹性滑动效果,包括了Android使用Scroller实现弹性滑动效果的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了Android使用Scroller实现弹性滑动展示的具体代码,供大家参考,具体内容如下 scrollTo、scrollBy View内部为了实现滑动提供了这两个方法,但是使用这两个方法滑动的效果是瞬间的不够平滑,如何

  • 本文向大家介绍javascript图片滑动效果实现,包括了javascript图片滑动效果实现的使用技巧和注意事项,需要的朋友参考一下 本文为大家分享了javascript图片滑动效果实现方法,具体内容如下,先看一下效果图: 鼠标滑过那张图,显示完整的哪张图,移除则复位: 简单的CSS加JS操作DOM实现: css: js操作: 更多关于滑动效果的专题,请点击下方链接查看: javascript滑