Android开发总结(七)上拉刷新、下拉加载库的使用

文/程序员男神

前言

本周被派遣到上海出差,去医院演示项目,收集收集医院的需求;大早上起得比平时早了那么一会,就感觉一天有点疲乏。晚上到了,突然精神来了,写篇文章压压惊。说实话,上拉刷新、下拉加载功能很常用,也很常见,但是需要自己开发时,却感觉那么多不知道选用哪个了?记录下来,让自己在刷新面前不在迷茫。


Android开发总结(七)上拉刷新、下拉加载库的使用_第1张图片
aj

概述

先上效果图:上拉刷新,下拉加载的功能。

Android开发总结(七)上拉刷新、下拉加载库的使用_第2张图片
效果图

废话不多说,先给出两个项目的地址:
下拉刷新
https://github.com/liaohuqiu/android-Ultra-Pull-To-Refresh
上拉刷新、上拉加载更多
https://github.com/captainbupt/android-Ultra-Pull-To-Refresh-With-Load-More/blob/master/README-cn.md

实现步骤

只讲使用方法,不扯淡,就是那么认真。

1、参数说明

  • 在旧版本中,ptr_duration_to_close是指回到刷新状态的事件。另外ptr_duration_to_close_header代表回到开始状态(不可见)的事件。这两个属性有点类似,因此可能造成误解,特别是在添加了footer之后。所以,在新版本中,ptr_duration_to_close被删除,而使用ptr_duration_to_back_refresh作为替代。同时,也加入了ptr_duration_to_back_header和ptr_duration_to_back_footer来区分头部和脚部。
  • 新版本中,添加ptr_duration_to_close_either代表回到开始状态(不可见)的事件。
  • 针对ptr_resistance,也分别添加ptr_resistance_header和ptr_resistance_footer。

2、添加的方法和类

  • setFooterView:对应于setHeaderView()。在set完footer后,你需要调用 addPtrUIHandler(),这和设置header的机制是一样的。
  • PtrHandler2:原有PtrHandler类的一个补充。当需要使用上拉加载更多的时候,你应该调用setPtrHandler(new PtrHandler2()),而不是setPtrHandler(new PtrHandler())。
  • PtrDefaultHandler2:实现了默认的 checkCanDoLoadMore() 逻辑,可以适用于大部分的View。机制和PtrDefaultHandler一致。
  • PtrClassicDefaultFooter:默认的footer,将默认header反转了过来。
  • setMode(Mode): Mode是本分支的一个新特性。通过调用setMode, 你可以任意的开启/关闭header或者footer。参数类型是一个枚举变量,可以通过以下方式调用:setMode(Mode.BOTH)。

3、使用方法

首先,在gradle中:

compile 'in.srain.cube:ptr-load-more:1.0.6'

下面是布局文件,activity_main.xml:




    

        
    


接下来就是我们的adapter的代码:

package com.winning.health.rims.recoverydemo.adapter;

import android.app.Activity;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.winning.health.rims.recoverydemo.R;
import com.winning.health.rims.recoverydemo.model.Project;
import com.winning.health.rims.recoverydemo.view.SlidingButtonView;

import java.util.List;

/**
 * desc: adapter
 * author:djj on 2017/7/3 12:49
 * :http://www.jianshu.com/u/dfbde65a03fc
 */
public class RecycleAdapter extends RecyclerView.Adapter implements SlidingButtonView.IonSlidingButtonListener {

    private List data;
    private Context mContext;
    private SlidingButtonView mMenu = null;

