SwipeRefreshLayout 下拉刷新控件(二)

简介: SwipeRefreshLayout 下拉刷新控件(二)

前面一篇文章中,我们已经学会了使用SwipeRefreshLayout 控件,但致命的缺点是只能进行下拉刷新,不能进行上拉加载,那我们在这里来进行扩展一下,让它具有上拉加载的功能。

首先,我们还是先来看看效果,这里会出现两种:


第一种:

aHR0cDovL2ltZy5ibG9nLmNzZG4ubmV0LzIwMTYxMjE0MTM0ODQyMDkx.png


第二种:

aHR0cDovL2ltZy5ibG9nLmNzZG4ubmV0LzIwMTYxMjE0MTM0OTEyNDgy.png

下面来看一下代码部分:

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import android.annotation.SuppressLint;
import android.content.Context;
import android.support.v4.widget.SwipeRefreshLayout;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ListView;
/**
 * 继承自SwipeRefreshLayout,从而实现滑动到底部时上拉加载更多的功能.
 * 
 * @author caijin
 */
public class RefreshLayout extends SwipeRefreshLayout implements
    OnScrollListener {
  /**
   * 滑动到最下面时的上拉操作
   */
  private int mTouchSlop;
  /**
   * listview实例
   */
  private ListView mListView;
  /**
   * 上拉监听器, 到了最底部的上拉加载操作
   */
  private OnLoadListener mOnLoadListener;
  /**
   * ListView的加载中footer
   */
  private View mListViewFooter;
  /**
   * 按下时的y坐标
   */
  private int mYDown;
  /**
   * 抬起时的y坐标, 与mYDown一起用于滑动到底部时判断是上拉还是下拉
   */
  private int mLastY;
  /**
   * 是否在加载中 ( 上拉加载更多 )
   */
  private boolean isLoading = false;
  /**
   * @param context
   */
  public RefreshLayout(Context context) {
    this(context, null);
  }
  @SuppressLint("InflateParams")
  public RefreshLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
    mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
    mListViewFooter = LayoutInflater.from(context).inflate(
        R.layout.listview_footer, null, false);
  }
  @Override
  protected void onLayout(boolean changed, int left, int top, int right,
      int bottom) {
    super.onLayout(changed, left, top, right, bottom);
    // 初始化ListView对象
    if (mListView == null) {
      getListView();
    }
  }
  /**
   * 获取ListView对象
   */
  private void getListView() {
    int childs = getChildCount();
    if (childs > 0) {
      View childView = getChildAt(0);
      if (childView instanceof ListView) {
        mListView = (ListView) childView;
        // 设置滚动监听器给ListView, 使得滚动的情况下也可以自动加载
        mListView.setOnScrollListener(this);
        Log.d(VIEW_LOG_TAG, "### 找到listview");
      }
    }
  }
  /*
   * (non-Javadoc)
   * 
   * @see android.view.ViewGroup#dispatchTouchEvent(android.view.MotionEvent)
   */
  @Override
  public boolean dispatchTouchEvent(MotionEvent event) {
    final int action = event.getAction();
    switch (action) {
    case MotionEvent.ACTION_DOWN:
      // 按下
      mYDown = (int) event.getRawY();
      break;
    case MotionEvent.ACTION_MOVE:
      // 移动
      mLastY = (int) event.getRawY();
      break;
    case MotionEvent.ACTION_UP:
      // 抬起
      if (canLoad()) {
        loadData();
      }
      break;
    default:
      break;
    }
    return super.dispatchTouchEvent(event);
  }
  /**
   * 是否可以加载更多, 条件是到了最底部, listview不在加载中, 且为上拉操作.
   * 
   * @return
   */
  private boolean canLoad() {
    return isBottom() && !isLoading && isPullUp();
  }
  /**
   * 判断是否到了最底部
   */
  private boolean isBottom() {
    if (mListView != null && mListView.getAdapter() != null) {
      return mListView.getLastVisiblePosition() == (mListView
          .getAdapter().getCount() - 1);
    }
    return false;
  }
  /**
   * 是否是上拉操作
   * 
   * @return
   */
  private boolean isPullUp() {
    return (mYDown - mLastY) >= mTouchSlop;
  }
  /**
   * 如果到了最底部,而且是上拉操作.那么执行onLoad方法
   */
  private void loadData() {
    if (mOnLoadListener != null) {
      // 设置状态
      setLoading(true);
      //
      mOnLoadListener.onLoad();
    }
  }
  /**
   * @param loading
   */
  public void setLoading(boolean loading) {
    isLoading = loading;
    if (isLoading) {
      mListView.addFooterView(mListViewFooter);
    } else {
      mListView.removeFooterView(mListViewFooter);
      mYDown = 0;
      mLastY = 0;
    }
  }
  /**
   * @param loadListener
   */
  public void setOnLoadListener(OnLoadListener loadListener) {
    mOnLoadListener = loadListener;
  }
  @Override
  public void onScrollStateChanged(AbsListView view, int scrollState) {
  }
  @Override
  public void onScroll(AbsListView view, int firstVisibleItem,
      int visibleItemCount, int totalItemCount) {
    // 滚动时到了最底部也可以加载更多
    if (canLoad()) {
      loadData();
    }
  }
  /**
   * 设置刷新
   */
  public static void setRefreshing(SwipeRefreshLayout refreshLayout,
      boolean refreshing, boolean notify) {
    Class<? extends SwipeRefreshLayout> refreshLayoutClass = refreshLayout
        .getClass();
    if (refreshLayoutClass != null) {
      try {
        Method setRefreshing = refreshLayoutClass.getDeclaredMethod(
            "setRefreshing", boolean.class, boolean.class);
        setRefreshing.setAccessible(true);
        setRefreshing.invoke(refreshLayout, refreshing, notify);
      } catch (NoSuchMethodException e) {
        e.printStackTrace();
      } catch (IllegalAccessException e) {
        e.printStackTrace();
      } catch (InvocationTargetException e) {
        e.printStackTrace();
      }
    }
  }
  /**
   * 加载更多的监听器
   * 
   * @author caijin
   */
  public static interface OnLoadListener {
    public void onLoad();
  }
}



