栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 移动开发 > Android

Android刷新加载框架详解

Android 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Android刷新加载框架详解

本文实例为大家分享了Android刷新加载框架的具体代码,供大家参考,具体内容如下

1.定义一个接口控制下拉和上拉

public interface Pullable {

  
  boolean canPullDown();

  
  boolean canPullUp();
}

2.定义一个刷新加载布局

public class PullToRefreshLayout extends RelativeLayout {

  
  private View headView;//头视图
  private ImageView headIv;//头图标
  private TextView headTv;//头文字
  private int headHeight;//头高度
  private float headBorder;//头临界
  
  private View pullView;//拉视图
  private int pullHeight;//拉高度
  private int pullWidth;//拉宽度

  
  private View footView;//尾视图
  private ImageView footIv;//尾图标
  private TextView footTv;//尾文字
  private int footHeight;//尾高度
  private float footBorder;//尾临界

  
  public static final int INIT = 0;//初始
  public static final int RELEASE_TO_REFRESH = 1;//释放刷新
  public static final int REFRESHING = 2;//正在刷新
  public static final int RELEASE_TO_LOAD = 3;//释放加载
  public static final int LOADING = 4;//正在加载
  public static final int DONE = 5;//完成
  private int state = INIT;

  
  private onRefreshListener mListener;

