上拉加载更多

上拉加载更多demo分析+实现:

     

(效果如图至于乱码,是demo是gbk,用utf-8打开,并无大碍)

让我们接下来搞一搞这坨吧,然后下一坨搞一搞下拉刷新:

一. 我们就一个MainActivity来进行的页面:

首先:一个ListView搞出来:

<ListView
        android:id="@+id/ll_main"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
然后:搞一个listviewitem出来:

<TextView
        android:id="@+id/tv_item"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="让我们一起摇摆"
        android:layout_gravity="center"/>
最后:搞一个上拉加载更多的东西:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingTop="20dip"
    android:paddingBottom="20dip"
    android:orientation="horizontal" android:visibility="gone" >

    <ProgressBar
        android:id="@+id/progressBar2"
        style="?android:attr/progressBarStyleSmall"
        android:layout_gravity="center_vertical"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/loadmore_text"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textSize="18dip"
        android:text="数据加载中..."
        />

</LinearLayout>
 

二. 接下来就是一些代码实现了:

package com.xzw.demo;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.HashMap;

public class MainActivity extends Activity implements OnScrollListener {
	
	private static final String TAG = "MainActivity";
	
	private ListView listView;
	private View moreView; //加载更多页面
	
	private SimpleAdapter adapter;
	private ArrayList<HashMap<String, String>> listData;
	
	private int lastItem;
    private int count;
     
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        listView = (ListView)findViewById(R.id.listView);
        moreView = getLayoutInflater().inflate(R.layout.load, null);
        listData = new ArrayList<HashMap<String,String>>();
        
        prepareData(); //准备数据
        count = listData.size();
     
        adapter = new SimpleAdapter(this, listData,R.layout.item, 
        		new String[]{"itemText"}, new int[]{R.id.itemText});
        
        listView.addFooterView(moreView); //添加底部view,一定要在setAdapter之前添加,否则会报错。
        
