Android简洁的下拉放大刷新效果示例

 更新时间:2017年10月26日 08:59:23   作者:_独爱夜色  
本篇文章主要介绍了Android简洁的下拉放大刷新效果示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

序言

国庆放假过后眼看一年又要过完了,年初指望着已经有一年的经验本以为自己不是刚出校的学生以为翅膀已经硬了,打算辞职换新工作,一面试才发现自己就是个垃圾,什么oninterceptEvent,dispatchTouchEvent ,Aysnctask都不会。做了一年的项目也是用的Xutils2.6版本 还有一堆不常用不好的不主流不时尚的框架,技术也没任何长进。还好公司真的轻松(所以也学不到任何东西)可以趁闲下来的时间多学点东西。于是写了个简单但也有需求的控件练练手。

首先先看效果图吧

这个是listview的效果还有一个ScrollView的效果当然使用和实现时一样的原理这里就一listview来讲解,文末传送门可以看到全部的代码

1、具体使用

项目build.gradle

allprojects {
 repositories {
  jcenter()
  maven { url 'https://jitpack.io' }
 }
}

app model build.gradle

compile 'com.github.xypmhxy:PullZoomLayout:1.1'

布局文件中

<com.ren.pullzoom.widget.PullZoomLayout
  android:id="@+id/pull"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="vertical"
  app:image_height="200dp" 图片高度
  app:image_res="@mipmap/timg" 图片资源
  app:refresh_enable="true" 是否开启刷新
  app:scale_type="center_crop">//图片缩放方式

  <ListView
   android:id="@+id/listview"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:background="@android:color/white" />

 </com.ren.pullzoom.widget.PullZoomLayout>

2、实现思路

其思路很简单

1.首先在构造方法中动态添加下拉缩放的imageView和刷新的refreshProgress(控件中为实现跟随手指滑动旋转因此使用的为imageView)

2.获取到listview对象,然后监听listview的滑动事件,判断滑到顶部后继续向下滑动的时候将需要放大的ImageView高度增加然后利用ImageView的Scale方法完成缩放。

3.最后放开手指的时候用属性动画让imageView平滑回到最初状态,并且如果开启下拉刷新则回调其方法。

3、具体实现

1.动态添加两个ImageView(下拉放大的和刷新的progress),大致原理就是将这两个ImageView添加到RelativeLayout中然后将RelativeLayout 添加到自身中。代码如下

/*实例化头部布局包含pullZoomImage 和 refreshProgress*/
protected void init(Context context) {
  RelativeLayout head = new RelativeLayout(context);
  ViewGroup.LayoutParams headParams = new ViewGroup.LayoutParams(-1, -2);
  head.setLayoutParams(headParams);
  /*实例化pullZoomImage*/
  ·······
  pullZoomImage.setImageResource(imageRes);
  originalParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, imageHeight);
  pullZoomImage.setLayoutParams(originalParams);
  head.addView(pullZoomImage);
  /*实例化refreshProgress*/
  refreshProgress = new ImageView(context);
  refreshProgress.setVisibility(GONE);
  refreshProgress.setImageResource(R.drawable.refresh);
  RelativeLayout.LayoutParams refreshParams = new RelativeLayout.LayoutParams(dip2px(context, 35), dip2px(context, 35));
  refreshParams.addRule(RelativeLayout.ALIGN_PARENT_END, RelativeLayout.TRUE);
  refreshProgress.setLayoutParams(refreshParams);
  head.addView(refreshProgress);
  /*将头部添加到此控件中*/
  addView(head, 0);
}

2.是获取listview对象,因为listview属于子控件所以不能在构造方法里直接获取,因为此时控件不一定加载完成所以需要等待子控件加载完成后获取因此在onFinishInflate方法中获取

 @Override
 protected void onFinishInflate() {
  super.onFinishInflate();
  /*获取listview*/
  if (getChildAt(1) instanceof ListView) {
   listView = (ListView) getChildAt(1);
   listView.setOnScrollListener(scrollListener);
   listView.setOnTouchListener(touchListener);
  }
 }

3.添加listview滑动监听判断是否滑动到顶部,可以开启下拉放大功能

 /*listview滑动监听*/
 protected AbsListView.OnScrollListener scrollListener = new AbsListView.OnScrollListener() {
  @Override
  public void onScrollStateChanged(AbsListView view, int scrollState) {
   /*判断是否滑动到顶部*/
   int firstVisibleItem = listView.getFirstVisiblePosition();
   if (firstVisibleItem == 0 && scrollState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
    View firstView = getChildAt(0);
    canZoom = firstView != null && firstView.getTop() == 0;
   } else
    canZoom = false;
  }

  @Override
  public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
  }
 };

4.实现OnTouchListener根据事件调用放大和缩小动画,抬手时实现刷新等操作

/*listview touchListener监听*/
 protected OnTouchListener touchListener = new OnTouchListener() {
  @Override
  public boolean onTouch(View v, MotionEvent ev) {
   if (pullZoomImage == null) return false;
   switch (ev.getAction()) {
    case MotionEvent.ACTION_DOWN:
     pressY = ev.getY();//获取按下的Y坐标
     break;
    case MotionEvent.ACTION_MOVE:
     if (canZoom)//如果已经滑动到顶部并继续滑动则开始放大pullZoomImage
      return zoomView(ev);
     break;
    case MotionEvent.ACTION_CANCEL:
    case MotionEvent.ACTION_UP:
     if (canZoom)
      restroe();//还原pullZoomImage动画
     if (needRefresh && refreshListener != null) {//达到刷新条件并且实现刷新监听
      refreshListener.onRefresh();
      rotationProgress();//刷新时progress旋转动画
     } else
      refreshProgress.setVisibility(GONE);
     //重置变量
     needRefresh = false;
     canZoom = false;
     break;

   }
   return false;
  }
 };

