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;
  /**
   * 这两个变量用来控制pull的方向,如果不加控制,当情况满足可上拉又可下拉时没法下拉
   */
  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为例)

<view.PullToRefreshLayout
  android:id="@+id/ptrl"
  android:layout_width="match_parent"
  android:layout_height="match_parent">

  <include layout="@layout/head" />

  <view.PullableListView
    android:id="@+id/plv"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

  <include layout="@layout/foot" />

</view.PullToRefreshLayout>

head

<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/head_view"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:background="@android:color/darker_gray">

  <RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:paddingBottom="20dp"
    android:paddingTop="20dp">

    <RelativeLayout
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:layout_centerInParent="true">

      <ImageView
        android:id="@+id/iv_head"
        android:layout_width="20dp"
        android:layout_height="20dp"
        android:layout_centerVertical="true"
        android:layout_marginLeft="60dp"
        android:scaleType="fitXY" />

      <TextView
        android:id="@+id/tv_head"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:textColor="@android:color/white"
        android:textSize="16sp" />

    </RelativeLayout>

  </RelativeLayout>

</RelativeLayout>

foot

<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/loadmore_view"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:background="@android:color/darker_gray">

  <RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:paddingBottom="20dp"
    android:paddingTop="20dp">

    <RelativeLayout
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:layout_centerInParent="true">

      <ImageView
        android:id="@+id/iv_foot"
        android:layout_width="20dp"
        android:layout_height="20dp"
        android:layout_centerVertical="true"
        android:layout_marginLeft="60dp"
        android:scaleType="fitXY" />

      <TextView
        android:id="@+id/tv_foot"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:textColor="@android:color/white"
        android:textSize="16sp" />
    </RelativeLayout>

  </RelativeLayout>

</RelativeLayout>

4.注意

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

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

(0)

相关推荐

  • android教你打造独一无二的上拉下拉刷新加载框架

    其实早在去年七月,群里小伙伴就有让我共享这个.但我当时绝的技术不纯熟.代码有bug什么的.没有写出来.现在感觉整理的差不多了.就写出来让大家看看,有问题一起讨论解决. 说到刷新加载,我们第一个想到啥,对了就是swiperefreshlayout,还有什么SuperSwiperefreshlayout,XRecyclerView等等.反正老多了,我还是之前那句话,不管用什么,我们需要知道他的原理. 打造框架开始 对于刷新加载的实现,你们第一个想到的是什么?是用swiperefresh然后在recy

  • Android ListView下拉刷新上拉自动加载更多DEMO示例

    代码下载地址已经更新.因为代码很久没更新,已经很落伍了,建议大家使用RecyclerView实现. 参考项目: https://github.com/bingoogolapple/BGARefreshLayout-Android https://github.com/baoyongzhang/android-PullRefreshLayout 下拉刷新,Android中非常普遍的功能.为了方便便重写的ListView来实现下拉刷新,同时添加了上拉自动加载更多的功能.设计最初是参考开源中国的And

  • Android下拉刷新上拉加载控件(适用于所有View)

    前面写过一篇关于下拉刷新控件的文章下拉刷新控件终结者:PullToRefreshLayout,后来看到好多人还有上拉加载更多的需求,于是就在前面下拉刷新控件的基础上进行了改进,加了上拉加载的功能.不仅如此,我已经把它改成了对所有View都通用!可以随心所欲使用这两个功能~~ 我做了一个大集合的demo,实现了ListView.GridView.ExpandableListView.ScrollView.WebView.ImageView.TextView的下拉刷新和上拉加载.后面会提供demo的

  • Android实现上拉加载更多以及下拉刷新功能(ListView)

    首先为大家介绍Andorid5.0原生下拉刷新简单实现. 先上效果图: 相对于上一个19.1.0版本中的横条效果好看了很多.使用起来也很简单. <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/container" and

  • Android中使用RecyclerView实现下拉刷新和上拉加载

    推荐阅读:使用RecyclerView添加Header和Footer的方法                       RecyclerView的使用之HelloWorld RecyclerView 是Android L版本中新添加的一个用来取代ListView的SDK,它的灵活性与可替代性比listview更好.本文给大家介绍如何为RecyclerView添加下拉刷新和上拉加载,过去在ListView当中添加下拉刷新和上拉加载是非常方便的利用addHeaderView和addFooterVie

  • Android使用recyclerview打造真正的下拉刷新上拉加载效果

    前言 前段时间需要用到recyclerview,就想找个封装好的下拉刷新,上拉加载的库,结果愣是没找到,便自己写了一个. 注意:我说的是"上拉加载",不是滑到底部自动加载. 虽然现在自动加载是主流和趋势,但也不排除有时候就需要用到上拉加载啊,毕竟林子大了,什么样的产品经理都有对吧. 代码写好后,准备发布到bintray的时候,向同事征求这个项目的名字,同事说:"就叫DZTRecyclerview!" 不解,同事解释:"叼炸天Recyclerview!&qu

  • Android RecyclerView实现下拉刷新和上拉加载

    RecyclerView已经出来很久了,许许多多的项目都开始从ListView转战RecyclerView,那么,上拉加载和下拉刷新是一件很有必要的事情. 在ListView上,我们可以通过自己添加addHeadView和addFootView去添加头布局和底部局实现自定义的上拉和下拉,或者使用一些第三方库来简单的集成,例如Android-pulltorefresh或者android-Ultra-Pull-to-Refresh,后者的自定义更强,但需要自己实现上拉加载. 而在下面我们将用两种方式

  • Android开发之ListView列表刷新和加载更多实现方法

    本文实例讲述了Android开发之ListView列表刷新和加载更多实现方法.分享给大家供大家参考.具体如下: 上下拉实现刷新和加载更多的ListView,如下: package com.sin.android.ui; import android.content.Context; import android.util.AttributeSet; import android.view.Gravity; import android.view.MotionEvent; import andro

  • Android RecyclerView 上拉加载更多及下拉刷新功能的实现方法

    RecyclerView 已经出来很久了,但是在项目中之前都使用的是ListView,最近新的项目上了都大量的使用了RecycleView.尤其是瀑布流的下拉刷新,网上吧啦吧啦没有合适的自己总结了一哈. 先贴图上来看看: 使用RecyclerView实现上拉加载更多和下拉刷新的功能我自己有两种方式: 1.使用系统自带的Android.support.v4.widget.SwipeRefreshLayout这个控价来实现. 2.自定义的里面带有RecyleView的控件. 使用RecycleVie

  • Android ListView实现上拉加载更多和下拉刷新功能

    本文实例为大家介绍了Android ListView下拉刷新功能的实现方法和功能,供大家参考,具体内容如下 1.ListView优化方式 界面缓存:ViewHolder+convertView 分页加载:上拉刷新 图片缓存 快速滑动ListView禁止刷新 2.效果 3.上拉加载更多原理及实现 当我们手指滑动到listview最后位置的时候,我们触发加载数据的方法.这触发之前我们需要做一些工作,包括: 如何判断滑动到最后? 如何避免重复加载数据? 加载之后如何刷新界面? 1).界面实现AbsLi

随机推荐