  private float downY;//按下时Y坐标
  private float lastY;//上一个Y坐标
  private float pullDownY = 0;//下拉偏移量
  private float pullUpY = 0;//上拉偏移量
  private int offset;//偏移量

  
  private RotateAnimation rotateAnimation;

  
  private Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
      super.handleMessage(msg);
      if (msg != null) {
 switch (msg.what) {
   case 1:
     headIv.clearAnimation();
     break;
   case 2:
     footIv.clearAnimation();
     break;
   default:
     break;
 }
 pullDownY = 0;
 pullUpY = 0;
 requestLayout();
 state = INIT;
 refreshViewByState();
 isTouch = true;
      }
    }
  };

  
  private boolean isLayout = false;
  
  private boolean isTouch = false;
  
  private float radio = 2;
  
  private int mEvents;
  
  private boolean canPullDown = true;
  private boolean canPullUp = true;

  public void setonRefreshListener(onRefreshListener listener) {
    mListener = listener;
  }

  public PullToRefreshLayout(Context context) {
    super(context);
    initView(context);
  }

  public PullToRefreshLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
    initView(context);
  }

  public PullToRefreshLayout(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    initView(context);
  }

  private void initView(Context context) {
    rotateAnimation = (RotateAnimation) AnimationUtils.loadAnimation(context, R.anim.rotating);
  }

  private void refreshViewByState() {
    switch (state) {
      case INIT:
 // 下拉布局初始状态
 headIv.setImageResource("下拉刷新显示的图片");
 headTv.setText("下拉刷新");
 // 上拉布局初始状态
 footIv.setImageResource("上拉加载显示的图片");
 footTv.setText("上拉加载");
 break;
      case RELEASE_TO_REFRESH:
 // 释放刷新状态
 headIv.setImageResource("释放刷新显示的图片");
 headTv.setText("释放刷新");
 break;
      case REFRESHING:
 // 正在刷新状态
 headIv.setImageResource("正在刷新显示的图片");
 headTv.setText("正在刷新");
 break;
      case RELEASE_TO_LOAD:
 // 释放加载状态
 footIv.setImageResource("释放加载显示的图片");
 footTv.setText("释放加载");
 break;
      case LOADING:
 // 正在加载状态
 footIv.setImageResource("正在加载显示的图片");
 footTv.setText("正在加载");
 break;
      case DONE:
 // 刷新或加载完毕,啥都不做
 break;
    }
  }

  
  private void releasePull() {
    canPullDown = true;
    canPullUp = true;
  }
  
  @Override
  public boolean dispatchTouchEvent(MotionEvent ev) {
    switch (ev.getActionMasked()) {
      case MotionEvent.ACTION_DOWN:
 downY = ev.getY();
 lastY = downY;
 mEvents = 0;
 releasePull();
 if (state != REFRESHING && state != LOADING) {
   isTouch = true;
 }
 break;
      case MotionEvent.ACTION_POINTER_DOWN:
      case MotionEvent.ACTION_POINTER_UP:
 // 过滤多点触碰
 mEvents = -1;
 break;
      case MotionEvent.ACTION_MOVE:
 if (mEvents == 0) {
   if (pullDownY > 0 || (((Pullable) pullView).canPullDown()
&& canPullDown && state != LOADING && state != REFRESHING)) {
     // 可以下拉,正在加载时不能下拉
     // 对实际滑动距离做缩小,造成用力拉的感觉
     pullDownY = pullDownY + (ev.getY() - lastY) / radio;
     if (pullDownY < 0) {
pullDownY = 0;
canPullDown = false;
canPullUp = true;
     }
     if (pullDownY > getMeasuredHeight()) {
pullDownY = getMeasuredHeight();
     }
     if (state == REFRESHING) {
// 正在刷新的时候触摸移动
isTouch = false;
     }
   } else if (pullUpY < 0
|| (((Pullable) pullView).canPullUp() && canPullUp && state != REFRESHING && state != LOADING)) {
     // 可以上拉,正在刷新时不能上拉
     pullUpY = pullUpY + (ev.getY() - lastY) / radio;

     if (pullUpY > 0) {
pullUpY = 0;
canPullDown = true;
canPullUp = false;
     }
     if (pullUpY < -getMeasuredHeight()) {
pullUpY = -getMeasuredHeight();
     }
     if (state == LOADING) {
// 正在加载的时候触摸移动
isTouch = false;
     }
   }
 }
 if (isTouch) {
   lastY = ev.getY();
   if (pullDownY > 0 || pullUpY < 0) {
     requestLayout();
   }
   if (pullDownY > 0) {
     if (pullDownY <= headBorder && (state == RELEASE_TO_REFRESH || state == DONE)) {
// 如果下拉距离没达到刷新的距离且当前状态是释放刷新,改变状态为下拉刷新
state = INIT;
refreshViewByState();
     }
     if (pullDownY >= headBorder && state == INIT) {
// 如果下拉距离达到刷新的距离且当前状态是初始状态刷新,改变状态为释放刷新
state = RELEASE_TO_REFRESH;
refreshViewByState();
     }
   } else if (pullUpY < 0) {
     // 下面是判断上拉加载的,同上,注意pullUpY是负值
     if (-pullUpY <= footBorder && (state == RELEASE_TO_LOAD || state == DONE)) {
state = INIT;
refreshViewByState();
     }
     // 上拉操作
     if (-pullUpY >= footBorder && state == INIT) {
state = RELEASE_TO_LOAD;
refreshViewByState();
     }
   }
   // 因为刷新和加载操作不能同时进行,所以pullDownY和pullUpY不会同时不为0,因此这里用(pullDownY +
   // Math.abs(pullUpY))就可以不对当前状态作区分了
   if ((pullDownY + Math.abs(pullUpY)) > 8) {
     // 防止下拉过程中误触发长按事件和点击事件
     ev.setAction(MotionEvent.ACTION_CANCEL);
   }
 }
 break;
      case MotionEvent.ACTION_UP:
 if (pullDownY > headBorder || -pullUpY > footBorder) {
   // 正在刷新时往下拉(正在加载时往上拉),释放后下拉头(上拉头)不隐藏
   isTouch = false;
 }
 if (state == RELEASE_TO_REFRESH) {
   state = REFRESHING;
   refreshViewByState();
   // 刷新操作
   if (mListener != null) {
     canPullDown = false;
     pullDownY = headBorder;
     pullUpY = 0;
     requestLayout();
     headIv.startAnimation(rotateAnimation);
     mListener.onRefresh(this);
   }
 } else if (state == RELEASE_TO_LOAD) {
   state = LOADING;
   refreshViewByState();
   // 加载操作
   if (mListener != null) {
     canPullUp = false;
     pullDownY = 0;
     pullUpY = -footBorder;
     requestLayout();
     footIv.startAnimation(rotateAnimation);
     mListener.onLoadMore(this);
   }
 } else {
   pullDownY = 0;
   pullUpY = 0;
   requestLayout();
 }
      default:
 break;
    }
    // 事件分发交给父类
    super.dispatchTouchEvent(ev);
    return true;
  }

  public void hideHeadView() {
    handler.sendEmptyMessage(1);
  }

  public void hideFootView() {
    handler.sendEmptyMessage(2);
  }

  private void initView() {
    // 初始化下拉布局
    headIv = (ImageView) headView.findViewById(R.id.iv_head);
    headTv = (TextView) headView.findViewById(R.id.tv_head);
    //初始化上拉布局
    footIv = (ImageView) footView.findViewById(R.id.iv_foot);
    footTv = (TextView) footView.findViewById(R.id.tv_foot);
    refreshViewByState();
  }

  @Override
  protected void onLayout(boolean changed, int l, int t, int r, int b) {
    if (!isLayout) {
      // 这里是第一次进来的时候做一些初始化
      headView = getChildAt(0);
      pullView = getChildAt(1);
      footView = getChildAt(2);
      headBorder = ((ViewGroup) headView).getChildAt(0).getMeasuredHeight();
      footBorder = ((ViewGroup) footView).getChildAt(0).getMeasuredHeight();
      headHeight = headView.getMeasuredHeight();
      pullHeight = pullView.getMeasuredHeight();
      footHeight = footView.getMeasuredHeight();
      pullWidth = pullView.getMeasuredWidth();
      initView();
      isLayout = true;
    }
    // 改变子控件的布局,这里直接用(pullDownY + pullUpY)作为偏移量,这样就可以不对当前状态作区分
    offset = (int) (pullDownY + pullUpY);
    headView.layout(0, -headHeight + offset, pullWidth, offset);
    pullView.layout(0, offset, pullWidth, pullHeight + offset);
    footView.layout(0, pullHeight + offset, pullWidth, pullHeight + footHeight + offset);
  }

  public interface onRefreshListener {
    void onRefresh(PullToRefreshLayout pullToRefreshLayout);

    void onLoadMore(PullToRefreshLayout pullToRefreshLayout);
  }

}

