下拉刷新、上拉加载更多功能的实现

如需转载请注明出处:http://blog.csdn.net/tyhj_sf/article/details/51079448

1 实现原理

自定义DraggableListView继承ListView,重新实现onTouchEvent(MotionEvent ev)方法,在此方法中根据用户动作事件(ACTION_DOWN、ACTION_MOVE、ACTION_UP)计算用户手指滑动的方向和距离,然后根据方向和距离值控制DraggableListView的header和footer的高度。
类图如下:
这里写图片描述
在上面的类图中, 类DraggableListViewHeader是DraggableListView的header,类DraggableListViewFooter是DraggableListView的footer,这个两个类并未扩展任何组件,它们只是分别组合了header、footer需要的所有组件,例如显示刷新时间的TextView、指示箭头ImageView、进度条组件等。这是自定义组件的方法之一。
对于接口OnDraggableListViewListener,使用到Android源码中很常见的回调机制,对于这一机制不清楚的同学可以看我的这一篇文章:源码分析——从button的点击事件看Android中回调机制
原理很简单,下面直接贴出类的具体实现,注释很详细,相信你能够看懂。

2 源码

2.1 DraggableListViewHeader类源码
    package com.util.pulltorefresh_loadmore;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.RelativeLayout.LayoutParams;
import android.widget.TextView;

/**
 * 自定义Listview的header,不继承view,只是所有view组件的聚合。
 * 
 * @author tyhj_sf@163.com
 *
 */
public final class DraggableListViewHeader {

    private final static String TAG = "DraggableListViewHeader";
    /**
     * header最小高度
     */
    private final static int HEADER_HEIGHT_MIN = 0;

    /**
     * header最大高度
     */
    private final static int HEADER_HEIGHT_MAX = 100;
    /**
     * header状态:正常态,仅提示用户可下拉刷新
     */
    public final static int STATE_NORMAL = 1;
    /**
     * header状态:就绪态,提示用户松手可刷新
     */
    public final static int STATE_READY = 2;
    /**
     * header状态:提示用户正在刷新
     */
    public final static int STATE_REFRESHING = 3;
    /**
     * header状态:提示用户刷新成功,该状态仅表示刷新结束后的几秒钟内。
     */
    public final static int STATE_SUCCESS = 4;
    /**
     * header状态:提示用户刷新失败
     */
    public final static int STATE_FAILURE = 5;
    /**
     * 旋转动画持续时间
     */
    private final long ROTATE_ANIM_DURATION = 180;
    /**Root of Listview header Layout */
    private RelativeLayout header;
    /**The container of all Views*/
    private RelativeLayout viewContainer;
    private TextView actionHint;
    private TextView lastTimeHint;
    private TextView lastTime;
    private ProgressBar progressBar;
    private ImageView arrowImageView;
    private Animation headerRotateUpAnim;
    private Animation headerRotateDownAnim;
    /**宿主activity*/
    private Activity activity;
    private int headerState;

    public DraggableListViewHeader(Context context) {
        // TODO Auto-generated constructor stub
        headerState = STATE_NORMAL;
        init(context);
    }

