自定义SwpieRefreshLayout(进入页面自动刷新,下拉刷新,点击加载更多)

一、自定义SwpieRefreshLayout简介
相信很多人都用过Android官方刷新控件SwipeRefreshLayout,不过如果直接使用可能无法满足日常开发的需求。有很多我们需要的操作,谷歌官方没有提供API给我们,例如进入页面自动刷新,上拉加载数据等操作。
这次我继承SwipeRefreshLayout控件,扩展并封装上拉加载操作和进入页面自动刷新操作。
按照惯例咋们来看看最终效果图



二、自定义SwpieRefreshLayout的使用方法
看完效果图之后就来说一说使用方法,不过在这之前,我还是贴一张此Demo的项目结构图

自定义控件只有一个JAVA文件,没有使用额外的XML布局文件
需要使用的同学,可以直接将CustomSwipeRefreshLayout文件拷贝到自己项目工程中即可。

1、只是用进入页面刷新功能。
(1)先实现CustomSwipeRefreshLayout.CustomOnRefreshListener下拉刷新接口。
(2)设置setCustomOnRefreshListener(this)注册监听器。
(3)调用进入页面刷新方法setAutoRefresh()。
(4)重写onRefresh()方法,在这里面实现业务逻辑操作。

效果图如下具体代码如下:
package sms.edward.per.myapplication;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.widget.ArrayAdapter;
import android.widget.ListView;

/**
 * 自定义SwpieRefreshLayout(进入页面自动刷新,下拉刷新,上拉加载更多)
 * <p/>
 * 此Demo博客地址:
 *
 * @author Edward
 */
public class MainActivity extends Activity implements CustomSwipeRefreshLayout.CustomOnRefreshListener {
    private CustomSwipeRefreshLayout customSwipeRefreshLayout;
    private ListView listView;
    private ArrayAdapter<String> adapter;

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

        listView = (ListView) findViewById(R.id.list_view);

        customSwipeRefreshLayout = (CustomSwipeRefreshLayout) findViewById(R.id.swipe_refresh);
        //实例化监听器,必须
        customSwipeRefreshLayout.setCustomOnRefreshListener(this);
        //设置进入页面刷新,可选
        customSwipeRefreshLayout.setAutoRefresh();
    }


    @Override
    public void onRefresh() {

        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                adapter = new ArrayAdapter<>(MainActivity.this, android.R.layout.simple_list_item_1);

                for (int i = 0; i < 5; i++) {
                    adapter.add(String.valueOf(i));
                }

                customSwipeRefreshLayout.setRefreshing(false);
                listView.setAdapter(adapter);
            }
        }, 1500);

    }
}


效果图如下


2、使用进入页面刷新,点击加载功能。
(1)先实现CustomSwipeRefreshLayout.CustomOnRefreshListener下拉刷新接口和CustomSwipeRefreshLayout.CustomLoadMoreListener加载接口。
(2)设置setCustomOnRefreshListener(this),setCustomLoadMoreListener(this)注册监听器。
(3)调用进入页面刷新方法setAutoRefresh()。
(4)重写onRefresh()方法,在这里面实现业务逻辑操作。
(5)重写loadMore()方法,在这里面实现"加载更多"操作。

具体代码如下:
package sms.edward.per.myapplication;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.widget.ArrayAdapter;
import android.widget.ListView;

/**
 * 自定义SwpieRefreshLayout(进入页面自动刷新,下拉刷新,上拉加载更多)
 * <p/>
 * 此Demo博客地址:
 *
 * @author Edward
 */
public class MainActivity extends Activity implements CustomSwipeRefreshLayout.CustomOnRefreshListener, CustomSwipeRefreshLayout.CustomLoadMoreListener {
    private CustomSwipeRefreshLayout customSwipeRefreshLayout;
    private ListView listView;
    private ArrayAdapter<String> adapter;

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

        listView = (ListView) findViewById(R.id.list_view);

