Android中ScrollView 滑到头部或尾部可伸缩放大效果

Android中ScrollView 滑到头部或尾部可伸缩放大效果,第1张

概述最近做项目,想要这么一个效果,就是ScrollView滑动到顶部,当不能在滑动的时候,图片可以下拉放大,松开又恢复。滑到底部没有内容的时候,也有伸缩效果,先看看效果图吧。

最近做项目,想要这么一个效果,就是ScrollVIEw 滑动到顶部,当不能在滑动的时候,图片可以下拉放大,松开又恢复。滑到底部没有内容的时候,也有伸缩效果,先看看效果图吧。

就是如上图这么个效果。系统提供的ScrollVIEw 是不能做到这个效果的,所以需要自己自定义,网上找了一些资料。也参考了下其他人的做法。自己也整合了一下。希望对大家有所帮助。

核心的控件就是下面的这段代码:

package com.kokjuis.travel.customVIEw; import androID.animation.ObjectAnimator; import androID.animation.ValueAnimator; import androID.content.Context; import androID.graphics.Rect; import androID.util.AttributeSet; import androID.vIEw.MotionEvent; import androID.vIEw.VIEw; import androID.vIEw.VIEwGroup; import androID.vIEw.animation.TranslateAnimation; import androID.Widget.ScrollVIEw; /**  * 注意使用的时候需要放大的vIEw,一般是第一个relativeLayout或者linearLayout。要加上 androID:layout_gravity="center_horizontal"  * <p>  * Created by kokJuis on 2017/3/14. [email protected]  */ public class BounceZoomScrollVIEw extends ScrollVIEw {  private static final String TAG = "BounceScrollVIEw";  //----头部收缩属性--------  // 记录首次按下位置  private float mFirstposition = 0;  // 头部图片是否正在放大  private Boolean mScaling = false;  private VIEw dropZoomVIEw;//需要被放大的vIEw  private int dropZoomVIEwWIDth;  private int dropZoomVIEwHeight;  //----头部收缩属性end--------  //------尾部收缩属性--------  private VIEw inner;// 子VIEw  private float y;// 点击时y坐标  private Rect normal = new Rect();// 矩形(这里只是个形式,只是用于判断是否需要动画.)  private boolean isCount = false;// 是否开始计算  //最后的坐标  private float lastX = 0;  private float lastY = 0;  //当前坐标  private float currentX = 0;  private float currentY = 0;  //移动的坐标量  private float distanceX = 0;  private float distanceY = 0;  private boolean updownSlIDe = false; //判断上下滑动的flag  //------尾部收缩属性end--------  public BounceScrollVIEw(Context context,AttributeSet attrs) {  super(context,attrs);  }  //初始化  private voID init() {  setoverScrollMode(OVER_SCRolL_NEVER);  if (getChildAt(0) != null) {   inner = getChildAt(0);//这个是底部收缩的vIEw   //头部收缩的   VIEwGroup vg = (VIEwGroup) getChildAt(0);   if (vg.getChildAt(0) != null) {   dropZoomVIEw = vg.getChildAt(0);   }  }  }  /***  * 生成视图工作完成.该函数在生成视图的最后调用,在所有子视图添加完之后. 即使子类覆盖了 onFinishInflate  * 方法,也应该调用父类的方法,使该方法得以执行.  */  @OverrIDe  protected voID onFinishInflate() {  //初始化  init();  super.onFinishInflate();  }  @OverrIDe  public boolean dispatchtouchEvent(MotionEvent ev) {  //这里只是计算尾部坐标  currentX = ev.getX();  currentY = ev.getY();  switch (ev.getAction()) {   case MotionEvent.ACTION_MOVE:   distanceX = currentX - lastX;   distanceY = currentY - lastY;   if (Math.abs(distanceX) < Math.abs(distanceY) && Math.abs(distanceY) > 12) {    updownSlIDe = true;   }   break;  }  lastX = currentX;  lastY = currentY;  if (updownSlIDe && inner != null) commOntouchEvent(ev);  return super.dispatchtouchEvent(ev);  }  /***  * 触摸事件  *  * @param ev  */  public voID commOntouchEvent(MotionEvent ev) {  //头部缩放计算  if (dropZoomVIEwWIDth <= 0 || dropZoomVIEwHeight <= 0) {   dropZoomVIEwWIDth = dropZoomVIEw.getMeasureDWIDth();   dropZoomVIEwHeight = dropZoomVIEw.getMeasuredHeight();  }  switch (ev.getAction()) {   case MotionEvent.ACTION_UP:   //手指离开后头部恢复图片   mScaling = false;   replyImage();   // 手指松开尾部恢复   if (isNeedAnimation()) {    animation();    isCount = false;   }   clear0();   break;   //这里头尾分开处理,互不干扰   case MotionEvent.ACTION_MOVE:   //尾部处理   final float preY = y;// 按下时的y坐标   float NowY = ev.getY();// 时时y坐标   int deltaY = (int) (preY - NowY);// 滑动距离   if (!isCount) {    deltaY = 0; // 在这里要归0.   }   y = NowY;   // 当滚动到最上或者最下时就不会再滚动,这时移动布局   if (isNeedMove()) {    // 初始化头部矩形    if (normal.isEmpty()) {    // 保存正常的布局位置    normal.set(inner.getleft(),inner.gettop(),inner.getRight(),inner.getBottom());    }    // 移动布局    inner.layout(inner.getleft(),inner.gettop() - deltaY / 2,inner.getBottom() - deltaY / 2);   }   isCount = true;   //尾部处理end   //头部处理   if (!mScaling) {    if (getScrollY() == 0) {    mFirstposition = ev.getY();// 滚动到顶部时记录位置,否则正常返回    } else {    break;    }   }   int distance = (int) ((ev.getY() - mFirstposition) * 0.6); // 滚动距离乘以一个系数   if (distance < 0) { // 当前位置比记录位置要小,正常返回    break;   }   // 处理放大   mScaling = true;   setZoom(1 + distance);   //头部处理end   break;  }  }  /***  * 回缩动画,尾部往下缩动画  */  public voID animation() {  // 开启移动动画  TranslateAnimation ta = new TranslateAnimation(0,normal.top);  ta.setDuration(200);  inner.startAnimation(ta);  // 设置回到正常的布局位置  inner.layout(normal.left,normal.top,normal.right,normal.bottom);  normal.setEmpty();  }  // 是否需要开启动画  public boolean isNeedAnimation() {  return !normal.isEmpty();  }  // 回d动画,header往上缩动画 (使用了属性动画)  public voID replyImage() {  final float distance = dropZoomVIEw.getMeasureDWIDth() - dropZoomVIEwWIDth;  // 设置动画  ValueAnimator anim = ObjectAnimator.offloat(0.0F,1.0F).setDuration((long) (distance * 0.7));  anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {   @OverrIDe   public voID onAnimationUpdate(ValueAnimator animation) {   float cVal = (float) animation.getAnimatedValue();   setZoom(distance - ((distance) * cVal));   }  });  anim.start();  }  //头部缩放  public voID setZoom(float s) {  if (dropZoomVIEwHeight <= 0 || dropZoomVIEwWIDth <= 0) {   return;  }  VIEwGroup.LayoutParams lp = dropZoomVIEw.getLayoutParams();  lp.wIDth = (int) (dropZoomVIEwWIDth + s);  lp.height = (int) (dropZoomVIEwHeight * ((dropZoomVIEwWIDth + s) / dropZoomVIEwWIDth));  dropZoomVIEw.setLayoutParams(lp);  }  /***  * 是否需要移动布局 inner.getMeasuredHeight():获取的是控件的总高度  *  * getHeight():获取的是屏幕的高度  *  * @return  */  public boolean isNeedMove() {  int offset = inner.getMeasuredHeight() - getHeight();  int scrollY = getScrollY();  // 0是顶部,后面那个是底部  if (scrollY == 0 || scrollY == offset) {   return true;  }  return false;  }  //清理尾部属性值  private voID clear0() {  lastX = 0;  lastY = 0;  distanceX = 0;  distanceY = 0;  updownSlIDe = false;  } }

下面是我自己使用的一个layout例子:

<?xml version="1.0" enCoding="utf-8"?> <com.kokjuis.travel.customVIEw.BounceZoomScrollVIEw xmlns:androID="http://schemas.androID.com/apk/res/androID"  xmlns:imagecontrol="http://schemas.androID.com/apk/res-auto"  androID:layout_wIDth="match_parent"  androID:layout_height="match_parent"  androID:scrollbars="none">  <!-- <linearLayout   androID:ID="@+ID/ui_allchatList_header_relativelayout"   androID:layout_wIDth="match_parent"   androID:layout_height="45dp"   androID:background="@drawable/bar_bg"   androID:orIEntation="horizontal"   androID:paddingBottom="5dp"   androID:paddingtop="5dp">   <button   androID:ID="@+ID/ui_allchatList_backbtn"   androID:layout_wIDth="wrap_content"   androID:layout_height="match_parent"   androID:layout_marginBottom="3dp"   androID:layout_marginleft="5dp"   androID:layout_margintop="3dp"   androID:background="@null"   androID:gravity="center"   androID:text="我"   androID:textcolor="@color/white"   androID:textSize="18sp" />  </linearLayout>  -->  <linearLayout  androID:layout_wIDth="match_parent"  androID:layout_height="match_parent"  androID:orIEntation="vertical">  <relativeLayout   androID:layout_wIDth="match_parent"   androID:layout_height="250dp"   androID:layout_gravity="center_horizontal">   <ImageVIEw   androID:layout_wIDth="match_parent"   androID:layout_height="match_parent"   androID:layout_marginBottom="40dp"   androID:background="@drawable/personinfo_bg" />   <com.kokjuis.travel.customVIEw.RoundImageVIEw   androID:ID="@+ID/headImage"   androID:layout_wIDth="80dp"   androID:layout_height="80dp"   androID:layout_alignParentBottom="true"   androID:layout_centerHorizontal="true"   androID:src="@drawable/headimg"   imagecontrol:border_insIDe_color="#fff7f2e9"   imagecontrol:border_outsIDe_color="#ffd5d1c8"   imagecontrol:border_thickness="2dp" />  </relativeLayout>  <linearLayout   androID:layout_wIDth="match_parent"   androID:layout_height="wrap_content"   androID:orIEntation="vertical">   <TextVIEw   androID:ID="@+ID/name_tv"   androID:layout_wIDth="wrap_content"   androID:layout_height="wrap_content"   androID:layout_gravity="center_horizontal"   androID:layout_margintop="6dp"   androID:gravity="center_vertical"   androID:text="昵称:"   androID:textSize="20sp" />   <TextVIEw   androID:ID="@+ID/motto_tv"   androID:layout_wIDth="wrap_content"   androID:layout_height="40dp"   androID:layout_gravity="center_horizontal"   androID:gravity="center_vertical"   androID:text="座右铭:"   androID:textSize="11sp" />   <linearLayout   androID:layout_wIDth="150dp"   androID:layout_height="wrap_content"   androID:layout_gravity="center_horizontal"   androID:orIEntation="vertical">   <TextVIEw    androID:ID="@+ID/accounts_tv"    androID:layout_wIDth="wrap_content"    androID:layout_height="wrap_content"    androID:layout_margintop="8dp"    androID:gravity="center_vertical"    androID:text="帐号:"    androID:textSize="12sp" />   <TextVIEw    androID:ID="@+ID/gender_tv"    androID:layout_wIDth="wrap_content"    androID:layout_height="wrap_content"    androID:layout_margintop="2dp"    androID:gravity="center_vertical"    androID:text="性别:"    androID:textSize="12sp" />   </linearLayout>   <button   androID:ID="@+ID/logout_btn"   androID:layout_wIDth="wrap_content"   androID:layout_height="wrap_content"   androID:layout_gravity="center_horizontal"   androID:layout_margintop="20dp"   androID:text="注销" />  </linearLayout>  </linearLayout> </com.kokjuis.travel.customVIEw.BounceZoomScrollVIEw>

以上所述是小编给大家介绍的AndroID ScrollVIEw 滑到头部尾部可伸缩放大效果,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对编程小技巧网站的支持!

总结

以上是内存溢出为你收集整理的Android中ScrollView 滑到头部或尾部可伸缩放大效果全部内容,希望文章能够帮你解决Android中ScrollView 滑到头部或尾部可伸缩放大效果所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1146637.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存