关闭

实现滑动到底部时上拉加载更多的功能的listview

标签: javaandroid开发android应用
1054人阅读 评论(0) 收藏 举报
分类:

先看效果图:


[java] view plain copy
 print?
  1. /** 
  2.  * 继承自SwipeRefreshLayout,从而实现滑动到底部时上拉加载更多的功能. 
  3.  */  
  4. public class RefreshLayout extends SwipeRefreshLayout implements  
  5.         OnScrollListener {  
  6.   
  7.     /** 
  8.      * 滑动到最下面时的上拉操作 
  9.      */  
  10.   
  11.     private int mTouchSlop;  
  12.     /** 
  13.      * listview实例 
  14.      */  
  15.     private ListView mListView;  
  16.   
  17.     /** 
  18.      * 上拉监听器, 到了最底部的上拉加载操作 
  19.      */  
  20.     private OnLoadListener mOnLoadListener;  
  21.   
  22.     /** 
  23.      * ListView的加载中footer 
  24.      */  
  25.     private View mListViewFooter;  
  26.   
  27.     /** 
  28.      * 按下时的y坐标 
  29.      */  
  30.     private int mYDown;  
  31.     /** 
  32.      * 抬起时的y坐标, 与mYDown一起用于滑动到底部时判断是上拉还是下拉 
  33.      */  
  34.     private int mLastY;  
  35.     /** 
  36.      * 是否在加载中 ( 上拉加载更多 ) 
  37.      */  
  38.     private boolean isLoading = false;  
  39.   
  40.     /** 
  41.      * @param context 
  42.      */  
  43.     public RefreshLayout(Context context) {  
  44.         this(context, null);  
  45.     }  
  46.   
  47.     @SuppressLint("InflateParams")  
  48.     public RefreshLayout(Context context, AttributeSet attrs) {  
  49.         super(context, attrs);  
  50.   
  51.         mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();  
  52.   
  53.         mListViewFooter = LayoutInflater.from(context).inflate(  
  54.                 R.layout.listview_footer, nullfalse);  
  55.     }  
  56.   
  57.     @Override  
  58.     protected void onLayout(boolean changed, int left, int top, int right,  
  59.             int bottom) {  
  60.         super.onLayout(changed, left, top, right, bottom);  
  61.         // 初始化ListView对象  
  62.         if (mListView == null) {  
  63.             getListView();  
  64.         }  
  65.     }  
  66.   
  67.     /** 
  68.      * 获取ListView对象 
  69.      */  
  70.     private void getListView() {  
  71.         int childs = getChildCount();  
  72.         if (childs > 0) {  
  73.             View childView = getChildAt(0);  
  74.             if (childView instanceof ListView) {  
  75.                 mListView = (ListView) childView;  
  76.                 // 设置滚动监听器给ListView, 使得滚动的情况下也可以自动加载  
  77.                 mListView.setOnScrollListener(this);  
  78.                 Log.d(VIEW_LOG_TAG, "### 找到listview");  
  79.             }  
  80.         }  
  81.     }  
  82.   
  83.     /* 
  84.      * (non-Javadoc) 
  85.      *  
  86.      * @see android.view.ViewGroup#dispatchTouchEvent(android.view.MotionEvent) 
  87.      */  
  88.     @Override  
  89.     public boolean dispatchTouchEvent(MotionEvent event) {  
  90.         final int action = event.getAction();  
  91.   
  92.         switch (action) {  
  93.         case MotionEvent.ACTION_DOWN:  
  94.             // 按下  
  95.             mYDown = (int) event.getRawY();  
  96.             break;  
  97.   
  98.         case MotionEvent.ACTION_MOVE:  
  99.             // 移动  
  100.             mLastY = (int) event.getRawY();  
  101.             break;  
  102.   
  103.         case MotionEvent.ACTION_UP:  
  104.             // 抬起  
  105.             if (canLoad()) {  
  106.                 loadData();  
  107.             }  
  108.             break;  
  109.         default:  
  110.             break;  
  111.         }  
  112.   
  113.         return super.dispatchTouchEvent(event);  
  114.     }  
  115.   
  116.     /** 
  117.      * 是否可以加载更多, 条件是到了最底部, listview不在加载中, 且为上拉操作. 
  118.      *  
  119.      * @return 
  120.      */  
  121.     private boolean canLoad() {  
  122.         return isBottom() && !isLoading && isPullUp();  
  123.     }  
  124.   
  125.     /** 
  126.      * 判断是否到了最底部 
  127.      */  
  128.     private boolean isBottom() {  
  129.   
  130.         if (mListView != null && mListView.getAdapter() != null) {  
  131.             return mListView.getLastVisiblePosition() == (mListView  
  132.                     .getAdapter().getCount() - 1);  
  133.         }  
  134.         return false;  
  135.     }  
  136.   
  137.     /** 
  138.      * 是否是上拉操作 
  139.      *  
  140.      * @return 
  141.      */  
  142.     private boolean isPullUp() {  
  143.         return (mYDown - mLastY) >= mTouchSlop;  
  144.     }  
  145.   
  146.     /** 
  147.      * 如果到了最底部,而且是上拉操作.那么执行onLoad方法 
  148.      */  
  149.     private void loadData() {  
  150.         if (mOnLoadListener != null) {  
  151.             // 设置状态  
  152.             setLoading(true);  
  153.             //  
  154.             mOnLoadListener.onLoad();  
  155.         }  
  156.     }  
  157.   
  158.     /** 
  159.      * @param loading 
  160.      */  
  161.     public void setLoading(boolean loading) {  
  162.         isLoading = loading;  
  163.         if (isLoading) {  
  164.             mListView.addFooterView(mListViewFooter);  
  165.         } else {  
  166.             mListView.removeFooterView(mListViewFooter);  
  167.             mYDown = 0;  
  168.             mLastY = 0;  
  169.         }  
  170.     }  
  171.   
  172.     /** 
  173.      * @param loadListener 
  174.      */  
  175.     public void setOnLoadListener(OnLoadListener loadListener) {  
  176.         mOnLoadListener = loadListener;  
  177.     }  
  178.   
  179.     @Override  
  180.     public void onScrollStateChanged(AbsListView view, int scrollState) {  
  181.   
  182.     }  
  183.   
  184.     @Override  
  185.     public void onScroll(AbsListView view, int firstVisibleItem,  
  186.             int visibleItemCount, int totalItemCount) {  
  187.         // 滚动时到了最底部也可以加载更多  
  188.         if (canLoad()) {  
  189.             loadData();  
  190.         }  
  191.     }  
  192.       
  193.     /** 
  194.      * 设置刷新 
  195.      */  
  196.     public static void setRefreshing(SwipeRefreshLayout refreshLayout,  
  197.             boolean refreshing, boolean notify) {  
  198.         Class<? extends SwipeRefreshLayout> refreshLayoutClass = refreshLayout  
  199.                 .getClass();  
  200.         if (refreshLayoutClass != null) {  
  201.   
  202.             try {  
  203.                 Method setRefreshing = refreshLayoutClass.getDeclaredMethod(  
  204.                         "setRefreshing"boolean.classboolean.class);  
  205.                 setRefreshing.setAccessible(true);  
  206.                 setRefreshing.invoke(refreshLayout, refreshing, notify);  
  207.             } catch (NoSuchMethodException e) {  
  208.                 e.printStackTrace();  
  209.             } catch (IllegalAccessException e) {  
  210.                 e.printStackTrace();  
  211.             } catch (InvocationTargetException e) {  
  212.                 e.printStackTrace();  
  213.             }  
  214.         }  
  215.     }  
  216.   
  217.     /** 
  218.      * 加载更多的监听器 
  219.      */  
  220.     public static interface OnLoadListener {  
  221.         public void onLoad();  
  222.     }  
  223. }  

