当前位置: 移动技术网 > 移动技术>移动开发>Android > Android实现果冻滑动效果的控件

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

2019年07月24日  | 移动技术网移动技术  | 我要评论
前言 在微信是的处理方法是让用户滑动,但最终还是回滚到最初的地方,这样的效果很生动(毕竟成功还是取决于细节)。那么在安卓我们要怎么弄呢。下面为大家介绍一下jellyscr

前言

在微信是的处理方法是让用户滑动,但最终还是回滚到最初的地方,这样的效果很生动(毕竟成功还是取决于细节)。那么在安卓我们要怎么弄呢。下面为大家介绍一下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

总结

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

如您对本文有疑问或者有任何想说的,请 点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网