        customSwipeRefreshLayout = (CustomSwipeRefreshLayout) findViewById(R.id.swipe_refresh);
        customSwipeRefreshLayout.setCustomOnRefreshListener(this);
        customSwipeRefreshLayout.setCustomLoadMoreListener(this);
        //设置进入页面刷新,可选        customSwipeRefreshLayout.setAutoRefresh();
    }


    @Override
    public void onRefresh() {

        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                adapter = new ArrayAdapter<>(MainActivity.this, android.R.layout.simple_list_item_1);

                for (int i = 0; i < 5; i++) {
                    adapter.add(String.valueOf(i));
                }

                customSwipeRefreshLayout.setRefreshing(false);
                listView.setAdapter(adapter);
            }
        }, 1500);

    }

    @Override
    public void loadMore() {

        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 2; i++) {
                    adapter.add(String.valueOf(i));
                }
                customSwipeRefreshLayout.setFinishLoadMoreText();
                adapter.notifyDataSetChanged();
            }
        }, 1500);
    }
}


效果图如下


好啦,关于此自定义控件的最简单用法已经介绍完毕。接下来说说样式的使用。

3、自定义SwipeRefreshLayout控件的样式使用
在SwipeRefreshLayout的源代码中,我写了一个SwipeRefreshParamsModel类,这个类用来定义底部"加载更多"的样式。
如果你对这个 原生的样式看起来很不顺眼,你可以new一个SwipeRefreshParamsModel类,使用各种SwipeRefreshParamsModel.setXXX方法,设置属性。将其传入给setSwipeRefreshParamsModel方法即可。

演示代码如下:
package sms.edward.per.myapplication;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.widget.ArrayAdapter;
import android.widget.ListView;

/**
 * 自定义SwpieRefreshLayout(进入页面自动刷新,下拉刷新,上拉加载更多)
 * <p/>
 * 此Demo博客地址:
 *
 * @author Edward
 */
public class MainActivity extends Activity implements CustomSwipeRefreshLayout.CustomOnRefreshListener, CustomSwipeRefreshLayout.CustomLoadMoreListener {
    private CustomSwipeRefreshLayout customSwipeRefreshLayout;
    private ListView listView;
    private ArrayAdapter<String> adapter;

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

        listView = (ListView) findViewById(R.id.list_view);

        customSwipeRefreshLayout = (CustomSwipeRefreshLayout) findViewById(R.id.swipe_refresh);
        customSwipeRefreshLayout.setCustomOnRefreshListener(this);
        customSwipeRefreshLayout.setCustomLoadMoreListener(this);
        //设置自动刷新
        customSwipeRefreshLayout.setAutoRefresh();

        //SwipeRefreshParamsModel的使用方法。
        CustomSwipeRefreshLayout.SwipeRefreshParamsModel swipeRefreshParamsModel = new CustomSwipeRefreshLayout.SwipeRefreshParamsModel();
        //设置字体大小
        swipeRefreshParamsModel.setTextSize(25);
        //设置字体颜色
        swipeRefreshParamsModel.setSetTextColor(Color.parseColor("#ffffff"));
        //设置底部背景
        swipeRefreshParamsModel.setSetContainerBackgroundColor(Color.parseColor("#31b2f7"));
        //设置底部按钮未点击前的提示文本
        swipeRefreshParamsModel.setStartRefreshText("疯狂加载中...");
        //设置底部按钮点击之后的提示文本
        swipeRefreshParamsModel.setFinishRefreshText("点我刷新");
        //设置进度框的宽度和高度
        swipeRefreshParamsModel.setProgressBarWidthSize(30);
        swipeRefreshParamsModel.setProgressBarHeightSize(30);

