Android ListView 下拉刷新 上拉加载

没耐心的直接拿demo吧,下载(1分) 

很多地方都会有listview下拉刷新数据,上拉加载更多的需求

网上找了一大堆,讲的都不是太明白,自己弄了一个下午勉强实现了,部分地方有一些BUG,欢迎探讨

首先是布局文件

整个页面分为三块,一个是中间的listview,上面的是下拉后显示的等待框,下面是上拉后显示的等待框

设定两个等待框的高度为0隐藏起来,再设定listview的布局在updatecontent的下方,waitcontent的上方

布局代码如下

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/RelativeLayout1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >
    <RelativeLayout
        android:id="@+id/updatecontent"
        android:layout_width="wrap_content"
        android:layout_height="1dp" >

        <ProgressBar
            android:id="@+id/progressBar2"
            style="?android:attr/progressBarStyleLarge"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </RelativeLayout>

    <RelativeLayout
        android:id="@+id/RelativeLayout2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/waitcontent"
        android:layout_below="@+id/updatecontent"
        android:orientation="vertical" >
        <ListView
            android:id="@+id/listView1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_alignParentLeft="true" >

        </ListView>
    </RelativeLayout>

    <RelativeLayout
        android:id="@+id/waitcontent"
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:layout_alignParentBottom="true"
        android:orientation="vertical" >

        <ProgressBar
            android:id="@+id/progressBar1"
            style="?android:attr/progressBarStyleLarge"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_alignParentTop="true" />
    </RelativeLayout>

</RelativeLayout>


 

接下来是上拉下拉的实现,

设定了listview有5种状态

	public enum ListState              //listview的状态
	{
	  Normal,         //一般
	  InBottom,	//在最底部,再向上滑动就要获取数据
	  PullUp,         //向上滑动中
	  Rflesh,		//获取数据中
	  InTop,		//在最顶部,再向下滑动就要更新数据
	  PullDown	//向下滑动中
	}


关系如下

渣工具,渣画法,大家凑活着看

核心思路在于,

为listview注册监听函数,在滑动过程中(MotionEvent.ACTION_MOVE)检测listview是否在顶部,或者底部

如果在顶部则跳到InTop状态,记录当前的触摸位置,如果继续滑动则跳到PullDown状态,用现在的触摸高度减去前面记录的高度

然后不断的设定updatecontent的高度,高度为前面减得的值,将listview挤下去

松手后(MotionEvent.ACTION_UP) 将updatecontent重新设为0隐藏起来

然后就可以开始更新数据

上拉加载也是同样的思路

核心代码如下

 listView.setOnTouchListener(new OnTouchListener() {
			
	public boolean onTouch(View v, MotionEvent event) {
		switch(event.getAction())
		{
		   case MotionEvent.ACTION_UP:
			TouchUp(event);
				break;
		   case MotionEvent.ACTION_MOVE:
			TouchMove(event);
				break;
		};
		//两种状态可以使listview滑动,其他状态则直接吃掉触摸事件,使listview不能滑动
		if(state==ListState.Normal||state==ListState.InTop)
		{
		return false;
		}
		else 
		{
		return true;
		}
	}
});


 

   //滑动过程中事件的处理
protected void TouchMove(MotionEvent event) {
		
	double height; //要设定的控件高度
		
	int postion=listView.getLastVisiblePosition();
	int f_postion=listView.getFirstVisiblePosition();
		
	boolean isbottom=((postion+1)==list.size());  //是否在底部
	boolean istop=(f_postion==0);                 //是否在顶部
		
	switch(state.ordinal())
	{
	case 0: //正常
		if(isbottom)
		{
			state=ListState.InBottom;
		}
		if(istop)
		{
			state=ListState.InTop;
		}
			break;
	case 1: //在底部,准备上拉
		bottomPostion=event.getY();
		state=ListState.PullUp;
		break;
	case 2:  //上拉过程中
		height=bottomPostion-event.getY();
		setWaitContent(height);
		break;
	case 3:   //更新过程中
		break;
	case 4:    //在顶部准备下拉
		if(event.getY()>lasttop&&lasttop!=0) //判断是否是向下拉动
		{
			toppostion=event.getY();
			state=ListState.PullDown;
		}
		lasttop=event.getY();
		break;
	case 5:
		if(event.getY()>lasttop) //防止抖动
		{
		height=event.getY()-toppostion;
		setUpdateContent(height);	
		lasttop=event.getY();
		}
		break;
		}
		
}


 

protected void TouchUp(MotionEvent event) {
		switch(state.ordinal())
		{
		case 0: //正常
			state=ListState.Normal;
			break;
		case 1: //在底部,准备上拉
			state=ListState.Normal;
			break;
		case 2:  //上拉过程中
			state=ListState.Rflesh;
			setWaitContent(0);     //不显示下方等待框
			addListData();         //增加数据
			state=ListState.Normal;
			break;
		case 3:   //更新过程中
			state=ListState.Normal;
			break;
		case 4:   //在最顶部
			state=ListState.Normal;
			lasttop=0;
			break;
		case 5:   //向下拖动中
			setUpdateContent(0);
			state=ListState.Normal;
			lasttop=0;
			break;
		}
	}


 

private void setUpdateContent(double height) {
		if(height<0)
			return;
		if(height>150)
			height=150;
		LayoutParams params = (LayoutParams) UpdateLayout.getLayoutParams();
		params.height=(int)height;
		UpdateLayout.setLayoutParams(params);
	}

另一个设置控件高度的代码基本一致


 

BUG在于,上拉加载的时候即使设定控件高度,listview也不会被挤上去,只会被覆盖

下拉刷新时会有抖动,所做做了个防止抖动的判断但是不知道为什么

额,希望大家多交流吧

 

demo下载(1分) 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值