您的位置:首页 > 移动开发 > Android开发

下拉刷新+加载更多的ListView(直接拿来用)

2016-07-25 11:48 603 查看
ListView Api bixu 好好看看

mNewsAdapter.notifyDataSetChanged();//刷新ListView


自定义的RefreashListView

package com.itguang.dell_pc.myapplication.view;

import android.content.Context;

import android.util.AttributeSet;

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;

import com.itguang.dell_pc.myapplication.R;

import java.text.SimpleDateFormat;

import java.util.Date;

/**

 * 作者: 小光哥 on 2016/7/7.

 * 邮箱: 1445037803@qq.com

 * 修订历史:

 * 描述:

 *         ┏┓   ┏┓

 *        ┏┛┻━━━┛┻┓━━━━┻┓

 *        ┃       ┃

 *        ┃   ━   ┃

 *        ┃ >   < ┃

 *        ┃       ┃

 *        ┃... ⌒ ... ┃

 *        ┃       ┃

 *        ┗━┓   ┏━┛

 *          ┃   ┃ Code is far away from bug with the animal protecting

 *          ┃ 史 ┃   神兽保佑,代码无bug

 *          ┃ 诗 ┃

 *          ┃ 之 ┃

 *          ┃ 宠 ┃

 *          ┃   ┃

 *          ┃   ┗━━━┓

 *          ┃BUG天敌   ┣┓┣┓┣┓┣┓┣┓

 *          ┃       ┏┛

 *          ┗┓┓┏━┳┓┏┛

 *           ┃┫┫ ┃┫┫

 *           ┗┻┛ ┗┻┛

 */

public class RefreshListView extends ListView implements AbsListView.OnScrollListener {

    private static final int STATE_PULL_REFRESH = 0;// 下拉刷新

    private static final int STATE_RELEASE_REFRESH = 1;// 松开刷新

    private static final int STATE_REFRESHING = 2;// 正在刷新

    private int mCurrrentState = STATE_PULL_REFRESH;// 当前状态

    private View mHeaderView;

    private TextView tvTitle;

    private TextView tvTime;

    private ProgressBar pbProgress;

    private ImageView ivArrow;

    private RotateAnimation animUp;

    private RotateAnimation animDown;

    private int startY = -1;// 滑动起点的y坐标

    private int endY;

    private int measuredHeight;

    private int mFooterViewHeight;

    private View footerView;

    public RefreshListView(Context context) {

        super(context);

        initHeaderView();

        initFooterView();

    }

    public RefreshListView(Context context, AttributeSet attrs) {

        super(context, attrs);

        initHeaderView();

        initFooterView();

    }

    public RefreshListView(Context context, AttributeSet attrs, int defStyleAttr) {

        super(context, attrs, defStyleAttr);

        initHeaderView();

        initFooterView();

    }

    /**

     * 初始化头布局

     */

    private void initHeaderView() {

        mHeaderView = View.inflate(getContext(), R.layout.refeeash_header, null);

        this.addHeaderView(mHeaderView);

        tvTitle = (TextView) mHeaderView.findViewById(R.id.tv_title);

        tvTime = (TextView) mHeaderView.findViewById(R.id.tv_time);

        pbProgress = (ProgressBar) mHeaderView.findViewById(R.id.pb_progress);

        ivArrow = (ImageView) mHeaderView.findViewById(R.id.iv_arr);

        mHeaderView.measure(0, 0);//先测量再拿到它的高度

        measuredHeight = mHeaderView.getMeasuredHeight();

        mHeaderView.setPadding(0, -measuredHeight, 0, 0);

        initArrowAnim();

        tvTime.setText("最后刷新时间:" + getCurrentTime());

    }

    /**

     * 初始化脚布局

     */

    public void initFooterView() {

        footerView = View.inflate(getContext(), R.layout.refreash_listview_footer, null);

        this.addFooterView(footerView);

        footerView.measure(0, 0);

        mFooterViewHeight = footerView.getMeasuredHeight();

        footerView.setPadding(0, -mFooterViewHeight, 0, 0);//默认隐藏脚布局

        this.setOnScrollListener(this);

    }

