自定义ListView,实现下拉刷新,上拉加载

来源:互联网 发布:淘宝卖家视频怎么上传 编辑:程序博客网 时间:2024/05/12 16:45
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:gravity="center"    >    <ImageView        android:id="@+id/image_arrow"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:src="@mipmap/indicator_arrow"        />    <ProgressBar        android:id="@+id/progressbar"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:indeterminateDrawable="@mipmap/indicate_rotate"        android:visibility="invisible"        />    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:orientation="vertical"        android:layout_toRightOf="@id/image_arrow"        >        <TextView            android:id="@+id/tv_state"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_marginLeft="30dp"            android:text="下拉刷新"            />        <TextView            android:id="@+id/tv_time"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_marginLeft="30dp"            android:layout_marginTop="20dp"            android:text="最后刷新2016-6-17"            />    </LinearLayout></RelativeLayout>

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="horizontal" android:layout_width="match_parent"    android:layout_height="match_parent"    >    <ProgressBar        android:id="@+id/itme1bar"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_marginLeft="20dp"        android:indeterminateDrawable="@mipmap/indicate_rotate"        android:visibility="visible"        />    <TextView        android:id="@+id/itme1textview"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:textColor="#ff00"        android:layout_marginLeft="30dp"        android:textStyle="bold"        android:textSize="25sp"        android:text="加载更多........"        /></LinearLayout>