缩放imageview

 /*放大pullZoomImage*/
 protected boolean zoomView(MotionEvent ev) {
  float offY = ev.getY() - pressY;
  if (offY <= 0 || offY < 16)//滑动方向上滑或者滑动距离小于16则不管
   return false;
  /*如果开启下拉刷新判断滑动距离是否大于refrshSlop则显示refreshProgress*/
  if (refreshEnable) {
   needRefresh = offY >= refrshSlop;
   if (needRefresh)
    refreshProgress.setVisibility(VISIBLE);
  }
  ViewGroup.LayoutParams params = pullZoomImage.getLayoutParams();
  float height = originalParams.height + offY / damp;//根据滑动距离增加pullZoomImage的高度
  params.height = (int) height;
  scaleImage(height);//放大图片
  rotationProgress(offY);//旋转refreshProgress
  if (params.height >= originalParams.height)
   pullZoomImage.setLayoutParams(params);//为pullZoomImage设置改变后的params
  return true;
 }
 /*缩放imageview*/
 protected void scaleImage(float height) {
//  if (pullZoomImage.getScaleType() == ImageView.ScaleType.CENTER_CROP)
//   return;
  float scale = (height - originalParams.height) / originalParams.height;//根据滑动的大小判断缩放比例
  pullZoomImage.setScaleX(1 + scale);
  pullZoomImage.setScaleY(1 + scale);
 }

抬手后通过属性动画还原pullZoomImage

 /*放开后还原pullZoomImage*/
 protected void restroe() {
  ValueAnimator animator = ValueAnimator.ofFloat(pullZoomImage.getLayoutParams().height, originalParams.height);// 动画更新的监听
  animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

   @Override
   public void onAnimationUpdate(ValueAnimator arg0) {
    float height = (float) arg0.getAnimatedValue();// 获取动画当前变化的值
    // 根据最新高度,更新布局高度
    ViewGroup.LayoutParams params = pullZoomImage.getLayoutParams();
    params.height = (int) height;
    scaleImage(height);
    pullZoomImage.setLayoutParams(params);
   }
  });
  animator.setDuration(200);// 动画时间
  animator.start();// 开启动画
 }

大致原理就是这样最后传送门开启 PullZoomLayout

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

相关文章

  • Android自定义View弧线进度控件

    Android自定义View弧线进度控件

    这篇文章主要为大家详细介绍了Android自定义View弧线进度控件,点击开始按钮时,逐渐的出现进度,感兴趣的小伙伴们可以参考一下
    2016-07-07
  • Android编程获取sdcard卡信息的方法

    Android编程获取sdcard卡信息的方法

    这篇文章主要介绍了Android编程获取sdcard卡信息的方法,可实现获取sdcard总容量、剩余容量等功能,涉及Android针对sdcard进程操作的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-11-11
  • Android开发笔记之图片缓存、手势及OOM分析

    Android开发笔记之图片缓存、手势及OOM分析

    这篇文章主要介绍了Android开发笔记之图片缓存、手势及OOM分析 的相关资料,需要的朋友可以参考下
    2016-01-01
  • Android判断wifi是5G还是2.4G

    Android判断wifi是5G还是2.4G

    这篇文章给大家分享android区分wifi是5G还是2.4G的方法,代码简单易懂,非常不错,具有参考借鉴价值,需要的朋友参考下
    2016-12-12
  • Android开发退出程序的方法汇总

    Android开发退出程序的方法汇总

    Android程序有很多Activity,比如说主窗口A,调用了子窗口B,子窗口B又调用子窗口C,back返回子窗口B后,在B中如何关闭整个Android应用程序呢? 下面脚本之家小编就给大家介绍android开发退出程序的几种方法,感兴趣的朋友参考下吧
    2016-03-03
  • android自动安装apk代码实例(不使用apk安装器安装)

    android自动安装apk代码实例(不使用apk安装器安装)

    这篇文章主要介绍了android自动安装apk代码实例,代码简单,大家参考使用吧
    2013-11-11
  • Android系统更改状态栏字体颜色

    Android系统更改状态栏字体颜色

    这篇文章主要介绍了Android系统更改状态栏字体颜色的方法,需要的朋友可以参考下
    2016-01-01
  • Android ChipGroup收起折叠效果实现详解

    Android ChipGroup收起折叠效果实现详解

    这篇文章主要为大家介绍了Android ChipGroup收起折叠效果实现详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-11-11
  • android仿QQ个人主页下拉回弹效果

    android仿QQ个人主页下拉回弹效果

    这篇文章主要为大家详细介绍了android仿QQ个人主页下拉回弹效果的相关资料,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-02-02
  • Flutter UI实现侧拉抽屉菜单

    Flutter UI实现侧拉抽屉菜单

    这篇文章主要为大家详细介绍了Flutter UI实现侧拉抽屉菜单,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03

最新评论