3.自定义View
ListView

public class PullableListView extends ListView implements Pullable {

  public PullableListView(Context context) {
    super(context);
  }

  public PullableListView(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  public PullableListView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
  }

  @Override
  public boolean canPullDown() {
    if (getCount() == 0) {
      // 没有item的时候也可以下拉刷新
      return false;
    } else if (getFirstVisiblePosition() == 0 && getChildAt(0).getTop() >= 0) {
      // 滑到ListView的顶部了
      return true;
    } else
      return false;
  }

  @Override
  public boolean canPullUp() {
    if (getCount() == 0) {
      // 没有item的时候也可以上拉加载
      return false;
    } else if (getLastVisiblePosition() == (getCount() - 1)) {
      // 滑到底部了
      if (getChildAt(getLastVisiblePosition() - getFirstVisiblePosition()) != null
   && getChildAt(getLastVisiblePosition() - getFirstVisiblePosition())
   .getBottom() <= getMeasuredHeight())
 return true;
    }
    return false;
  }
}

GridView

public class PullableGridView extends GridView implements Pullable {

  public PullableGridView(Context context) {
    super(context);
  }

  public PullableGridView(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  public PullableGridView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
  }

  @Override
  public boolean canPullDown() {
    if (getCount() == 0) {
      // 没有item的时候也可以下拉刷新
      return false;
    } else if (getFirstVisiblePosition() == 0
 && getChildAt(0).getTop() >= 0) {
      // 滑到顶部了
      return true;
    } else
      return false;
  }

  @Override
  public boolean canPullUp() {
    if (getCount() == 0) {
      // 没有item的时候也可以上拉加载
      return false;
    } else if (getLastVisiblePosition() == (getCount() - 1)) {
      // 滑到底部了
      if (getChildAt(getLastVisiblePosition() - getFirstVisiblePosition()) != null
   && getChildAt(
   getLastVisiblePosition()
- getFirstVisiblePosition()).getBottom() <= getMeasuredHeight())
 return true;
    }
    return false;
  }

}

RecyclerView

public class PullableRecyclerView extends RecyclerView implements Pullable {

  public PullableRecyclerView(Context context) {
    super(context);
  }

  public PullableRecyclerView(Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
  }

  public PullableRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
  }

  @Override
  public boolean canPullDown() {
    RecyclerView.LayoutManager layoutManager = getLayoutManager();
    if (layoutManager instanceof LinearLayoutManager) {
      LinearLayoutManager linearLayoutManager = (LinearLayoutManager) layoutManager;
      if (linearLayoutManager.getItemCount() == 0) {
 return false;
      } else if (linearLayoutManager.findFirstVisibleItemPosition() == 0 && linearLayoutManager.getChildAt(0).getTop() >= 0) {
 return true;
      } else {
 return false;
      }
    } else if (layoutManager instanceof StaggeredGridLayoutManager) {
      StaggeredGridLayoutManager staggeredGridLayoutManager = (StaggeredGridLayoutManager) layoutManager;
      if (staggeredGridLayoutManager.getItemCount() == 0) {
 return false;
      } else {
 int[] firstVisibleItems = null;
 firstVisibleItems = staggeredGridLayoutManager.findFirstVisibleItemPositions(firstVisibleItems);
 if (firstVisibleItems != null && firstVisibleItems.length > 0) {
   if (staggeredGridLayoutManager.getChildCount() + firstVisibleItems[0] == staggeredGridLayoutManager.getItemCount()) {
     return true;
   }
 }
      }
    }
    return false;
  }

  @Override
  public boolean canPullUp() {
    RecyclerView.LayoutManager layoutManager = getLayoutManager();
    if (layoutManager instanceof LinearLayoutManager) {
      LinearLayoutManager linearLayoutManager = (LinearLayoutManager) layoutManager;
      if (linearLayoutManager.getItemCount() == 0) {
 return false;
      } else if (linearLayoutManager.findLastVisibleItemPosition() == (linearLayoutManager.getItemCount() - 1)) {
 if (linearLayoutManager.getChildAt(linearLayoutManager.findLastVisibleItemPosition() - linearLayoutManager.findFirstVisibleItemPosition()) != null
     && linearLayoutManager.getChildAt(linearLayoutManager.findLastVisibleItemPosition() - linearLayoutManager.findFirstVisibleItemPosition()).getBottom() <= getMeasuredHeight()) {
   return true;
 }
      }
    } else if (layoutManager instanceof StaggeredGridLayoutManager) {
      StaggeredGridLayoutManager staggeredGridLayoutManager = (StaggeredGridLayoutManager) layoutManager;
      if (staggeredGridLayoutManager.getItemCount() == 0) {
 return false;
      } else {
 int[] lastPositions = new int[staggeredGridLayoutManager.getSpanCount()];
 lastPositions = staggeredGridLayoutManager.findLastVisibleItemPositions(lastPositions);
 if (findMax(lastPositions) >= staggeredGridLayoutManager.getItemCount() - 1) {
   return true;
 }
      }
    }
    return false;
  }

  private int findMax(int[] lastPositions) {
    int max = lastPositions[0];
    for (int value : lastPositions) {
      if (value > max) {
 max = value;
      }
    }
    return max;
  }
}

