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

<?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)+"条数据");

        }
    }


}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章