当前位置: 移动技术网 > IT编程>移动开发>Android > Android仿QQ好友详情页下拉顶部图片缩放效果

Android仿QQ好友详情页下拉顶部图片缩放效果

2019年07月30日  | 移动技术网IT编程  | 我要评论

北理人网上导航,中国好声音第三季歌曲试听,vcfeditor

今天已经是这个星期连续加班的第四天了,趁着现在后台在处理逻辑问题,将前几天写的一个小例子整理下来。

效果图

效果分析

1 向下滑动,头部的图片随着手指滑动不断变大
2 向上滑动,不断的向上移动图片,直到图片不可见
3 当顶部图片不可见时,向上滑动,滑动listview

实现思路

1 由于这个view分上下两部分,垂直排列,可以通过继承linearlayout实现::自定义一个dragimageview,该view继承linearlayout

public dragimageview(context context, attributeset attrs) {
 super(context, attrs);
 // 默认该view垂直排列
 setorientation(linearlayout.vertical);
 // 用于配合处理该view的惯性滑动
 mscroller = new overscroller(context);
 mtouchslop = viewconfiguration.get(context).getscaledtouchslop();
 mmaximumvelocity = viewconfiguration.get(context)
    .getscaledmaximumflingvelocity();
 mminimumvelocity = viewconfiguration.get(context)
    .getscaledminimumflingvelocity();
 }

2 onmeasure中设置内容视图的高度

@override
protected void onmeasure(int widthmeasurespec, int heightmeasurespec) {
 super.onmeasure(widthmeasurespec, heightmeasurespec);
 layoutparams params = (layoutparams) getchildat(1).getlayoutparams();
 // 头部可以全部隐藏,所以内容视图的高度即为该控件的高度
 params.height = getmeasuredheight();
}

3 设置imageview的scaletype属性

@override
protected void onfinishinflate() {
 super.onfinishinflate();
 imageview = (imageview) getchildat(0);
 // 随着手指滑动,图片不断放大(宽高都大于或者等于imageview的大小),并居中显示:
 // 根据上边的分析,center_crop:可以使用均衡的缩放图像(保持图像原始比例),使图片的两个坐标(宽、高)都大于等于 相应的视图坐标(负的内边距),图像则位于视图的中央
 imageview.setscaletype(scaletype.center_crop);
 listview = (listview) getchildat(1);
}

4 事件拦截

@override
public boolean onintercepttouchevent(motionevent ev) {
 if (ev.getaction() == motionevent.action_down) {
  downx = (int) ev.getx();
  downy = (int) ev.gety();
 }
 if (ev.getaction() == motionevent.action_move) {
  int currentx = (int) ev.getx();
  int currenty = (int) ev.gety();
  // 确保是垂直滑动
  if (math.abs(currenty - downy) > math.abs(currentx - downx)) {
   view childview = listview.getchildat(listview
     .getfirstvisibleposition());
   // 有两种情况需要拦截:
   // 1 图片没有完全隐藏
   // 2 图片完全隐藏,但是向下滑动,并且listview滑动到顶部
   if (getscrolly() != imageheight
     || (getscrolly() == imageheight && currenty - downy > 0
       && childview != null && childview.gettop() == 0)) {
    initvelocitytrackerifnotexists();
    mvelocitytracker.addmovement(ev);
    return true;
   }
  }

 }
 if (ev.getaction() == motionevent.action_up) {
  recyclevelocitytracker();
 }
 return super.onintercepttouchevent(ev);
}

5 ontouchevent的action_move处理

if (ev.getaction() == motionevent.action_move) {
  int currentx = (int) ev.getx();
  int currenty = (int) ev.gety();
  int deltyx = currentx - downx;
  int deltyy = currenty - downy;
  if (math.abs(deltyy) > math.abs(deltyx)) {
   if (deltyy > 0) {
    if (getscrolly() > 0) {
     if (getscrolly() - deltyy < 0) {
      scrollby(0, -getscrolly());
      return true;
     }
     // 当图片没有完全显示,并且向下滑动时,继续整个view使图片可见
     scrollby(0, -deltyy);
    } else {
    // 当图片完全显示,并且向下滑动时,则不断的放大图片(通过改变imageview)的高度
     layoutparams layoutparams = (layoutparams) getchildat(0)
       .getlayoutparams();
     layoutparams.height = layoutparams.height + deltyy / 2;
     getchildat(0).setlayoutparams(layoutparams);
    }
   } else {
   // 当图片还处于放大状态,并且向上滑动时,继续不断的缩小图片的高度,使图片缩小
    if (getchildat(1).gettop() > imageheight) {
     layoutparams layoutparams = (layoutparams) getchildat(0)
       .getlayoutparams();
     layoutparams.height = layoutparams.height + deltyy / 2;
     getchildat(0).setlayoutparams(layoutparams);
    } else {
    // 当图片处于正常状态,并且向上滑动时,移动整个view,缩小图片的可见范围
     if (getscrolly() - deltyy > imageheight) {
      scrollby(0, imageheight - getscrolly());
      return true;
     }
     scrollby(0, -deltyy);
    }
   }
   downy = currenty;
   downx = currentx;
   return true;
  }
 }

5 ontouchevent的action_up处理

if (ev.getaction() == motionevent.action_up) {
 // 当图片处于放大状态时松手,使图片缓慢的缩回到原来的状态
 if (getchildat(1).gettop() > imageheight) {
  isanimating = true;
  valueanimator valueanimator = valueanimator.ofint(getchildat(1)
    .gettop(), imageheight);
  valueanimator.setduration(300);
  valueanimator.addupdatelistener(new animatorupdatelistener() {
   @override
   public void onanimationupdate(valueanimator animation) {
    int value = (integer) animation.getanimatedvalue();
    layoutparams layoutparams = (layoutparams) getchildat(0)
      .getlayoutparams();
    layoutparams.height = value;
    getchildat(0).setlayoutparams(layoutparams);
   }
  });
  valueanimator.addlistener(new animatorlisteneradapter() {
   @override
   public void onanimationend(animator animation) {
    super.onanimationend(animation);
    isanimating = false;
   }
  });
  valueanimator.start();
 }
 // 当现在图片处于正常状态,并且图片没有完全隐藏,并且松手时滑动的速度大于可惯性滑动的最小值,让view产生惯性滑动效果
 if (getchildat(1).gettop() == imageheight
   && getscrolly() != imageheight) {
  mvelocitytracker.computecurrentvelocity(1000, mmaximumvelocity);
  int velocityy = (int) mvelocitytracker.getyvelocity();
  if (math.abs(velocityy) > mminimumvelocity) {
   fling(-velocityy);
  }
  recyclevelocitytracker();
 }

总结

这里主要有两个学习的点

1 图片缩放的处理,事件的拦截

2 view的惯性滑动:主要是结合overscroller的使用

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网