ExpandableListView

public class PullableExpandableListView extends ExpandableListView implements
    Pullable {

  public PullableExpandableListView(Context context) {
    super(context);
  }

  public PullableExpandableListView(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  public PullableExpandableListView(Context context, AttributeSet attrs,
     int defStyle) {
    super(context, attrs, defStyle);
  }

  @Override
  public boolean canPullDown() {
    if (getCount() == 0) {
      // 没有item的时候也可以下拉刷新
      return false;
    } else if (getFirstVisiblePosition() == 0
 && getChildAt(0).getTop() >= 0) {
      // 滑到顶部了
      return true;
    } else
      return false;
  }

  @Override
  public boolean canPullUp() {
    if (getCount() == 0) {
      // 没有item的时候也可以上拉加载
      return false;
    } else if (getLastVisiblePosition() == (getCount() - 1)) {
      // 滑到底部了
      if (getChildAt(getLastVisiblePosition() - getFirstVisiblePosition()) != null
   && getChildAt(
   getLastVisiblePosition()
- getFirstVisiblePosition()).getBottom() <= getMeasuredHeight())
 return true;
    }
    return false;
  }

}

ScrollView

public class PullableScrollView extends ScrollView implements Pullable {

  public PullableScrollView(Context context) {
    super(context);
  }

  public PullableScrollView(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  public PullableScrollView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
  }

  @Override
  public boolean canPullDown() {
    if (getScrollY() == 0)
      return true;
    else
      return false;
  }

  @Override
  public boolean canPullUp() {
    if (getScrollY() >= (getChildAt(0).getHeight() - getMeasuredHeight()))
      return true;
    else
      return false;
  }

}

WebView

 public class PullableWebView extends WebView implements Pullable {

  public PullableWebView(Context context) {
    super(context);
  }

  public PullableWebView(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  public PullableWebView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
  }

  @Override
  public boolean canPullDown() {
    if (getScrollY() == 0)
      return true;
    else
      return false;
  }

  @Override
  public boolean canPullUp() {
    if (getScrollY() >= getContentHeight() * getScale()
 - getMeasuredHeight())
      return true;
    else
      return false;
  }
}

ImageView

public class PullableImageView extends ImageView implements Pullable
{

  public PullableImageView(Context context)
  {
    super(context);
  }

  public PullableImageView(Context context, AttributeSet attrs)
  {
    super(context, attrs);
  }

  public PullableImageView(Context context, AttributeSet attrs, int defStyle)
  {
    super(context, attrs, defStyle);
  }

  @Override
  public boolean canPullDown()
  {
    return true;
  }

  @Override
  public boolean canPullUp()
  {
    return true;
  }

}

TextView

public class PullableTextView extends TextView implements Pullable {

  public PullableTextView(Context context) {
    super(context);
  }

  public PullableTextView(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  public PullableTextView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
  }

  @Override
  public boolean canPullDown() {
    return true;
  }

  @Override
  public boolean canPullUp() {
    return true;
  }

}

4.使用示例(以ListView为例)



  

  

  
  


head




  

    

      

      
      
    
    
  
  


foot




  

    

      

      
    
    
  
  


4.注意

自定义的View跟正常的View的使用没有什么差别
如需实现刷新加载,必须使ptrl.setonRefreshListener(PullToRefreshLayout.onRefreshListener onRefreshListener);

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

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/156945.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号