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

来源:互联网 发布:有安卓调音软件吗 编辑:程序博客网 时间:2024/06/02 17:26

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
1 0
原创粉丝点击