        //设置所有属性之后,将swipeRefreshParamsModel传去给此方法
        customSwipeRefreshLayout.setSwipeRefreshParamsModel(swipeRefreshParamsModel);

    }


    @Override
    public void onRefresh() {

        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                adapter = new ArrayAdapter<>(MainActivity.this, android.R.layout.simple_list_item_1);

                for (int i = 0; i < 5; i++) {
                    adapter.add(String.valueOf(i));
                }

                customSwipeRefreshLayout.setRefreshing(false);
                listView.setAdapter(adapter);
            }
        }, 1500);

    }

    @Override
    public void loadMore() {

        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 2; i++) {
                    adapter.add(String.valueOf(i));
                }
                customSwipeRefreshLayout.setFinishLoadMoreText();
                adapter.notifyDataSetChanged();
            }
        }, 1500);
    }
}


效果如下图:
最后一个方法我差点忘记说了,CustomSwipeRefreshLayout类提供了一个isOpenToastHint方法,这个方法用来提示用户此时正在执行下拉刷新操作,不能点击加载。或者此时正在执行加载操作,不能执行下拉刷新

也就一行代码的事
//开启提示
customSwipeRefreshLayout.setIsOpenToastHint(true);
效果如图所示

三、自定义SwipeRefreshLayout控件源代码
好了来到源代码这一块,不过本人不打算讲解了,该注意的地方都用注释写了。有兴趣的同学可以看看^_^
package sms.edward.per.myapplication;

import android.content.Context;
import android.graphics.Color;
import android.support.v4.widget.SwipeRefreshLayout;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

/**
 * description:自定义SwipeRefreshLayout(进入页面自动刷新,下拉刷新,点击加载更多)
 * <p/>
 * 在底部加一个Button按钮,来点击“加载更多”
 * <p/>
 * 此demo在Android2.3.7版本运行通过
 * <p/>
 * author:Edward
 * <p/>
 * 2015/10/17
 */
public class CustomSwipeRefreshLayout extends SwipeRefreshLayout implements SwipeRefreshLayout.OnRefreshListener {
    private Context mContext;
    private ListView listView;
    //“加载更多”监听事件
    private CustomLoadMoreListener customLoadMoreListener;
    //下拉刷新监听事件
    private CustomOnRefreshListener customOnRefreshListener;
    //标记当前正在执行“加载更多”操作,(false表示没有正在加载,true表示正在加载)
    private boolean isLoadMore = false;
    //底部“加载更多”容器
    private RelativeLayout container;
    //“加载更多”按钮TextView
    private TextView loadMoreTextView;
    //“加载更多”进度框
    private ProgressBar progressBar;
    //此Model用来设置整个CustomSwipeRefreshLayout自定义控件的参数
    private SwipeRefreshParamsModel swipeRefreshParamsModel;
    //是否开启Toast提示,默认为不开启
    private boolean isOpenToastHint = false;
    //
    private RelativeLayout.LayoutParams lp, lp1;

    //设置开启Toast
    public void setIsOpenToastHint(boolean isOpenToastHint) {
        this.isOpenToastHint = isOpenToastHint;
    }

    /**
     * 设置底部容器的参数
     *
     * @param swipeRefreshParamsModel
     */
    public void setSwipeRefreshParamsModel(SwipeRefreshParamsModel swipeRefreshParamsModel) {
        this.swipeRefreshParamsModel = swipeRefreshParamsModel;
    }

    /**
     * 设置刷新回调监听器
     *
     * @param customOnRefreshListener
     */
    public void setCustomOnRefreshListener(CustomOnRefreshListener customOnRefreshListener) {
        this.customOnRefreshListener = customOnRefreshListener;
    }

    /**
     * 设置加载更多回调监听器
     *
     * @param customLoadMoreListener
     */
    public void setCustomLoadMoreListener(CustomLoadMoreListener customLoadMoreListener) {
        this.customLoadMoreListener = customLoadMoreListener;
    }


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

