自定義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)+"條數據");

        }
    }


}


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