    @SuppressLint("InflateParams")
    private void init(Context context) {
        // TODO Auto-generated method stub
        Log.d(TAG, "初始化执行开始");
        LayoutInflater layoutInflater = LayoutInflater.from(context);
        viewContainer = (RelativeLayout) layoutInflater.inflate(
                R.layout.draggablelistview_header, null);
        header = new RelativeLayout(context);
        header.setVisibility(View.GONE);
        header.addView(viewContainer, new RelativeLayout.LayoutParams(
                LayoutParams.MATCH_PARENT, HEADER_HEIGHT_MIN));
        Log.d(TAG, "NULL判别:viewContainer=" + viewContainer);
        actionHint = (TextView) viewContainer
                .findViewById(R.id.draggablelistview_header_hint_textview);
        lastTimeHint = (TextView) viewContainer
                .findViewById(R.id.draggablelistview_header_last_time_textview);
        lastTime = (TextView) viewContainer
                .findViewById(R.id.draggablelistview_header_time);
        lastTime.setText(context.getSharedPreferences(TAG, Context.MODE_PRIVATE).getString("lastTime", "未知"));
        progressBar = (ProgressBar) viewContainer
                .findViewById(R.id.draggablelistview_header_progressbar);
        arrowImageView = (ImageView) viewContainer
                .findViewById(R.id.draggablelistview_header_arrow);
        Log.d(TAG, "headerRotateUpAnim动画初始化执行开始");
        headerRotateUpAnim = new RotateAnimation(0.0f, -180.0f,
                Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
                0.5f);
        headerRotateUpAnim.setDuration(ROTATE_ANIM_DURATION);
        headerRotateUpAnim.setFillAfter(true);
        Log.d(TAG, "headerRotateDownAnim动画初始化执行开始");
        headerRotateDownAnim = new RotateAnimation(-180.0f, 0.0f,
                Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
                0.5f);
        headerRotateDownAnim.setDuration(ROTATE_ANIM_DURATION);
        headerRotateDownAnim.setFillAfter(true);
        Log.d(TAG, "初始化执行完成");
    }

    public RelativeLayout getCustumHeader() {
        Log.d(TAG, "viewContainer=" + header);
        return header;
    }

    /**
     * get the root view of layout file of header
     * 
     * @return
     */
    public RelativeLayout getViewContainer() {
        return viewContainer;
    }