package com.example.administrator.app4;import android.content.Context;import android.util.AttributeSet;import android.view.LayoutInflater;import android.view.MotionEvent;import android.view.View;import android.view.animation.Animation;import android.view.animation.RotateAnimation;import android.widget.AbsListView;import android.widget.ImageView;import android.widget.ListView;import android.widget.ProgressBar;import android.widget.TextView;/** * Created by Administrator on 2016/6/17 0017. * <p/> * 自定义ListView,把布局加载到ListView中 */public class PullListView extends ListView {    private ImageView image_arrow;//箭头图片(顶部、底部)    private ProgressBar progressBar,itme1bar;//进度条(顶部)    private TextView tv_state, tv_time,itme1textview;//顶部显示的文字、底部    private int headerHeight;//添加的顶部布局高度    private View headerView;//添加的布局(View对象,顶部)    private View footerView;//底部布局    private boolean isComplete = false;//判断是否拖动到底部了    public PullListView(Context context) {        super(context);        init();    }    public PullListView(Context context, AttributeSet attrs) {        super(context, attrs);        init();    }    private void init() {        initHeaderView();//初始化顶部View        initFooterView();//底部View        initAnimation();//动画的方法        this.setOnScrollListener(//ListrView添加滑动事件                new OnScrollListener() {                    @Override//开始和结束拖地时会调用该方法                    public void onScrollStateChanged(AbsListView view, int scrollState) {                        //停止拖地       到底部                        if (scrollState == OnScrollListener.SCROLL_STATE_IDLE && isComplete) {                            //加载更多的数据                            footerView.setPadding(0, 0, 0, 0);                            if (pullRefreshInterface != null) {                                itme1textview.setText("正在加载更多......");                                itme1bar.setVisibility(VISIBLE);//显示进度条                                itme1bar.startAnimation(animationBar);//设置进度条启动动画                                pullRefreshInterface.onMore();                            }                        }                    }                    @Override//拖地的过程中会调用该方法                    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {                        isComplete = firstVisibleItem + visibleItemCount == totalItemCount;//到底了                    }                }        );    }    private void initFooterView() {//底部布局View        LayoutInflater inflater = LayoutInflater.from(getContext());        footerView = inflater.inflate(R.layout.itme1, null);        itme1bar= (ProgressBar) footerView.findViewById(R.id.itme1bar);        itme1textview= (TextView) footerView.findViewById(R.id.itme1textview);//找到底部的控件        footerView.measure(0, 0);//强制执行该方法,测量控件大小        int footer_height = footerView.getMeasuredHeight();        //设置内边距(隐藏)        footerView.setPadding(0,-footer_height,0,0);        //把View对象添加到ListView的底部        this.addFooterView(footerView);    }    private void initHeaderView() {//顶部View        LayoutInflater inflater = LayoutInflater.from(getContext());        headerView = inflater.inflate(R.layout.itme, null);        image_arrow = (ImageView) headerView.findViewById(R.id.image_arrow);        progressBar = (ProgressBar) headerView.findViewById(R.id.progressbar);        tv_state = (TextView) headerView.findViewById(R.id.tv_state);        tv_time = (TextView) headerView.findViewById(R.id.tv_time);        //获取布局的高度        headerView.measure(0, 0);        headerHeight = headerView.getMeasuredHeight();        headerView.setPadding(0, -headerHeight, 0, 0);//设置内边距,不可见        this.addHeaderView(headerView);//把View对象加载到ListView的顶部    }    private float down_y;//点击的Y坐标    //定义表示ListView状态的常量    private final int PULLREFRESH = 0;//下拉刷新    private final int RELLRESH = 1;//松开刷新    private final int RELLRESHING = 2;//正在刷新    private int currentState = PULLREFRESH;//记录当前状态(初始化为下拉刷新)    private int paddingTop = 0;    @Override    public boolean onTouchEvent(MotionEvent ev) {        switch (ev.getAction()) {//判断ListView的状态            case MotionEvent.ACTION_DOWN://按下状态                down_y = ev.getY();//获得按下的Y坐标(高度)                break;            case MotionEvent.ACTION_MOVE://移动状态                float y = ev.getY();                //往下拉(获得用户往下拉的距离,高度)                int length = (int) (y - down_y);                paddingTop = length - headerHeight;//往下拉的距离和顶部View的内边距                //正在刷新                if (currentState == RELLRESHING) {                    break;                }                //大于顶部View的高度                if (paddingTop > -headerHeight && getFirstVisiblePosition() == 0) {                    headerView.setPadding(0, paddingTop, 0, 0);//设置顶部的内边距                    //下拉刷新                    if (paddingTop >= 0 && currentState == PULLREFRESH) {//正在刷新                        currentState = RELLRESH;//松开刷新                        refreshState();                         //松开刷新                    } else if (paddingTop < 0 && currentState == RELLRESH) {                        currentState = PULLREFRESH;//正在刷新                        refreshState();//处理事件的方法                    }                    return true;//ListView不用处理滑动事件                }                break;            case MotionEvent.ACTION_UP://松开状态                if (currentState == PULLREFRESH) {//下拉刷新                    headerView.setPadding(0, -headerHeight, 0, 0);                } else if (currentState == RELLRESH) {//松开刷新                    currentState = RELLRESHING;//正在刷新                    refreshState();                    if (pullRefreshInterface!=null) {//接口对象不为空                        pullRefreshInterface.onPull();//调用自己的方法                    }                }        }        return super.onTouchEvent(ev);//不消费此次触屏事件    }    private PullRefreshInterface pullRefreshInterface;//接口对象    private RotateAnimation animationUp,animationDown,animationBar;//旋转的补间动画对象    public void setPullRefreshInterface(PullRefreshInterface pullRefreshInterface) {        this.pullRefreshInterface = pullRefreshInterface;    }    public interface PullRefreshInterface {//回调的接口        public void onPull();        public void onMore();    }    private void refreshState() {//修改界面的显示        switch (currentState) {//当前状态            case PULLREFRESH://下拉刷新                tv_state.setText("下拉刷新");                //图片控件开始执行动画                image_arrow.startAnimation(animationDown);                break;            case RELLRESH://松开刷新                tv_state.setText("松开刷新");                image_arrow.startAnimation(animationUp);                break;            case RELLRESHING://正在刷新                tv_state.setText("正在刷新");                headerView.setPadding(0, 0, 0, 0);//设置内边距(完全显示)                //动画取消、箭头消失                image_arrow.clearAnimation();//取消动画                image_arrow.setVisibility(INVISIBLE);//隐藏控件                //进度条显示                progressBar.setVisibility(VISIBLE);                progressBar.startAnimation(animationBar);//启动动画                progressBar.setIndeterminate(true);                break;        }    }    public void initAnimation(){        //创建旋转动画        animationUp=new RotateAnimation(0,-180,                RotateAnimation.RELATIVE_TO_SELF,0.5f,                Animation.RELATIVE_TO_SELF,0.5f);        animationUp.setDuration(1000);        animationUp.setFillAfter(true);        animationDown=new RotateAnimation(-180,-360,                RotateAnimation.RELATIVE_TO_SELF,0.5f,                RotateAnimation.RELATIVE_TO_SELF,0.5f);        animationDown.setDuration(1000);        animationDown.setFillAfter(true);        //进度条的旋转        animationBar=new RotateAnimation(                0,360,RotateAnimation.RELATIVE_TO_PARENT,0.5f,                RotateAnimation.RELATIVE_TO_SELF,0.5f);        animationBar.setDuration(1000);        animationBar.setFillAfter(true);        animationBar.setRepeatCount(Animation.INFINITE);//无限循环    }    public void complete(boolean isPull){        if(isPull){            currentState=PULLREFRESH;//下拉刷新            tv_state.setText("下拉刷新");            tv_time.setText("2016-6-18");            progressBar.clearAnimation();//取消动画            progressBar.setVisibility(INVISIBLE);//进度条隐藏            headerView.setPadding(0,-headerHeight,0,0);//隐藏顶部View        }else{//隐藏底部View            itme1textview.setText("加载更多.......");            itme1bar.clearAnimation();//取消动画            itme1bar.setVisibility(INVISIBLE);//隐藏进度条            footerView.setPadding(0, -footerView.getMeasuredHeight(),0,0);        }    }}
在主UI的XML文件中使用自定义的ListView
<pre name="code" class="html"><?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="com.example.administrator.app4.MainActivity">    <com.example.administrator.app4.PullListView       android:id="@+id/listview"        android:layout_width="match_parent"        android:layout_height="match_parent"        /></RelativeLayout>


package com.example.administrator.app4;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.support.v7.app.AppCompatActivity;import android.widget.ArrayAdapter;import java.util.ArrayList;import java.util.List;/** * 下拉刷新上拉加载 *  自定义的ListView */public class MainActivity extends AppCompatActivity {    private PullListView listView;//自定义的ListView    private List<String> strs;//适配器需要的数据    private ArrayAdapter adapter;//适配器    private int connt1=1,connt2=1;    private Handler handler=new Handler(){        @Override        public void handleMessage(Message msg) {            int what=msg.what;//获取发送过来的空消息            if(what==1){                //下拉刷新完成(添加到集合里面,最上面)                strs.add(0, "第"+connt1+"次下拉刷新的新数据哦!");                adapter.notifyDataSetChanged();//提醒控件更新显示                connt1++;            //下拉刷新需要改变状态                listView.complete(true);            }else if(what==2){                //加载更多数据(底部的View)                for(int i=0;i<10;i++){                    strs.add("第"+connt2+"次,加载更多的数据"+(i+1)+"号");                }                connt2++;//自增                adapter.notifyDataSetChanged();//通知更新                listView.complete(false);            }        }    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        listView= (PullListView) findViewById(R.id.listview);        init();        adapter=new ArrayAdapter(this,android.R.layout.simple_list_item_1,strs);        listView.setAdapter(adapter);//设置适配器        setOnList();//设置监听    }    private void setOnList() {        listView.setPullRefreshInterface(//回调ListView里面的接口                new PullListView.PullRefreshInterface() {                    @Override                    public void onPull() {                        //执行具体的操作                        new Thread(){//创建子线程                            @Override                            public void run() {                                try {                                    Thread.sleep(3000);//线程休眠                                } catch (InterruptedException e) {                                    e.printStackTrace();                                }                                handler.sendEmptyMessage(1);//发送空消息回主线程(增加上面的内容)                            }                        }.start();//启动线程                    }                    @Override                    public void onMore() {                        new Thread(){//创建线程                            @Override                            public void run() {                                try {                                    Thread.sleep(3000);                                } catch (InterruptedException e) {                                    e.printStackTrace();                                }                                handler.sendEmptyMessage(2);//发送空消息(增加下面的内容)                            }                        }.start();//开启线程                    }                }        );    }    private void init() {//初始化集合        strs=new ArrayList<String>();        for(int i=0;i<30;i++){            strs.add("List原来的第"+(i+1)+"条数据");        }    }}


1 1