然后是适配器部分:

import java.util.ArrayList;
import java.util.HashMap;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
public class MyAdapter extends BaseAdapter {
  public ArrayList< HashMap< String, String>> list;
  public Context context;
  public LayoutInflater layoutInflater;
  public MyAdapter(Context context, ArrayList<HashMap<String, String>> list) {
    this.context = context;
    this.list = list;
    layoutInflater = LayoutInflater.from(context);
  }
  @Override
  public int getCount() {
    return list.size();
  }
  @Override
  public Object getItem(int position) {
    return null;
  }
  @Override
  public long getItemId(int position) {
    return 0;
  }
  @Override
  public View getView(int position, View convertView, ViewGroup parent) {
    View view = null;
    ViewHolder holder = null;
    if (convertView == null) {
      view = layoutInflater.inflate(R.layout.item, null);
      holder = new ViewHolder();
      view.setTag(holder);
    } else {
      view = convertView;
      holder = (ViewHolder) view.getTag();
    }
    return view;
  }
  static class ViewHolder {
  }
}


最后是在Activity中的使用:

import java.util.ArrayList;
import java.util.HashMap;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.widget.SwipeRefreshLayout.OnRefreshListener;
import android.view.View;
import android.widget.ListView;
import com.example.swiperefreshlayoutdemo.RefreshLayout.OnLoadListener;
/**
 * 
 * @author caijin
 * @e-mail 1652783461@qq.com
 *
 */