    /**
     * 设置header视图的布局高度
     * 
     * @param height
     */
    public void setHeadertHeight(int height) {
        // 阈值处理
        if (height <= DraggableListViewHeader.HEADER_HEIGHT_MIN) {
            height = DraggableListViewHeader.HEADER_HEIGHT_MIN;
            if (getHeaderState() != STATE_REFRESHING) {
                header.setVisibility(View.GONE);
                Log.d(TAG, "阈值处理-STATE_NORMAL");
                setHeaderState(STATE_NORMAL);
            } else {
                // continue.
            }
        } else {
            header.setVisibility(View.VISIBLE);
            if (height > DraggableListViewHeader.HEADER_HEIGHT_MAX) {
                height = DraggableListViewHeader.HEADER_HEIGHT_MAX;
                if (getHeaderState() != STATE_REFRESHING) {
                    Log.d(TAG, "阈值处理-STATE_READY");
                    setHeaderState(STATE_READY);
                } else {
                    // continue.
                }
            } else {
                if (getHeaderState() != STATE_REFRESHING) {
                    Log.d(TAG, "阈值处理-STATE_NORMAL");
                    setHeaderState(STATE_NORMAL);
                } else {
                    // continue.
                }
            }
        }
        RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) viewContainer
                .getLayoutParams();
        Log.d(TAG, "layoutParams=" + layoutParams);
        layoutParams.height = height;
        viewContainer.setLayoutParams(layoutParams);
    }

    public int getHeaderHeight() {
        return header.getHeight();
    }

    /**
     * 通过补偿值更新header的高度
     * 
     * @param offset
     *            补偿值
     */
    public void updateHeaderHeightByOffset(int offset) {
        int currentHeight=header.getHeight()+offset;
        setHeadertHeight(currentHeight);
    }

    /**
     * 复位header,可视高度最小、不可视、状态为STATE_NORMAL
     */
    public void resetHeader() {
        setHeadertHeight(DraggableListViewHeader.HEADER_HEIGHT_MIN);
        header.setVisibility(View.GONE);
        header.clearAnimation();
        setHeaderState(DraggableListViewHeader.STATE_NORMAL);
    }

    public void setHeaderState(int state) {
        if (state == DraggableListViewHeader.STATE_REFRESHING) {
            arrowImageView.setVisibility(View.INVISIBLE);
            progressBar.setVisibility(View.VISIBLE);
            lastTimeHint.setVisibility(View.VISIBLE);
            lastTime.setVisibility(View.VISIBLE);
        } else if (state == STATE_SUCCESS || state == STATE_FAILURE) {
            arrowImageView.setVisibility(View.GONE);
            progressBar.setVisibility(View.GONE);
            lastTimeHint.setVisibility(View.GONE);
            lastTime.setVisibility(View.GONE);
        } else {
            arrowImageView.setVisibility(View.VISIBLE);
            progressBar.setVisibility(View.INVISIBLE);
            lastTimeHint.setVisibility(View.VISIBLE);
            lastTime.setVisibility(View.VISIBLE);
        }
        switch (state) {
        case DraggableListViewHeader.STATE_NORMAL:
            actionHint.setText(R.string.draggablelistview_header_hint_normal);
            if (headerState == DraggableListViewHeader.STATE_READY) {
                arrowImageView.startAnimation(headerRotateDownAnim);
            } else {
                arrowImageView.clearAnimation();
            }
            Log.d(TAG, "处理STATE_NORMAL工作完成");
            break;
        case DraggableListViewHeader.STATE_READY:
            if (headerState != DraggableListViewHeader.STATE_READY) {
                actionHint
                        .setText(R.string.draggablelistview_header_hint_ready);
                arrowImageView.startAnimation(headerRotateUpAnim);
            } else {
                // continue.
            }
            Log.d(TAG, "处理STATE_READY工作完成");
            break;
        case DraggableListViewHeader.STATE_REFRESHING:
            actionHint
                    .setText(R.string.draggablelistview_header_hint_refreshing);
            arrowImageView.clearAnimation();
            break;
        case DraggableListViewHeader.STATE_SUCCESS:
            actionHint
                    .setText(R.string.draggablelistview_header_hint_refresh_finished);
            // TODO更新刷新完成的时间
            SimpleDateFormat formatter = new SimpleDateFormat(
                    "MM月dd日  HH:mm:ss");
            Date curDate = new Date(System.currentTimeMillis());
            String str = formatter.format(curDate);
            lastTime.setText(str);
            SharedPreferences sharedPreferences=activity.getSharedPreferences(TAG, Context.MODE_PRIVATE);
            sharedPreferences.edit().putString("lastTime", str).apply();
            Log.d(TAG, "处理STATE_FINISHED工作完成");
            break;
        case DraggableListViewHeader.STATE_FAILURE:
            actionHint
                    .setText(R.string.draggablelistview_header_hint_refresh_failure);
            Log.d(TAG, "处理STATE_FAILURE工作完成");
            break;
        default:
            break;
        }
        headerState = state;
    }

    public int getHeaderState() {
        return headerState;
    }


    /**
     * 提示刷新成功
     * @param activity 宿主activity
     */
    public void showRefreshSuccess(Activity activity) {
        this.activity=activity;
        if (!Thread.currentThread().getName().equals("MAIN")) {
            activity.runOnUiThread(new Runnable() {

                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    setHeaderState(STATE_SUCCESS);
                }
            });
        }else {
            setHeaderState(STATE_SUCCESS);
        }
        Timer timer=new Timer();
        timer.schedule(new UiTask(activity,timer), 2500);
    }

    /**
     * 提示刷新失败
     * @param activity 宿主activity
     */
    public void showRefreshFailure(Activity activity) {
        this.activity=activity;
        if (!Thread.currentThread().getName().equals("MAIN")) {
            activity.runOnUiThread(new Runnable() {

                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    setHeaderState(STATE_FAILURE);
                }
            });
        }else {
            setHeaderState(STATE_FAILURE);
        }
        Timer timer=new Timer();
        timer.schedule(new UiTask(activity,timer), 2500);
    }

    /**
     * 处理UI任务
     * @author tyhj_sf@163.com
     *
     */
    private class UiTask extends TimerTask{
        Activity activity;
        Timer timer;
        public UiTask(Activity activity,Timer timer) {
            // TODO Auto-generated constructor stub
            super();
            this.activity=activity;
            this.timer=timer;
        }

        @Override
        public void run() {
            // TODO 使header不可视
            activity.runOnUiThread(new Runnable() {

                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    header.setVisibility(View.GONE);
                    resetHeader();
                    timer.cancel();
                }
            });
        }

    }
}
2.2 DraggableListViewFooter的源码
package com.util.pulltorefresh_loadmore;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.RelativeLayout.LayoutParams;
import android.widget.TextView;