        listView.setAdapter(adapter); //设置adapter
        listView.setOnScrollListener(this); //设置listview的滚动事件
    }

    private void prepareData(){  //准备数据
    	for(int i=0;i<10;i++){
    		HashMap<String, String> map = new HashMap<String, String>();
    		map.put("itemText", "测试数据"+i);
    		listData.add(map);
    	}
    	
    }
    
    private void loadMoreData(){ //加载更多数据
    	 count = adapter.getCount(); 
    	for(int i=count;i<count+5;i++){
    		HashMap<String, String> map = new HashMap<String, String>();
    		map.put("itemText", "测试数据"+i);
    		listData.add(map);
    	}
    	count = listData.size();
    }

	@Override
	public void onScroll(AbsListView view, int firstVisibleItem,
			int visibleItemCount, int totalItemCount) {
		
		Log.i(TAG, "firstVisibleItem="+firstVisibleItem+"\nvisibleItemCount="+
				visibleItemCount+"\ntotalItemCount"+totalItemCount);
		
		lastItem = firstVisibleItem + visibleItemCount - 1;  //减1是因为上面加了个addFooterView
		
	}

	@Override
	public void onScrollStateChanged(AbsListView view, int scrollState) { 
		Log.i(TAG, "scrollState="+scrollState);
		//下拉到空闲是,且最后一个item的数等于数据的总数时,进行更新
		if(lastItem == count  && scrollState == this.SCROLL_STATE_IDLE){ 
			Log.i(TAG, "拉到最底部");
			moreView.setVisibility(view.VISIBLE);
		 
		    mHandler.sendEmptyMessage(0);
			 
		}
		
	}
	//声明Handler
	private Handler mHandler = new Handler(){
		public void handleMessage(android.os.Message msg) {
			switch (msg.what) {
			case 0:
			     
				try {
					Thread.sleep(3000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			    loadMoreData();  //加载更多数据,这里可以使用异步加载
			    adapter.notifyDataSetChanged();
			    moreView.setVisibility(View.GONE); 
			    
			    if(count > 30){
			    	Toast.makeText(MainActivity.this, "木有更多数据!", Toast.LENGTH_LONG).show();
			          listView.removeFooterView(moreView); //移除底部视图
			    }
				Log.i(TAG, "加载更多数据");
				break;
            case 1:
				
				break;
			default:
				break;
			}
		};
	};
    
}

主要分为这么几个部分:

数据准备:是将我们用到的数据放到一个hashmap的arraylist中,通过循环将数据加入:

for(int i=0;i<10;i++){
    		HashMap<String, String> map = new HashMap<String, String>();
    		map.put("itemText", "测试数据"+i);
    		listData.add(map);
    	}
(初始0-9,共十条数据,测试数据0-9)

数据更多:是创造更多的数据到arraylist中,依旧是循环添加:

 count = adapter.getCount(); 
    	for(int i=count;i<count+5;i++){
    		HashMap<String, String> map = new HashMap<String, String>();
    		map.put("itemText", "测试数据"+i);
    		listData.add(map);
    	}
    	count = listData.size();
继续添加呗;注意count的变化即可。每次数据改变之后,修改count,使moredata能够正确加载更多数据

onScroll和onScrollStateChanged是implements AbsListView.OnScrollListener之后的方法,主要是用来监听滑动事件:

onScroll:

 lastItem = firstVisibleItem + visibleItemCount - 1;  //减1是因为上面加了个addFooterView

onScrollStateChanged:

if(lastItem == count  && scrollState == this.SCROLL_STATE_IDLE){
            Log.i(TAG, "拉到最底部");
            moreView.setVisibility(view.VISIBLE);

            mHandler.sendEmptyMessage(0);

        }

mHandle:

private Handler mHandler = new Handler(){
        public void handleMessage(android.os.Message msg) {
            switch (msg.what) {
                case 0:

                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    loadMoreData();  //加载更多数据,这里可以使用异步加载
                    adapter.notifyDataSetChanged();
                    moreView.setVisibility(View.GONE);

                    if(count > 30){
                        Toast.makeText(MainActivity.this, "木有更多数据!", Toast.LENGTH_LONG).show();
                        listView.removeFooterView(moreView); //移除底部视图
                    }
                    Log.i(TAG, "加载更多数据");
                    break;
                case 1:

                    break;
                default:
                    break;
            }
        };
    };

总结来说就是:

不断的去改变item的count,在拖动到item到底-1意味着要把加载更多数据这个不算,然后并且是停止状态且“手指”未在item上,moreView可见,之后我们handler发一个空消息,然后去handmessage中去判断哪个消息,在该方法加载更多数据,刷新adapter,并将moreView不可见。

在最后我们去了解几个方法:

(a)SimpleAdapter

SimpleAdapter是扩展性最好的适配器,可以定义各种你想要的布局。

第一个参数 表示访问整个android应用程序接口,基本上所有的组件都需要。
第二个参数表示生成一个Map(String ,Object)列表选项
第三个参数表示界面布局的id  表示该文件作为列表项的组件
第四个参数表示该Map对象的哪些key对应value来生成列表项
第五个参数表示来填充的组件 Map对象key对应的资源一依次填充组件 顺序有对应关系
注意的是map对象可以key可以找不到 但组件的必须要有资源填充  因为 找不到key也会返回null 其实就相当于给了一个null资源

adapter=new SimpleAdapter(this,listData,R.layout.listview_main_item,
                new String[]{"itemText"},new int[]{R.id.tv_item});
在本例子中,依次:

上下文

数据

item布局

数据中的对应,比如我们的数据是hanshmap--->键值对是ietmText,测试数据+i--->此处对应的键

此处对应键值对中对应的哪一个id也就是哪一个控件,这样就将某控件与数据联系起来,且把item布局联系起来

(b)onScroll

 public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) 

  /**
            * firstVisibleItem 表示在当前屏幕<span style="color:#FF0000;">显示</span>的第一个listItem在整个listView里面的位置(下标从0开始)
            * visibleItemCount表示在现时屏幕<span style="color:#FF0000;">可以见到</span>的ListItem(部分显示的ListItem也算)<span style="color:#FF0000;">总数</span>
            * totalItemCount表示<span style="color:#FF0000;">ListView的ListItem总数</span> 
            * listView.<span style="color:#FF0000;">getLast</span>VisiblePosition()表示在现时屏幕最后一个ListItem
            * (最后ListItem要完全显示出来才算)在整个ListView的位置(下标从0开始) 
            */  
此处主要用来判断到没到底部 此处主要用来得到底部

(c)onScrollStateChanged 滑动状态

在此处判断静止,并且加上判断是否到底部来进行下一步操作

——————————————————————————————

   

——————

在代码中Progressbar 是引入了新的style,但是自己并没有去引入,所以与demo有出入

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值