    public CustomSwipeRefreshLayout(Context context, AttributeSet attrs) {
        super(context, attrs);

        mContext = context;
        setOnRefreshListener(this);

        //如果没有设置SwipeRefreshParamsModel,则实例化初始值
        if (this.swipeRefreshParamsModel == null) {
            this.swipeRefreshParamsModel = new SwipeRefreshParamsModel();
        }
    }


    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        //了解一下控件绘制流程
        if (listView == null) {
            //获取当前布局孩子的总数
            int count = getChildCount();

            //获取子类布局控件
            if (count > 0) {
                View view = getChildAt(0);
                if (view instanceof ListView) {
                    listView = (ListView) view;

                    //判断用户是否设置过“加载更多”监听事件
                    if (this.customLoadMoreListener != null) {
                        setClickLoadMore();
                    }
                }
            }
        }
    }


    /**
     * 设置加载更多按钮
     */
    public void setClickLoadMore() {
        //创建一个container容器
        container = new RelativeLayout(mContext);
        container.setOnClickListener(new loadMoreClickListener());
        //设置间距
        container.setPadding(swipeRefreshParamsModel.getLeftPadding(), swipeRefreshParamsModel.getTopPadding(), swipeRefreshParamsModel.getRightPadding(), swipeRefreshParamsModel.getBottomPadding());
        container.setBackgroundColor(swipeRefreshParamsModel.getSetContainerBackgroundColor());

        loadMoreTextView = new TextView(mContext);
        loadMoreTextView.setTextColor(swipeRefreshParamsModel.getSetTextColor());
        loadMoreTextView.setTextSize(swipeRefreshParamsModel.getTextSize());
        loadMoreTextView.setText(swipeRefreshParamsModel.getFinishRefreshText());
        lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
        lp.addRule(RelativeLayout.CENTER_IN_PARENT);
        loadMoreTextView.setId(Integer.valueOf(1));
        loadMoreTextView.setLayoutParams(lp);
        container.addView(loadMoreTextView);

        //默认为隐藏状态
        progressBar = new ProgressBar(mContext);
        //设置进度框的大小
        lp1 = new RelativeLayout.LayoutParams(swipeRefreshParamsModel.getProgressBarWidthSize(), swipeRefreshParamsModel.getProgressBarHeightSize());
        lp1.addRule(RelativeLayout.LEFT_OF, 1);
        lp1.addRule(RelativeLayout.CENTER_VERTICAL);
        progressBar.setLayoutParams(lp1);
        container.addView(progressBar);
        progressBar.setVisibility(View.GONE);

        if (listView != null) {
            //将整个container容器添加到ListView的底部
            listView.addFooterView(container);
        }
    }

    /**
     * 设置结束加载文本
     */
    public void setFinishLoadMoreText() {
        loadMoreTextView.setText(swipeRefreshParamsModel.getFinishRefreshText());
        //重新隐藏进度框
        progressBar.setVisibility(View.GONE);
        //将加载更多的标记设为false(加载完毕)
        isLoadMore = false;
    }


    /**
     * 加载按钮点击事件
     */
    public class loadMoreClickListener implements OnClickListener {

        @Override
        public void onClick(View view) {
            //没有执行下拉刷新,加载更多的监听事件不为空。
            if (!isRefreshing() && customLoadMoreListener != null) {
                isLoadMore = true;
                loadMoreTextView.setText(swipeRefreshParamsModel.getStartRefreshText());
                //将隐藏的ProGressBar显示出来
                progressBar.setVisibility(View.VISIBLE);
                customLoadMoreListener.loadMore();
            } else {
                if (isOpenToastHint)
                    Toast.makeText(mContext, swipeRefreshParamsModel.getPullUpText(), Toast.LENGTH_SHORT).show();
            }
        }
    }


    /**
     * 设置进入页面自动刷新
     */
    public void setAutoRefresh() {
        //判断是否已经设置了setRefreshing(true)
        if (isRefreshing()) {
            //如果已经设置将其改变为false
            setRefreshing(false);
        }
        post(new Thread(new Runnable() {
            @Override
            public void run() {
                setRefreshing(true);
            }
        }));
        onRefresh();
    }

    @Override
    public void onRefresh() {
        //回调刷新控件,如果监听器为空并且正在处于加载更多的过程中,则不刷新
        if (customOnRefreshListener != null && !isLoadMore) {
            customOnRefreshListener.onRefresh();
        } else {
            if (isOpenToastHint) {
                Toast.makeText(mContext, swipeRefreshParamsModel.getPullDownText(), Toast.LENGTH_SHORT).show();
            }
            setRefreshing(false);
        }
    }

    /**
     * 下拉刷新回调监听事件
     */
    public interface CustomOnRefreshListener {
        void onRefresh();
    }

    /**
     * 加载更多回调监听事件
     */
    public interface CustomLoadMoreListener {
        void loadMore();
    }


    /**
     * 用来设置整个SwipeRefreshLayout控件参数的Model,可提供给用户直接修改。
     */
    public static class SwipeRefreshParamsModel {
        private float textSize = 14;
        private String finishRefreshText = "加载更多";
        private String startRefreshText = "正在加载...";
        //设置进度框的大小
        private int progressBarWidthSize = 50, progressBarHeightSize = 50;
        private int setContainerBackgroundColor = Color.parseColor("#e8ebee");
        private int setTextColor = Color.GRAY;
        private int leftPadding = 20, topPadding = 20, rightPadding = 0, bottomPadding = 20;
        private String pullDownText = "正在加载中,请稍后再试...";
        private String pullUpText = "正在刷新中,请稍后再试...";


        public float getTextSize() {
            return textSize;
        }

        public void setTextSize(float textSize) {
            this.textSize = textSize;
        }

        public String getFinishRefreshText() {
            return finishRefreshText;
        }

        public void setFinishRefreshText(String finishRefreshText) {
            this.finishRefreshText = finishRefreshText;
        }

        public String getStartRefreshText() {
            return startRefreshText;
        }

        public void setStartRefreshText(String startRefreshText) {
            this.startRefreshText = startRefreshText;
        }

        public int getProgressBarWidthSize() {
            return progressBarWidthSize;
        }

        public void setProgressBarWidthSize(int progressBarWidthSize) {
            this.progressBarWidthSize = progressBarWidthSize;
        }

        public int getProgressBarHeightSize() {
            return progressBarHeightSize;
        }

        public void setProgressBarHeightSize(int progressBarHeightSize) {
            this.progressBarHeightSize = progressBarHeightSize;
        }

        public int getSetContainerBackgroundColor() {
            return setContainerBackgroundColor;
        }

        public void setSetContainerBackgroundColor(int setContainerBackgroundColor) {
            this.setContainerBackgroundColor = setContainerBackgroundColor;
        }

        public int getSetTextColor() {
            return setTextColor;
        }

        public void setSetTextColor(int setTextColor) {
            this.setTextColor = setTextColor;
        }

        public void setLeftPadding(int leftPadding, int topPadding, int rightPadding, int bottomPadding) {
            this.leftPadding = leftPadding;
            this.topPadding = topPadding;
            this.rightPadding = rightPadding;
            this.bottomPadding = bottomPadding;
        }

        public int getLeftPadding() {
            return leftPadding;
        }

        public int getTopPadding() {
            return topPadding;
        }

        public int getRightPadding() {
            return rightPadding;
        }

        public int getBottomPadding() {
            return bottomPadding;
        }

        public String getPullDownText() {
            return pullDownText;
        }

        public void setPullDownText(String pullDownText) {
            this.pullDownText = pullDownText;
        }

        public String getPullUpText() {
            return pullUpText;
        }

        public void setPullUpText(String pullUpText) {
            this.pullUpText = pullUpText;
        }
    }
}


四、结束
结束了,谢谢各位捧场^_^。




  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值