自定义适配器

[java] view plain copy
 print?
  1. public class MyAdapter extends BaseAdapter {  
  2.     public ArrayList<HashMap<String, String>> list;  
  3.     public Context context;  
  4.     public LayoutInflater layoutInflater;  
  5.   
  6.     public MyAdapter(Context context, ArrayList<HashMap<String, String>> list) {  
  7.         this.context = context;  
  8.         this.list = list;  
  9.         layoutInflater = LayoutInflater.from(context);  
  10.     }  
  11.   
  12.     @Override  
  13.     public int getCount() {  
  14.         return list.size();  
  15.     }  
  16.   
  17.     @Override  
  18.     public Object getItem(int position) {  
  19.         return null;  
  20.     }  
  21.   
  22.     @Override  
  23.     public long getItemId(int position) {  
  24.         return 0;  
  25.     }  
  26.   
  27.     @Override  
  28.     public View getView(int position, View convertView, ViewGroup parent) {  
  29.         View view = null;  
  30.         ViewHolder holder = null;  
  31.         if (convertView == null) {  
  32.             view = layoutInflater.inflate(R.layout.item, null);  
  33.             holder = new ViewHolder();  
  34.             holder.txt  =(TextView) view.findViewById(R.id.textView1);  
  35.             view.setTag(holder);  
  36.         } else {  
  37.             view = convertView;  
  38.             holder = (ViewHolder) view.getTag();  
  39.         }  
  40.         holder.txt.setText(list.get(position).get("itemText"));  
  41.         return view;  
  42.     }  
  43.   
  44.     static class ViewHolder {  
  45.           
  46.         TextView txt;  
  47.     }  
  48.   
  49. }  

