自定义RefreshListView

最近在做一个新闻类的项目,把自己写的一点东西记录下来,希望自己能够慢慢的成长,也希望自己帮到他人,哈哈哈···
自定义下拉刷新和加载更多,首先要初始化一个头和一个尾,加到(ListView)中

//尾,简称上拉刷新的布局吧

private void initFooterView(Context context) {

    footView=View.inflate(context,R.layout.refresh_foot_view,null);
    pb_status_bottom= (ProgressBar) footView.findViewById(R.id.pb_status_bottom);
    tv_status_bottom= (TextView) footView.findViewById(R.id.tv_status_bottom);
    footView.measure(0,0);
    footViewHeight=footView.getMeasuredHeight();
    footView.setPadding(0,-footViewHeight,0,0);
    //ListView自带的方法
    addFooterView(footView);
    setOnScrollListener(new MyOnScrollListener());
}

//头,就是下拉刷新的一个布局

private void initHeaderView(Context context) {

    headerView = (LinearLayout) View.inflate(context, R.layout.refresh_header, null);
    ll_pull_down_refresh = headerView.findViewById(R.id.ll_pull_down_refresh);
    iv_refresh_image = (ImageView) headerView.findViewById(R.id.iv_refresh_image);
    tv_status = (TextView) headerView.findViewById(R.id.tv_status);
    tv_time = (TextView) headerView.findViewById(R.id.tv_time);
    pb_status = (ProgressBar) headerView.findViewById(R.id.pb_status);
    //测量
    ll_pull_down_refresh.measure(0, 0);
    //控件的高
    viewHeight = ll_pull_down_refresh.getMeasuredHeight();
    /**
     * 默认隐藏下拉刷新控件
     */
    ll_pull_down_refresh.setPadding(0, -viewHeight, 0, 0);

}

//重写一个接口,在需要调用的时候,在实例化的时候通过自定义的控件调用
//一个是下拉刷新对应头,一个是加载更多对应尾

/**
 * 监听事件的刷新
 */
public interface OnRefreshListener{
    /**
     当下拉刷新的时候回调这个方法
     */
    void onPullDownRefresh();
    /**
     当加载更多的时候回调这个方法
     */
     void onLoadMore(); 

}

//如果顶部有轮播图加上,把这个布局加入到headerView中,没有的话,就不要加入了

/**
 * 添加顶部轮播图
 * @param topNewsView
 */

public void addTopNewsView(View topNewsView) {
    if (topNewsView!=null) {
        this.topNewsView = topNewsView;
        headerView.addView(topNewsView);
    }
}


/**
 * 得到当前Android系统的时间
 *
 * @return
 */

private String getSystemTime() {
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    return format.format(new Date());
}

//通过触摸事件来判断

/**
 * 判断是否完全显示顶部轮播图
 * @return
 */
private boolean isDisplayTopNews() {
    if (topNewsView!=null) {
        //1.得到listview在屏幕上的坐标
        int[] location = new int[2];

        if (listviewScreenY == -1) {
            getLocationOnScreen(location);
            listviewScreenY = location[1];
        }
        //2.得到顶部轮播图在屏幕上的坐标
        topNewsView.getLocationOnScreen(location);
        int topNewsViewOnScreenY = location[1];
        if (listviewScreenY <= topNewsViewOnScreenY) {
            return true;
        } else {
            return false;
        }
    }else {
        return true;
    }
}

@Override
public boolean onTouchEvent(MotionEvent ev) {
    switch (ev.getAction()){
        case MotionEvent.ACTION_DOWN:
            //记录起始坐标
            startY=ev.getY();
            break;
        case MotionEvent.ACTION_MOVE:
            if (startY==-1){
                startY=ev.getY();
            }
            //判断头部轮播图是否完全显示,只有完全显示才会下拉刷新
            boolean isDisplayTopNews=isDisplayTopNews();
            if (!isDisplayTopNews){
                //加载更多
                break;
            }else {

            }
            if (currentStatus==REFRESHING){
                break;
            }
            //2.来到新的坐标
            float endY=ev.getY();
            //记录滑动的坐标
            float deltaY=endY-startY;
            if (deltaY>0){
                int paddingTop= (int) (-viewHeight+deltaY);
                if (paddingTop < 0 && currentStatus != PULL_DOWN_REFRESH) {
                    //下拉刷新状态
                    currentStatus = PULL_DOWN_REFRESH;
                    //更新状态
                    refreshViewState();
                } else if (paddingTop > 0 && currentStatus != RELEASE_REFRESH) {
                    //手松刷新状态
                    currentStatus = RELEASE_REFRESH;
                    //更新状态
                    refreshViewState();
                }
                ll_pull_down_refresh.setPadding(0, paddingTop, 0, 0);
            }
            break;
        case MotionEvent.ACTION_UP:
            startY=-1;
            if (currentStatus == PULL_DOWN_REFRESH) {//下拉刷新

//             View.setPadding(0,-控件高,0,0);
            //完全隐藏
               ll_pull_down_refresh.setPadding(0, -viewHeight, 0, 0);
            } else if (currentStatus == RELEASE_REFRESH) {
                //设置状态为正在刷新
                currentStatus = REFRESHING;
                refreshViewState();
                ll_pull_down_refresh.setPadding(0, 0, 0, 0);
                //回调接口
                if (mOnRefreshListener != null) {
                    mOnRefreshListener.onPullDownRefresh();
                }
            }
            break;
    }
    return super.onTouchEvent(ev);
}

  private void refreshViewState() {
    switch (currentStatus){
        case PULL_DOWN_REFRESH://下拉刷新状态
            iv_refresh_image.startAnimation(downAnimation);
            tv_status.setText("下拉刷新....");
            break;
        case RELEASE_REFRESH://手松刷新状态
            iv_refresh_image.startAnimation(upAnimation);
            tv_status.setText("手松刷新....");
            break;
        case REFRESHING://正在刷新状态
            tv_status.setText("正在刷新....");
            pb_status.setVisibility(VISIBLE);
            iv_refresh_image.clearAnimation();
            iv_refresh_image.setVisibility(GONE);
            break;
    }
}