    private boolean isLoadingMOre;

    @Override

    public void onScrollStateChanged(AbsListView view, int scrollState) {

        if (scrollState == SCROLL_STATE_FLING || scrollState == SCROLL_STATE_IDLE) {

            if (getLastVisiblePosition() == getCount() - 1 && !isLoadingMOre) {//滑倒最后

                System.out.println("到底了......");

                footerView.setPadding(0, 0, 0, 0);

                setSelection(getCount() - 1);//改变ListView的显示位置

                isLoadingMOre = true;

                if (mListener != null) {

                    mListener.onLoadMore();

                }

            }

        }

    }

    @Override

    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {

    }

    @Override

    public boolean onTouchEvent(MotionEvent ev) {

        switch (ev.getAction()) {

            case MotionEvent.ACTION_DOWN:

                startY = (int) ev.getRawY();

                break;

            case MotionEvent.ACTION_MOVE:

                if (startY == -1) {//有时候不会响应 MotionEvent.ACTION_DOWN 事件,这是要重新获取startY坐标

                    startY = (int) ev.getRawY();

                }

                //当正在刷新的时候,跳出循环,不再执行下面逻辑

                if (mCurrrentState == STATE_RELEASE_REFRESH) {

                    break;

                }

                endY = (int) ev.getRawY();

                int dy = endY - startY;//计算手指滑动距离

                if (dy > 0 && getFirstVisiblePosition() == 0) {// 只有下拉并且当前是第一个item,才允许下拉

                    int padding = dy - measuredHeight;//计算padding

                    mHeaderView.setPadding(0, padding, 0, 0);//设置当前padding

                    if (padding > 0 && mCurrrentState != STATE_RELEASE_REFRESH) {

                        mCurrrentState = STATE_RELEASE_REFRESH;

                        refreshState();

                    } else if (padding < 0 && mCurrrentState != STATE_PULL_REFRESH) {// 改为下拉刷新状态

                        mCurrrentState = STATE_PULL_REFRESH;

                        refreshState();

                    }

                    return true;

                }

                break;

            case MotionEvent.ACTION_UP:

                startY = -1;//手指抬起重置

                //当状态是松开刷新时抬起了手指,正在刷新

                if (mCurrrentState == STATE_RELEASE_REFRESH) {

                    mCurrrentState = STATE_REFRESHING;// 正在刷新

                    mHeaderView.setPadding(0, 0, 0, 0);// 显示

                    refreshState();

                } else if (mCurrrentState == STATE_PULL_REFRESH) {

                    mHeaderView.setPadding(0, -measuredHeight, 0, 0);// 隐藏

                }

                break;

            default:

                break;

        }

        return super.onTouchEvent(ev);

    }

    private String getCurrentTime() {

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        String currentTime = format.format(new Date());

        return currentTime;

    }

    private void initArrowAnim() {

        //初始化箭头动画

        animUp = new RotateAnimation(0, -180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);

        animUp.setDuration(500);

        animUp.setFillAfter(true);//保持状态

        //箭头向下动画

        animDown = new RotateAnimation(-180, 0, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);

        animDown.setDuration(500);

        animDown.setFillAfter(true);

    }

    /**

     * 刷新下拉控件的布局

     */

    private void refreshState() {

        switch (mCurrrentState) {

            case STATE_PULL_REFRESH:

                tvTitle.setText("下拉刷新");

                ivArrow.setVisibility(View.VISIBLE);

                pbProgress.setVisibility(View.INVISIBLE);

                ivArrow.startAnimation(animDown);

                break;

            case STATE_RELEASE_REFRESH:

                tvTitle.setText("松开刷新");

                ivArrow.setVisibility(View.VISIBLE);

                pbProgress.setVisibility(View.INVISIBLE);

                ivArrow.startAnimation(animUp);

                break;

            case STATE_REFRESHING:

                tvTitle.setText("正在刷新...");

                ivArrow.clearAnimation();// 必须先清除动画,才能隐藏

                ivArrow.setVisibility(View.INVISIBLE);

                pbProgress.setVisibility(View.VISIBLE);

                if (mListener != null) {

                    mListener.onRefreash();

                }

                break;

            default:

                break;

        }

    }