/**
 * 不继承view,只是所有view组件的聚合。
 * 
 * @author Administrator
 *
 */
public class DraggableListViewFooter {

    private final static String TAG = "DraggableListViewFooter";
    private final static int FOOTER_HEIGHT_MIN = 0;
    private final static int FOOTER_HEIGHT_MAX = 80;

    /**
     * footer状态:正常态,仅提示用户可上拉加载更多
     */
    public final static int STATE_NORMAL = 1;
    /**
     * footer状态:就绪态,提示用户松手可加载
     */
    public final static int STATE_READY = 2;
    /**
     * footer状态:提示用户正在加载更多
     */
    public final static int STATE_REFRESHING = 3;
    /**
     * footer状态:提示用户刷新成功,该状态仅表示刷新结束后的几秒钟内。
     */
    public final static int STATE_SUCCESS = 4;
    /**
     * footer状态:提示用户刷新失败
     */
    public final static int STATE_FAILURE = 5;

    private RelativeLayout viewContainer;
    /**
     * footer布局视图
     */
    private RelativeLayout footer;
    private TextView actionHint;
    private ProgressBar progressBar;
    private int footerState;

    public DraggableListViewFooter(Context context) {
        // TODO Auto-generated constructor stub
        init(context);
    }

    /**
     * 初始化视图
     * 
     * @param context
     */
    @SuppressLint("InflateParams")
    private void init(Context context) {
        // TODO Auto-generated method stub
        viewContainer = (RelativeLayout) LayoutInflater.from(context).inflate(
                R.layout.draggablistview_footer, null);
        footer = new RelativeLayout(context);
        footer.addView(viewContainer, new RelativeLayout.LayoutParams(
                LayoutParams.MATCH_PARENT, FOOTER_HEIGHT_MIN));
        footer.setVisibility(View.GONE);
        actionHint = (TextView) viewContainer
                .findViewById(R.id.draggablelistview_footer_hint_textview);
        progressBar = (ProgressBar) viewContainer
                .findViewById(R.id.draggablelistview_footer_progressbar);
        footerState = DraggableListViewFooter.STATE_NORMAL;
        Log.d(TAG, "初始化执行完成");
    }

    public RelativeLayout getCustumFooter() {
        return footer;
    }

    /**
     * get the root view of layout file of fooder
     * 
     * @return
     */
    public RelativeLayout getViewContainer() {
        return viewContainer;
    }