    public RecycleAdapter(List data, Context mContext) {
        this.data = data;
        this.mContext = mContext;
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_list, parent, false);
        MyViewHolder myViewHolder = new MyViewHolder(view);
        return myViewHolder;
    }

    @Override
    public void onBindViewHolder(final MyViewHolder holder, int position) {

        //将数据填充到具体的view中
        holder.itemTitle.setText(data.get(position).getItemTitle());
        holder.itemDuration.setText(data.get(position).getItemDuration() + "");
        holder.startTask.setText(data.get(position).getStartTask());
        holder.tvDelete.setText(data.get(position).getTvDelete());

        //设置内容布局的宽为屏幕宽度
        DisplayMetrics metrics = new DisplayMetrics();
        ((Activity) mContext).getWindowManager().getDefaultDisplay().getMetrics(metrics);
        int width = metrics.widthPixels;
        holder.layoutContent.getLayoutParams().width = width;

        // 如果设置了回调,则设置点击事件
        if (mIDeleteBtnClickListener != null) {
            holder.startTask.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    int n = holder.getLayoutPosition();
                    mIDeleteBtnClickListener.onStartItemClick(view, holder, n);
                }
            });
            holder.layoutContent.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    //判断侧滑是否打开
                    if (menuIsOpen()) {
                        closeMenu();
                    } else {
                        int n = holder.getLayoutPosition();
                        mIDeleteBtnClickListener.onDeleteBtnClick(view, holder, n);
                    }
                }
            });
            holder.tvDelete.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    int n = holder.getLayoutPosition();
                    mIDeleteBtnClickListener.onDeleteBtnClick(view, holder, n);
                }
            });
        }
    }

    @Override
    public int getItemCount() {
        if (data != null) {
            return data.size();
        }
        return 0;
    }

    /**
     * 删除菜单打开信息接收
     */
    @Override
    public void onMenuIsOpen(View view) {
        mMenu = (SlidingButtonView) view;
    }

    /**
     * 滑动或者点击了Item监听
     *
     * @param slidingButtonView
     */
    @Override
    public void onDownOrMove(SlidingButtonView slidingButtonView) {
        if (menuIsOpen()) {
            if (mMenu != slidingButtonView) {
                closeMenu();
            }
        }
    }

    /**
     * 关闭菜单
     */
    public void closeMenu() {
        mMenu.closeMenu();
        mMenu = null;
    }

    /**
     * 判断是否有菜单打开
     */
    public Boolean menuIsOpen() {
        if (mMenu != null) {
            return true;
        }
        return false;
    }


    /**
     * 定义接口回调
     */
    private IonSlidingViewClickListener mIDeleteBtnClickListener;

    public void setOnSlidingViewClickListener(IonSlidingViewClickListener listener) {
        this.mIDeleteBtnClickListener = listener;
    }

    public interface IonSlidingViewClickListener {
        void onStartItemClick(View view, MyViewHolder holder, int position);

        void onDeleteBtnClick(View view, MyViewHolder holder, int position);
    }

    public class MyViewHolder extends RecyclerView.ViewHolder {

        public TextView itemTitle;
        public TextView itemDuration;
        public TextView startTask;
        public TextView tvDelete;
        public ViewGroup layoutContent;

        public MyViewHolder(View itemView) {
            super(itemView);
            itemTitle = itemView.findViewById(R.id.item_title);
            itemDuration = itemView.findViewById(R.id.item_duration);
            startTask = itemView.findViewById(R.id.start_task);
            tvDelete = itemView.findViewById(R.id.tv_delete);
            layoutContent = itemView.findViewById(R.id.layout_content);
            ((SlidingButtonView) itemView).setSlidingButtonListener(RecycleAdapter.this);

        }
    }
}

接下来贴出item的xml代码item_list.xml:




    

        

            

                

                    

                        

                        
                    

                    

                        


                        

                        

                        
                    

                

                
            
        

        
    


实体类Project的代码,set、get方法自己添加:

package com.winning.health.rims.recoverydemo.model;

/**
 * desc: 治疗项目实体类
 * 

* author:djj *

* date: 2017/7/3 13:12 *

* blog:http://www.jianshu.com/u/dfbde65a03fc */ public class Project { private String itemTitle; private int itemDuration; private String startTask; private String tvDelete; }

由于这是在有滑动删除的Recycleview代码基础上添加的刷新,所以也把滑动的自定义贴出来:

package com.winning.health.rims.recoverydemo.view;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.HorizontalScrollView;
import android.widget.TextView;