    OnRefreashListener mListener;

    public void setOnRefreashListener(OnRefreashListener listener) {

        mListener = listener;

    }

    public interface OnRefreashListener {

        void onRefreash();

        void onLoadMore();

    }

    /**

     * 收起下拉刷新的控件

     */

    public void onRefreashComplete() {

        if (isLoadingMOre) {

            footerView.setPadding(0, -mFooterViewHeight, 0, 0);//隐藏脚布局

            isLoadingMOre = false;

        } else {

            mCurrrentState = STATE_PULL_REFRESH;

            tvTitle.setText("下拉刷新");

            ivArrow.setVisibility(View.VISIBLE);

            pbProgress.setVisibility(View.INVISIBLE);

            mHeaderView.setPadding(0, -measuredHeight, 0, 0);//隐藏

        }

    }

    public void noFooterView() {

        footerView.setPadding(0, mFooterViewHeight, 0, 0);//隐藏脚布局

    }

}


代码中引用RefreashListView

package com.itguang.dell_pc.myapplication.base;

import android.app.Activity;

import android.support.v4.view.PagerAdapter;

import android.support.v4.view.ViewPager;

import android.text.TextUtils;

import android.view.View;

import android.view.ViewGroup;

import android.widget.BaseAdapter;

import android.widget.ImageView;

import android.widget.ListView;

import android.widget.TextView;

import android.widget.Toast;

import com.google.gson.Gson;

import com.itguang.dell_pc.myapplication.R;

import com.itguang.dell_pc.myapplication.domain.NewsData;

import com.itguang.dell_pc.myapplication.domain.TabData;

import com.itguang.dell_pc.myapplication.globe.GlobeContents;

import com.itguang.dell_pc.myapplication.view.RefreshListView;

import com.lidroid.xutils.BitmapUtils;

import com.lidroid.xutils.HttpUtils;

import com.lidroid.xutils.ViewUtils;

import com.lidroid.xutils.exception.HttpException;

import com.lidroid.xutils.http.ResponseInfo;

import com.lidroid.xutils.http.callback.RequestCallBack;

import com.lidroid.xutils.http.client.HttpRequest;

import com.lidroid.xutils.view.annotation.ViewInject;

import com.viewpagerindicator.CirclePageIndicator;

import java.util.ArrayList;

/**

 * 作者: 小光哥 on 2016/4/22.

 * 邮箱: 1445037803@qq.com

 * 修订历史:

 * 描述:

 *         ┏┓   ┏┓

 *        ┏┛┻━━━┛┻┓━━━━┻┓

 *        ┃       ┃

 *        ┃   ━   ┃

 *        ┃ >   < ┃

 *        ┃       ┃

 *        ┃... ⌒ ... ┃

 *        ┃       ┃

 *        ┗━┓   ┏━┛

 *          ┃   ┃ Code is far away from bug with the animal protecting

 *          ┃ 史 ┃   神兽保佑,代码无bug

 *          ┃ 诗 ┃

 *          ┃ 之 ┃

 *          ┃ 宠 ┃

 *          ┃   ┃

 *          ┃   ┗━━━┓

 *          ┃BUG天敌   ┣┓┣┓┣┓┣┓┣┓

 *          ┃       ┏┛

 *          ┗┓┓┏━┳┓┏┛

 *           ┃┫┫ ┃┫┫

 *           ┗┻┛ ┗┻┛

 */

/**

 * 也签详情页

 */

public class TabDetailPager extends BaseMenuDetailPager implements ViewPager.OnPageChangeListener {

    /**

     * @param activity

     * @param newsTabData

     */

    NewsData.NewsTabData mTabdata;

    private String mUrl;

    private TabData mTabDetailData;

    @ViewInject(R.id.vp_news)

    private ViewPager mViewPager;

    @ViewInject(R.id.lv_newslist)

    private RefreshListView newsListView;//新闻列表

    @ViewInject(R.id.tv_title)