    /**
     * 设置footer视图的布局高度
     * 
     * @param height
     */
    public void setFootertHeight(int height) {
        // 阈值处理
        if (height <= DraggableListViewFooter.FOOTER_HEIGHT_MIN) {
            height = DraggableListViewFooter.FOOTER_HEIGHT_MIN;
            footer.setVisibility(View.GONE);
            setFooterState(STATE_NORMAL);
        } else {
            footer.setVisibility(View.VISIBLE);
            if (height > DraggableListViewFooter.FOOTER_HEIGHT_MAX) {
                height = DraggableListViewFooter.FOOTER_HEIGHT_MAX;
                setFooterState(STATE_READY);
            } else {
                setFooterState(STATE_NORMAL);
            }
        }
        RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) viewContainer
                .getLayoutParams();
        layoutParams.height = height;
        viewContainer.setLayoutParams(layoutParams);
    }

    public int getFooterHeight() {
        return footer.getHeight();
    }

    /**
     * 通过补偿值更新footer的高度,根据高度阈值设定footer状态。
     * 
     * @param offset
     *            补偿值
     */
    public void updateHeaderHeightByOffset(int offset) {
        setFootertHeight(footer.getHeight() + offset);
    }

    /**
     * 复位footer,可视高度最小、不可视、状态为STATE_NORMAL
     */
    public void resetFooter() {
        setFootertHeight(DraggableListViewFooter.FOOTER_HEIGHT_MIN);
        footer.setVisibility(View.GONE);
        setFooterState(DraggableListViewFooter.STATE_NORMAL);
    }

    public void setFooterState(int state) {
        switch (state) {
        case DraggableListViewFooter.STATE_NORMAL:
            progressBar.setVisibility(View.GONE);
            actionHint.setVisibility(View.VISIBLE);
            actionHint.setText(R.string.draggablelistview_footer_hint_normal);
            break;
        case DraggableListViewFooter.STATE_READY:
            progressBar.setVisibility(View.GONE);
            actionHint.setVisibility(View.VISIBLE);
            if (footerState == DraggableListViewFooter.STATE_NORMAL) {
                actionHint
                        .setText(R.string.draggablelistview_footer_hint_ready);
            } else {
                // do nothing
            }
            break;
        case DraggableListViewFooter.STATE_REFRESHING:
            progressBar.setVisibility(View.VISIBLE);
            actionHint.setVisibility(View.GONE);
            if (footerState == DraggableListViewFooter.STATE_READY) {
                actionHint
                        .setText(R.string.draggablelistview_footer_hint_loading);
            } else {
                // do nothing
            }
            break;
        case DraggableListViewFooter.STATE_SUCCESS:
            RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) viewContainer
                    .getLayoutParams();
            layoutParams.height = 0;
            viewContainer.setLayoutParams(layoutParams);
            footer.setVisibility(View.GONE);
            break;
        case DraggableListViewFooter.STATE_FAILURE:
            footer.setVisibility(View.VISIBLE);
            progressBar.setVisibility(View.GONE);
            actionHint.setVisibility(View.VISIBLE);
            actionHint
                    .setText(R.string.draggablelistview_footer_hint_load_failure);
            break;
        default:
            break;
        }
        footerState = state;
    }

    public int getFooterState() {
        return footerState;
    }

    /**
     * 提示加载成功
     * 
     * @param activity
     *            宿主activity
     */
    public void showLoadSuccess(Activity activity) {
        if (!Thread.currentThread().getName().equals("MAIN")) {
            activity.runOnUiThread(new Runnable() {

                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    setFooterState(STATE_SUCCESS);
                }
            });
        } else {
            setFooterState(STATE_SUCCESS);
        }
    }

    /**
     * 提示加载失败
     * 
     * @param activity
     *            宿主activity
     */
    public void showLoadFailure(Activity activity) {
        if (!Thread.currentThread().getName().equals("MAIN")) {
            activity.runOnUiThread(new Runnable() {

                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    setFooterState(STATE_FAILURE);
                }
            });
        } else {
            setFooterState(STATE_FAILURE);
        }
    }

}
2.3 DraggableListView的源码
package com.util.pulltorefresh_loadmore;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.ListView;

/**
 * 自定义带下拉刷新和上拉加载更多的Listview组件
 * 
 * @author sunfeng
 * @since 2016-3-18
 *
 */
public final class DraggableListView extends ListView {

    private final static String TAG = "DraggableListView";
    private final static double FREQUENCY_CONTROL = 1.8;

    private int lastY = -1;
    private int totalItemCount = 0;
    // private OnScrollListener onDraggableListViewScrollListener;
    private DraggableListViewHeader headerView;
    private DraggableListViewFooter footerView;
    private OnDraggableListViewListener onDraggableListViewListener;