import com.winning.health.rims.recoverydemo.R;

/**
 * desc: 侧滑按钮自定义
 * author: dj
 * date: 2017/3/10 10:01
 */

public class SlidingButtonView extends HorizontalScrollView {

    private TextView mTextView_Delete;
    private int mScrollWidth;
    private Boolean isOpen = false;
    private Boolean once = false;

    public SlidingButtonView(Context context) {
        this(context, null);
    }

    public SlidingButtonView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public SlidingButtonView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.setOverScrollMode(OVER_SCROLL_NEVER);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if (!once) {
            mTextView_Delete = (TextView) findViewById(R.id.tv_delete);
            once = true;
        }
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        if (changed) {
            this.scrollTo(0, 0);
            //获取水平滚动条可以滑动的范围,即右侧按钮的宽度
            mScrollWidth = mTextView_Delete.getWidth();
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        int action = ev.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_MOVE:
                mIonSlidingButtonListener.onDownOrMove(this);
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                changeScrollx();
                return true;
            default:
                break;
        }
        return super.onTouchEvent(ev);
    }

    /**
     * 按滚动条被拖动距离判断关闭或打开菜单
     */
    public void changeScrollx() {
        if (getScrollX() >= (mScrollWidth / 2)) {
            this.smoothScrollTo(mScrollWidth, 0);
            isOpen = true;
            mIonSlidingButtonListener.onMenuIsOpen(this);
        } else {
            this.smoothScrollTo(0, 0);
            isOpen = false;
        }
    }

    /**
     * 打开菜单
     */
    public void openMenu() {
        if (isOpen) {
            return;
        }
        this.smoothScrollTo(mScrollWidth, 0);
        isOpen = true;
        mIonSlidingButtonListener.onMenuIsOpen(this);
    }

    /**
     * 关闭菜单
     */
    public void closeMenu() {
        if (!isOpen) {
            return;
        }
        this.smoothScrollTo(0, 0);
        isOpen = false;
    }

    private IonSlidingButtonListener mIonSlidingButtonListener;

    public void setSlidingButtonListener(IonSlidingButtonListener listener) {
        this.mIonSlidingButtonListener = listener;
    }

    public interface IonSlidingButtonListener {
        void onMenuIsOpen(View view);

        void onDownOrMove(SlidingButtonView slidingButtonView);
    }
}

最后就是我们的activity的代码,Mainactivity.java:

package com.winning.health.rims.recoverydemo.activity;

import android.graphics.Color;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.Toast;

import com.winning.health.rims.recoverydemo.R;
import com.winning.health.rims.recoverydemo.adapter.RecycleAdapter;
import com.winning.health.rims.recoverydemo.model.Project;

import java.util.ArrayList;
import java.util.List;

import in.srain.cube.views.ptr.PtrClassicDefaultFooter;
import in.srain.cube.views.ptr.PtrClassicDefaultHeader;
import in.srain.cube.views.ptr.PtrClassicFrameLayout;
import in.srain.cube.views.ptr.PtrDefaultHandler2;
import in.srain.cube.views.ptr.PtrFrameLayout;
import in.srain.cube.views.ptr.PtrHandler2;
import in.srain.cube.views.ptr.util.PtrLocalDisplay;

public class MainActivity extends AppCompatActivity {