    private TextView tvTitle;//新闻标题

    @ViewInject(R.id.indicator)

    private CirclePageIndicator indicator;//头条新闻指示器

    private ArrayList<TabData.TopNewsData> mTopNewsList;//新闻数据集合

    private int[] images;

    private ArrayList<TabData.TabNewsData> mNewsList;//新闻数据集合

    private String mMoreUrl;

    private NewsAdapter mNewsAdapter;

    public TabDetailPager(Activity activity, NewsData.NewsTabData newsTabData) {

        super(activity);

        mTabdata = newsTabData;

        mUrl = GlobeContents.SERVER_URL + mTabdata.url;

    }

    @Override

    public View initViews() {

        images = new int[]{R.drawable.topnews1, R.drawable.topnews21, R.drawable.topnews31, R.drawable.topimage};

        View view = View.inflate(mActivity, R.layout.tab_detail_pager, null);

        View headerView = View.inflate(mActivity, R.layout.list_header_topnews, null);//加载头布局

//        TextView tvTitle = (TextView) view.findViewById(R.id.tv_title);

        //事件注入

        ViewUtils.inject(this, view);

        ViewUtils.inject(this, headerView);

        mViewPager.addOnPageChangeListener(this);

        //将肥头条新闻以头布局形式加载到listView中

        newsListView.addHeaderView(headerView);

        //设置下拉刷新监听

        newsListView.setOnRefreashListener(new RefreshListView.OnRefreashListener() {

            @Override

            public void onRefreash() {

                getDataFromServer();

            }

            @Override

            public void onLoadMore() {

                if (mMoreUrl != null) {

                    getMoreDataFromServer();

                } else {

                    Toast.makeText(mActivity, "没有更多数据了", Toast.LENGTH_SHORT).show();

                    newsListView.onRefreashComplete();

//                    newsListView.noFooterView();

                }

            }

        });

        return view;

    }

    @Override

    public void initData() {

        getDataFromServer();//这是一个异步的,

    }

    private void getDataFromServer() {

        HttpUtils utils = new HttpUtils();

        utils.send(HttpRequest.HttpMethod.GET, mUrl, new RequestCallBack<String>() {

            @Override

            public void onSuccess(ResponseInfo<String> responseInfo) {

                String result = (String) responseInfo.result;

//                System.out.println("页签详情页返回结果:+++++++++++++++++++" + result);

                praseData(result, false);

                newsListView.onRefreashComplete();

            }

            @Override

            public void onFailure(HttpException e, String s) {

                Toast.makeText(mActivity, "获取Tabdetaildata失败!", Toast.LENGTH_SHORT).show();

//                error.printStackTrace();

            }

        });

    }

    /**

     * 加载下一页数据

     */

    private void getMoreDataFromServer() {

        HttpUtils utils = new HttpUtils();

        utils.send(HttpRequest.HttpMethod.GET, mMoreUrl, new RequestCallBack<String>() {

            @Override

            public void onSuccess(ResponseInfo<String> responseInfo) {

                String result = (String) responseInfo.result;

//                System.out.println("页签详情页返回结果:+++++++++++++++++++" + result);

                praseData(result, true);

                newsListView.onRefreashComplete();

            }

            @Override

            public void onFailure(HttpException e, String s) {

                Toast.makeText(mActivity, "获取Tabdetaildata失败!", Toast.LENGTH_SHORT).show();

//                error.printStackTrace();

            }

        });

    }

    /**

     * 把json字符串解析成为json对象

     *

     * @param result 要解析的的json字符串

     */