新建一个Activity展示

[java] view plain copy
 print?
  1. public class MainActivity extends Activity implements OnRefreshListener,  
  2.         OnLoadListener {  
  3.     private RefreshLayout swipeLayout;  
  4.     private ListView listView;  
  5.     private MyAdapter adapter;  
  6.     private ArrayList<HashMap<String, String>> list;  
  7.     private View header;  
  8.     @Override  
  9.     public void onCreate(Bundle savedInstanceState) {  
  10.         super.onCreate(savedInstanceState);  
  11.         setContentView(R.layout.activity_main);  
  12.         initView();  
  13.         setData();  
  14.         setListener();  
  15.         /*设置自动刷新 swipeLayout.setRefreshing(true); 
  16.         在 setRefreshing(true)并没有触发onRefresh的,须要手动调用一次 
  17.         */  
  18. //      swipeLayout.post(new Thread(new Runnable() {  
  19. //          @Override  
  20. //          public void run() {  
  21. //              swipeLayout.setRefreshing(true);  
  22. //          }  
  23. //      }));  
  24. //      onRefresh();  
  25.     }  
  26.   
  27.     /** 
  28.      * 初始化布局 
  29.      */  
  30.     @SuppressLint({ "InlinedApi""InflateParams" })  
  31.     private void initView() {  
  32.         header = getLayoutInflater().inflate(R.layout.header, null);  
  33.         swipeLayout = (RefreshLayout) findViewById(R.id.swipe_container);  
  34.         swipeLayout.setColorSchemeResources(R.color.color_bule2,R.color.color_bule,R.color.color_bule2,R.color.color_bule3);  
  35.     }  
  36.   
  37.     /** 
  38.      * 添加数据 
  39.      */  
  40.     private void setData() {  
  41.         list = new ArrayList<HashMap<String, String>>();  
  42.         for (int i = 0; i < 10; i++) {  
  43.             HashMap<String, String> map = new HashMap<String, String>();    
  44.             map.put("itemImage", i+"默认");    
  45.             map.put("itemText", i+"默认");    
  46.             list.add(map);  
  47.         }  
  48.         listView = (ListView) findViewById(R.id.list);  
  49.         listView.addHeaderView(header);  
  50.         adapter = new MyAdapter(this, list);  
  51.         listView.setAdapter(adapter);  
  52.     }  
  53.   
  54.     /** 
  55.      * 设置监听 
  56.      */  
  57.     private void setListener() {  
  58.         swipeLayout.setOnRefreshListener(this);  
  59.         swipeLayout.setOnLoadListener(this);  
  60.     }  
  61.   
  62.     /** 
  63.      * 上拉刷新 
  64.      */  
  65.     @Override  
  66.     public void onRefresh() {  
  67.         swipeLayout.postDelayed(new Runnable() {  
  68.   
  69.             @Override  
  70.             public void run() {  
  71.                 // 更新数据  更新完后调用该方法结束刷新  
  72.                 list.clear();  
  73.                 for (int i = 0; i < 8; i++) {  
  74.                     HashMap<String, String> map = new HashMap<String, String>();    
  75.                     map.put("itemImage", i+"刷新");    
  76.                     map.put("itemText", i+"刷新");    
  77.                     list.add(map);  
  78.                 }  
  79.                 adapter.notifyDataSetChanged();  
  80.                 swipeLayout.setRefreshing(false);  
  81.             }  
  82.         }, 2000);  
  83.   
  84.     }  
  85.   
  86.     /** 
  87.      * 加载更多 
  88.      */  
  89.     @Override  
  90.     public void onLoad() {  
  91.         swipeLayout.postDelayed(new Runnable() {  
  92.             @Override  
  93.             public void run() {  
  94.                 // 更新数据  更新完后调用该方法结束刷新  
  95.                 swipeLayout.setLoading(false);  
  96.                 for (int i = 1; i < 10; i++) {  
  97.                     HashMap<String, String> map = new HashMap<String, String>();    
  98.                     map.put("itemImage", i+"更多");    
  99.                     map.put("itemText", i+"更多");    
  100.                     list.add(map);  
  101.                 }  
  102.                 adapter.notifyDataSetChanged();  
  103.             }  
  104.         }, 2000);  
  105.     }  
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:162692次
    • 积分:3030
    • 等级:
    • 排名:第11498名
    • 原创:151篇
    • 转载:24篇
    • 译文:0篇
    • 评论:14条
    最新评论