    private RecyclerView mRecyclerView;
    private RecycleAdapter mAdapter;
    private RecyclerView.LayoutManager mLayoutManager;
    private List projectList;
    private PtrClassicFrameLayout ptrClassicLayout;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initDate();
        initView();


    }

    //初始化数据
    private void initDate() {
        projectList = new ArrayList();
        for (int i = 0; i < 20; i++) {
            Project project = new Project();
            project.setItemTitle("微波治疗");
            project.setItemDuration(10);
            project.setStartTask("开始");
            project.setTvDelete("取消");
            projectList.add(project);
        }
    }

    //初始化控件
    private void initView() {
        mRecyclerView = (RecyclerView) findViewById(R.id.recycle_view);
        ptrClassicLayout = (PtrClassicFrameLayout) findViewById(R.id.ptr_classic_frame_layout);
        mRecyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
        mLayoutManager = new LinearLayoutManager(this);
        mRecyclerView.setLayoutManager(mLayoutManager);
        mAdapter = new RecycleAdapter(projectList, MainActivity.this);
        mRecyclerView.setAdapter(mAdapter);
        mAdapter.setOnSlidingViewClickListener(new RecycleAdapter.IonSlidingViewClickListener() {
            @Override
            public void onStartItemClick(View view, final RecycleAdapter.MyViewHolder holder, int position) {
                //判断状态调收费接口
                CountDownTimer timer = new CountDownTimer((20 * 1000), 1000) {
                    @Override
                    public void onTick(long l) {
                        holder.itemDuration.setText(l / 1000 + "");
                        holder.startTask.setBackgroundResource(R.drawable.button_load_back);
                        holder.startTask.setTextColor(Color.parseColor("#0BC0BA"));
                        holder.startTask.setText("进行");

                    }

                    @Override
                    public void onFinish() {
                        holder.itemDuration.setText("00:00:00");
                        holder.startTask.setBackgroundResource(R.drawable.button_no_back);
                        holder.startTask.setText("完成");
                    }
                };
                timer.start();
            }

            @Override
            public void onDeleteBtnClick(View view, RecycleAdapter.MyViewHolder holder, int position) {
                Toast.makeText(MainActivity.this, "onDeleteBtnClick", Toast.LENGTH_SHORT).show();

            }
        });
        /**
         * 经典 风格的头部实现
         */
        final PtrClassicDefaultHeader header = new PtrClassicDefaultHeader(this);
        header.setPadding(0, PtrLocalDisplay.dp2px(15), 0, 0);

        PtrClassicDefaultFooter footer = new PtrClassicDefaultFooter(this);
        footer.setPadding(0, 0, 0, PtrLocalDisplay.dp2px(15));

        ptrClassicLayout.setHeaderView(header);
        ptrClassicLayout.addPtrUIHandler(header);

        ptrClassicLayout.setFooterView(footer);
        ptrClassicLayout.addPtrUIHandler(footer);
        //mPtrFrame.setKeepHeaderWhenRefresh(true);//刷新时保持头部的显示,默认为true
        //mPtrFrame.disableWhenHorizontalMove(true);//如果是ViewPager,设置为true,会解决ViewPager滑动冲突问题。
        ptrClassicLayout.setPtrHandler(new PtrHandler2() {
            @Override
            public boolean checkCanDoLoadMore(PtrFrameLayout frame, View content, View footer) {
                // 默认实现,根据实际情况做改动
                return PtrDefaultHandler2.checkContentCanBePulledUp(frame, content, footer);
            }

            /**
             * 加载更多的回调
             * @param frame
             */
            @Override
            public void onLoadMoreBegin(PtrFrameLayout frame) {
                frame.postDelayed(new Runnable() {
                    @Override
                    public void run() {

                        ptrClassicLayout.refreshComplete();
                    }
                }, 2000);
            }

            @Override
            public boolean checkCanDoRefresh(PtrFrameLayout frame, View content, View header) {
                // 默认实现,根据实际情况做改动
                return PtrDefaultHandler2.checkContentCanBePulledDown(frame, content, header);
            }

            /**
             * 下拉刷新的回调
             * @param frame
             */
            @Override
            public void onRefreshBegin(PtrFrameLayout frame) {
                frame.postDelayed(new Runnable() {
                    @Override
                    public void run() {

                        ptrClassicLayout.refreshComplete();
                    }
                }, 1000);
            }
        });

    }
}

这些都是我真实项目的demo,里面不止上拉刷新、下拉加载的功能,在以前功能基础上添加到,把这分享出来和大家交流,希望可以更好的进步。
最后贴上源码地址:https://github.com/hellodonj/PtrClassicDemo.git

总结:
学习需要坚持。不要怂,就是干。

你可能感兴趣的:(Android开发总结(七)上拉刷新、下拉加载库的使用)