public class MainActivity extends Activity implements OnRefreshListener,
    OnLoadListener {
  private RefreshLayout swipeLayout;
  private ListView listView;
  private MyAdapter adapter;
  private ArrayList<HashMap<String, String>> list;
  private View header;
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    initView();
    setData();
    setListener();
    /*设置自动刷新 swipeLayout.setRefreshing(true);
    setRefreshing(true)是不会触发onRefresh的,必须要手动调用一次
    所以在界面onCreate里面想要立刻加载就需要这样*/
    swipeLayout.post(new Thread(new Runnable() {
      @Override
      public void run() {
        swipeLayout.setRefreshing(true);
      }
    }));
    onRefresh();
  }
  /**
   * 初始化布局
   */
  @SuppressLint({ "InlinedApi", "InflateParams" })
  private void initView() {
    header = getLayoutInflater().inflate(R.layout.header, null);
    swipeLayout = (RefreshLayout) findViewById(R.id.swipe_container);
    swipeLayout.setColorSchemeResources(R.color.color_bule2,
        R.color.color_bule,
        R.color.color_bule2,
        R.color.color_bule3);
  }
  /**
   * 添加数据
   */
  private void setData() {
    list = new ArrayList<HashMap<String, String>>();
    for (int i = 0; i < 10; i++) {
      list.add(new HashMap<String, String>());
    }
    listView = (ListView) findViewById(R.id.list);
    listView.addHeaderView(header);
    adapter = new MyAdapter(this, list);
    listView.setAdapter(adapter);
  }
  /**
   * 设置监听
   */
  private void setListener() {
    swipeLayout.setOnRefreshListener(this);
    swipeLayout.setOnLoadListener(this);
  }
  /**
   * 上拉刷新
   */
  @Override
  public void onRefresh() {
    swipeLayout.postDelayed(new Runnable() {
      @Override
      public void run() {
        // 更新数据
        // 更新完后调用该方法结束刷新
        list.clear();
        for (int i = 0; i < 10; i++) {
          list.add(new HashMap<String, String>());
        }
        adapter.notifyDataSetChanged();
        swipeLayout.setRefreshing(false);
      }
    }, 2000);
  }
  /**
   * 加载更多
   */
  @Override
  public void onLoad() {
    swipeLayout.postDelayed(new Runnable() {
      @Override
      public void run() {
        // 更新数据
        // 更新完后调用该方法结束刷新
        swipeLayout.setLoading(false);
        for (int i = 0; i < 10; i++) {
          list.add(new HashMap<String, String>());
        }
        adapter.notifyDataSetChanged();
      }
    }, 2000);
  }
}


以上就可以实现上拉加载和下拉刷新了。布局文件我就不贴出来了。

下载地址:

http://download.csdn.net/detail/u014727709/9711105



欢迎start,欢迎评论,欢迎指正



相关文章
|
Android开发
Android 使用SwipeRefreshLayout实现RecyclerVeiw的下拉刷新和上拉加载
Android 使用SwipeRefreshLayout实现RecyclerVeiw的下拉刷新和上拉加载
108 0
|
JavaScript Linux
【unapp】上拉加载,下拉刷新
【unapp】上拉加载,下拉刷新
102 0
SwipeRefreshLayout 下拉刷新控件(一)
SwipeRefreshLayout 下拉刷新控件(一)
|
iOS开发
iOS开发 - 让tableView不能下拉刷新,可以上拉加载
iOS开发 - 让tableView不能下拉刷新,可以上拉加载
312 0
|
API
为RecyclerView添加下拉刷新功能
在之前的文章中,我们实现了带有header和footer功能的WrapRecyclerView。 现今App中列表的下拉刷新和上拉加载已经是一种习惯了,这两个操作也确实方便很多。 为RecyclerView添加这个功能可以通过多种方法,这里我选用了一种简单的做法。基于pulltorefresh这个库。
183 0
|
Android开发
GridView基于pulltorefresh实现下拉刷新 上拉加载更多功能
GridView基于pulltorefresh实现下拉刷新 上拉加载更多功能
RecyclerView的下拉刷新和加载更多 动画
下拉刷新和加载更多 1、https://github.com/jianghejie/XRecyclerView 2、http://blog.csdn.net/jabony/article/details/44780187   动画 1、https://github.
1946 0
|
前端开发
RecyclerView学习(五)----SwipeRefreshLayout的下拉刷新与上拉加载
SwipeRefreshLayout作为官方的下拉刷新控件,简洁美观的风格使其广泛应用在项目中。美中不足的是SwipeRefreshLayout缺少上拉加载的效果,今天结合RecyclerView实现一个支持下拉刷新与上拉加载的SwipeRefreshLayout。
1349 0