/**
 * 当联网成功和失败的时候回调该方法
 * 用户刷新状态的还原
 * 控件进行调用这个方法
 * @param sucess
 */

public void onRefreshFinish(boolean sucess) {
    if (!isLoadMore) {//不加载更多
        tv_status.setText("下拉刷新...");
        currentStatus = PULL_DOWN_REFRESH;
        pb_status.setVisibility(GONE);
        iv_refresh_image.setVisibility(VISIBLE);
        //隐藏下拉刷新控件
        ll_pull_down_refresh.setPadding(0, -viewHeight, 0, 0);
        if (sucess) {
            //设置最新更新时间
            tv_time.setText("上次更新时间:" + getSystemTime());
        }
    }else {
        isLoadMore=false;
        //隐藏加载更多布局
        footView.setPadding(0,-footViewHeight,0,0);
    }
}


<?xml version="1.0" encoding="utf-8"?>
<!--尾部刷新布局-->
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:padding="8dp"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ProgressBar
    android:id="@+id/pb_status_bottom"
    android:layout_gravity="center"                    android:indeterminateDrawable="@drawable/progress_bar_selector"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
<TextView
    android:layout_marginLeft="10dp"
    android:text="加载更多"
    android:textColor="#ff0000"
    android:textSize="18sp"
    android:id="@+id/tv_status_bottom"
    android:gravity="center_horizontal"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
</LinearLayout>

<?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">
<!--头部刷新-->
<!--下拉刷新控件-->
<LinearLayout
    android:id="@+id/ll_pull_down_refresh"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
    <FrameLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center">
        <ProgressBar
            android:id="@+id/pb_status"
            android:layout_gravity="center"
            android:indeterminateDrawable="@drawable/progress_bar_selector"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </FrameLayout>
    <LinearLayout
        android:layout_gravity="center_vertical"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:text="下拉刷新"
            android:textColor="#ff0000"
            android:textSize="18sp"
            android:id="@+id/tv_status"
            android:gravity="center_horizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
        <TextView
            android:text="上次更新时间:2017-8-4"
            android:textColor="#55000000"
            android:textSize="18sp"
            android:id="@+id/tv_time"
            android:gravity="center_horizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
        </LinearLayout>
    </LinearLayout>
</LinearLayout>

布局如上

具体怎么用

private RefreshListView lv_news_content;
private boolean isLoadMore=false;
@Override
public View initView() {
    View view = View.inflate(context, R.layout.tab_detail_pager, null);
    lv_news_content = (RefreshListView) view.findViewById(R.id.lv_news_content);
    View topNewsView = View.inflate(context, R.layout.topnews, null);
    view_pager = (HorizontalScrollViewPager) topNewsView.findViewById(R.id.view_pager);
    tv_tab_detile_title = (TextView) topNewsView.findViewById(R.id.tv_tab_detile_title);
    ll_point_group = (LinearLayout) topNewsView.findViewById(R.id.ll_point_group);
    //而且要把顶部轮播图部分,以子布局的形式加入到listview中
//        lv_news_content.addHeaderView(topNewsView);
    lv_news_content.addTopNewsView(topNewsView);
    //设置listview的下拉刷新监听事件
    lv_news_content.setOnRefreshListenenr(new MyOnRefreshListener());
    //设置listview的点击监听
    lv_news_content.setOnItemClickListener(new MyItemClickListener());
    return view;
}

class MyOnRefreshListener implements RefreshListView.OnRefreshListener {
    @Override
    public void onPullDownRefresh() {
        Toast.makeText(context, "你在下拉刷新", Toast.LENGTH_SHORT).show();
        getDataFromNet();
    }

    @Override
    public void onLoadMore() {
        if (TextUtils.isEmpty(moreUrl)){
            Toast.makeText(context, "没有更多数据", Toast.LENGTH_SHORT).show();
            lv_news_content.onRefreshFinish(false);
        }else {
            getMoreDataFromNet();
        }
    }
}

到此就完了,可能说的不是很清楚

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值