    /**
     * @param context
     */
    public DraggableListView(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
        initWithContext(context);
    }

    /**
     * @param context
     * @param attrs
     * @param defStyle
     */
    public DraggableListView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        // TODO Auto-generated constructor stub
        initWithContext(context);
    }

    /**
     * @param context
     * @param attrs
     */
    public DraggableListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
        initWithContext(context);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        // TODO Auto-generated method stub
        switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
            lastY = (int) ev.getRawY();
            totalItemCount = getAdapter().getCount();
            Log.d(TAG, "MotionEvent.ACTION_DOWN执行");
            break;
        case MotionEvent.ACTION_MOVE:
            final int offsetY = (int) ((ev.getRawY() - lastY) / DraggableListView.FREQUENCY_CONTROL);
            lastY = (int) ev.getRawY();
            // 滑动到顶部
            if ((headerView.getHeaderState() == DraggableListViewHeader.STATE_NORMAL || headerView
                    .getHeaderState() == DraggableListViewHeader.STATE_READY)
                    && (footerView.getFooterState() != DraggableListViewFooter.STATE_REFRESHING)
                    && (getFirstVisiblePosition() == 0)&&(offsetY > 0)) {
                headerView.updateHeaderHeightByOffset(offsetY);
            }
            // 滑动到底部
            if (headerView.getHeaderState() != DraggableListViewHeader.STATE_REFRESHING
                    && footerView.getFooterState() != DraggableListViewFooter.STATE_REFRESHING
                    && ((getLastVisiblePosition() == (totalItemCount - 1)) && (offsetY < 0))) {
                footerView.updateHeaderHeightByOffset(-offsetY);
            }
            Log.d(TAG, "MotionEvent.ACTION_MOVE执行");
            break;
        case MotionEvent.ACTION_UP:
            if (headerView.getHeaderState() == DraggableListViewHeader.STATE_READY) {
                headerView
                        .setHeaderState(DraggableListViewHeader.STATE_REFRESHING);
                // 刷新DraggableListView
                onDraggableListViewListener.onRefresh();
            } else if (headerView.getHeaderState() == DraggableListViewHeader.STATE_NORMAL
                    || footerView.getFooterState() != DraggableListViewFooter.STATE_NORMAL) {
                // TODO 复位header
                headerView.resetHeader();
            } else {
                // do nothing
            }
            if (footerView.getFooterState() == DraggableListViewFooter.STATE_READY) {
                footerView
                        .setFooterState(DraggableListViewFooter.STATE_REFRESHING);
                // 加载更多数据到DraggableListView
                onDraggableListViewListener.onLoadMore();
            } else if (headerView.getHeaderState() != DraggableListViewHeader.STATE_NORMAL
                    || footerView.getFooterState() == DraggableListViewFooter.STATE_NORMAL) {
                // TODO 复位footer
                footerView.resetFooter();
            } else {
                // do nothing
            }
            Log.d(TAG, "MotionEvent.ACTION_UP执行");
            break;
        default:
            // 异常终止滑动操作时,复位header和footer
            headerView.resetHeader();
            footerView.resetFooter();
            break;
        }
        return super.onTouchEvent(ev);
    }

    /**
     * 用context初始化
     * 
     * @param context
     */
    protected void initWithContext(Context context) {
        // TODO 初始化
        Log.d(TAG, "初始化开始执行");
        Thread.currentThread().setName("MAIN");
        lastY = -1;
        headerView = new DraggableListViewHeader(context);
        addHeaderView(headerView.getCustumHeader());
        footerView = new DraggableListViewFooter(context);
        addFooterView(footerView.getCustumFooter());
        Log.d(TAG, "初始化执行完成");
    }

    public DraggableListViewHeader getHeaderView() {
        return headerView;
    }

    public DraggableListViewFooter getFooterView() {
        return footerView;
    }

    public void setOnDraggableListViewListener(OnDraggableListViewListener d) {
        onDraggableListViewListener = d;
    }

    public interface OnDraggableListViewListener {

        /**
         * 下拉回调刷新
         */
        public void onRefresh();

        /**
         * 上拉加载更多
         */
        public void onLoadMore();
    }

}

