Android仿QQ好友详情页下拉顶部图片缩放效果
程序员文章站
2022-04-12 11:36:11
今天已经是这个星期连续加班的第四天了,趁着现在后台在处理逻辑问题,将前几天写的一个小例子整理下来。
效果图
效果分析
1 向下滑动,头部的图片随着手指滑动不断...
今天已经是这个星期连续加班的第四天了,趁着现在后台在处理逻辑问题,将前几天写的一个小例子整理下来。
效果图
效果分析
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的使用
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: golang module 下载外网资源失败解决办法
下一篇: BearerToken之JWT的介绍