    private void praseData(String result, boolean isLoadMore) {

        Gson gson = new Gson();

        mTabDetailData = gson.fromJson(result, TabData.class);//返回TabData对象

        System.out.println("页签详情页:+++++++++++++++++++++" + mTabdata);

        //处理更多页面的逻辑

        final String more = mTabDetailData.data.more;

        if (!TextUtils.isEmpty(more)) {

            mMoreUrl = GlobeContents.SERVER_URL + more;

        } else {

            mMoreUrl = null;

        }

        if (!isLoadMore) {

            mTopNewsList = mTabDetailData.data.topnews;

            mNewsList = mTabDetailData.data.news;

            if (mTopNewsList != null) {

                mViewPager.setAdapter(new TopNewsAdapter());

                indicator.setOnPageChangeListener(this);

                indicator.setViewPager(mViewPager);//在设置完适配器后,在设置指示器

                indicator.setSnap(true);//设置快照显示

                indicator.onPageSelected(0);//indicator会自作聪明,离开时会记录当前位置

                tvTitle.setText(mTopNewsList.get(0).title);

            }

            mNewsAdapter = new NewsAdapter();

            //填充新闻列表

            if (mNewsList != null) {

                newsListView.setAdapter(mNewsAdapter);

            }

        } else {//如果是加载下一页,需要将数据追加给原来的集合

            ArrayList<TabData.TabNewsData> news = mTabDetailData.data.news;

            mNewsList.addAll(news);

            mNewsAdapter.notifyDataSetChanged();//刷新ListView

        }

    }

    @Override

    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

    }

    @Override

    public void onPageSelected(int position) {//更新头条新闻标题

        TabData.TopNewsData topNewsData = mTopNewsList.get(position);

        tvTitle.setText(topNewsData.title);

    }

    @Override

    public void onPageScrollStateChanged(int state) {

    }

    /**

     * ListView适配器

     */

    class NewsAdapter extends BaseAdapter {

        private final BitmapUtils utils;

        NewsAdapter() {

            utils = new BitmapUtils(mActivity);

            utils.configDefaultLoadingImage(R.drawable.pic_item_list_default);

        }

        @Override

        public int getCount() {

            return mNewsList.size();

        }

        @Override

        public Object getItem(int position) {

            return mNewsList.get(position);

        }

        @Override

        public long getItemId(int position) {

            return position;

        }

        @Override

        public View getView(int position, View convertView, ViewGroup parent) {

            ViewHolder holder;

            if (convertView == null) {

                convertView = View.inflate(mActivity, R.layout.list_news_item, null);

                holder = new ViewHolder();

                holder.ivPic = (ImageView) convertView.findViewById(R.id.iv_pic);

                holder.tvTitle = (TextView) convertView.findViewById(R.id.tv_title);

                holder.tvDate = (TextView) convertView.findViewById(R.id.tv_date);

                convertView.setTag(holder);

            } else {

                holder = (ViewHolder) convertView.getTag();

            }

            TabData.TabNewsData item = (TabData.TabNewsData) getItem(position);

            holder.tvTitle.setText(item.title);

            holder.tvDate.setText(item.pubdate);

            utils.display(holder.ivPic, item.listimage);

            return convertView;

        }

    }

    static class ViewHolder {

        public TextView tvTitle;

        public TextView tvDate;

        public ImageView ivPic;

    }

    /**

     * Viewpager适配器

     */

    class TopNewsAdapter extends PagerAdapter {

        private BitmapUtils bitmapUtils;

        TopNewsAdapter() {

            bitmapUtils = new BitmapUtils(mActivity);

            bitmapUtils.configDefaultLoadingImage(R.drawable.topnews_item_default);//设置默认图片

        }

        @Override

        public int getCount() {

            return mTabDetailData.data.topnews.size();

        }

        @Override

        public boolean isViewFromObject(View view, Object object) {

            return view == object;

        }

        @Override

        public Object instantiateItem(ViewGroup container, int position) {

            ImageView imageView = new ImageView(mActivity);

            imageView.setImageResource(images[position]);

            imageView.setScaleType(ImageView.ScaleType.FIT_XY);//基于控件大小填充图片

//            TabData.TopNewsData topNewsData = mTopNewsList.get(position);

//            bitmapUtils.display(imageView,mTabDetailData.data.topnews.get(position).url);

            container.addView(imageView);

            return imageView;

        }

        @Override

        public void destroyItem(ViewGroup container, int position, Object object) {

            container.removeView((View) object);

        }

    }

}

转载自:http://blog.csdn.net/itguangit/article/details/52021760
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息