3 使用方法

下面通过一个简单的实验演示这个带下拉刷新和上拉加载更多功能的Listview的使用方法。

3.1 主程序源码
package com.util.pulltorefresh_loadmore;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.util.pulltorefresh_loadmore.DraggableListView.OnDraggableListViewListener;

import android.app.Activity;
import android.app.TaskStackBuilder;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Adapter;
import android.widget.ListAdapter;
import android.widget.ProgressBar;
import android.widget.SimpleAdapter;
import android.widget.Toast;

public class MainActivity extends Activity {

    private DraggableListView draggableListView;
    private List<Map<String, String>> list;
    private Map<String, String> map;
    private Adapter adapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        draggableListView=(DraggableListView)findViewById(R.id.listview);
        draggableListView.setOnDraggableListViewListener(new OnDraggableListViewListener() {

            @Override
            public void onRefresh() {
                // TODO Auto-generated method stub
                new Thread(new Runnable() {

                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        try {
                            Thread.sleep(3000);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        draggableListView.getHeaderView().showRefreshFailure(MainActivity.this);
                    }
                }).start();
            }

            @Override
            public void onLoadMore() {
                // TODO Auto-generated method stub
                new Thread(new Runnable() {

                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        try {
                            Thread.sleep(3000);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        draggableListView.getFooterView().showLoadSuccess(MainActivity.this);
                    }
                }).start();
            }
        });

        list=new ArrayList<Map<String,String>>();
        map=new HashMap<>();
        map.put("1", "牛肉");
        map.put("2", "鸡肉");
        list.add(map);
        map=new HashMap<>();
        map.put("1", "苹果");
        map.put("2", "香蕉");
        list.add(map);
        map=new HashMap<>();
        map.put("1", "1");
        map.put("2", "11");
        list.add(map);
        map=new HashMap<>();
        map.put("1", "2");
        map.put("2", "22");
        list.add(map);
        map=new HashMap<>();
        map.put("1", "3");
        map.put("2", "33");
        list.add(map);
        map=new HashMap<>();
        map.put("1", "4");
        map.put("2", "44");
        list.add(map);
        map=new HashMap<>();
        map.put("1", "5");
        map.put("2", "55");
        list.add(map);
        map=new HashMap<>();
        map.put("1", "6");
        map.put("2", "66");
        list.add(map);
        map=new HashMap<>();
        map.put("1", "7");
        map.put("2", "77");
        list.add(map);
        map=new HashMap<>();
        map.put("1", "8");
        map.put("2", "88");
        list.add(map);
        map=new HashMap<>();
        map.put("1", "9");
        map.put("2", "99");
        list.add(map);
        map=new HashMap<>();
        map.put("1", "0");
        map.put("2", "00");
        list.add(map);
        map=new HashMap<>();
        map.put("1", "11");
        map.put("2", "111");
        list.add(map);
        adapter=new SimpleAdapter(this, list, R.layout.listitem, new String[]{"1","2"}, new int[]{R.id.item_1,R.id.item_2});
        draggableListView.setAdapter((ListAdapter)adapter);
    }
}
3.2 布局文件

布局文件很简单,这里直接贴出来。
activity_main.xml文件:

<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="${relativePackage}.${activityClass}">
    <com.util.pulltorefresh_loadmore.DraggableListView
        android:id="@+id/listview"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</RelativeLayout>

listitem.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/item_1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="16sp" />
    <TextView
        android:id="@+id/item_2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="16sp" />
</LinearLayout>

4 说明

这个源码完全是本人的实现思路,很简单,通过阅读源码相信你能看懂的。
有不足的地方欢迎留言或私信我提出。
有需要完整源代码同学请发私信留下你的邮箱。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值