博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
让Android Support V4中的SwipeRefreshLayout支持上拉载入很多其它
阅读量:6929 次
发布时间:2019-06-27

本文共 7516 字,大约阅读时间需要 25 分钟。

前言

原来的Android SDK中并没有下拉刷新组件,可是这个组件确实绝大多数APP必备的一个部件。好在google在v4包中出了一个SwipeRefreshLayout。可是这个组件仅仅支持下拉刷新,不支持上拉载入很多其它的操作。

因此,我们就来简单的扩展一下这个组件以实现上拉下载的目的。

基本原理

上拉载入或者说滚动究竟部时自己主动载入,都是通过推断是否滚动到了ListView或者其它View的底部,然后触发对应的操作,这里我们以ListView来说明。因此我们须要在监听ListView的滚动事件,当ListView滚动究竟部时自己主动触发载入操作;可是当用户支持手指滑动屏幕,没有滚动时,我们也须要让它载入,因此这样的情形就是上拉载入很多其它。所以我们须要在触摸事件里面进行推断,假设到了底部,且用户是上拉操作,那么运行载入很多其它。很多其它关于下拉刷新、上拉载入请參考。
时间有限,直接上代码吧。

实现代码

/** * 继承自SwipeRefreshLayout,从而实现滑动究竟部时上拉载入很多其它的功能. *  * @author mrsimple */public class RefreshLayout extends SwipeRefreshLayout implements OnScrollListener {    /**     * 滑动到最以下时的上拉操作     */    private int mTouchSlop;    /**     * listview实例     */    private ListView mListView;    /**     * 上拉监听器, 到了最底部的上拉载入操作     */    private OnLoadListener mOnLoadListener;    /**     * ListView的载入中footer     */    private View mListViewFooter;    /**     * 按下时的y坐标     */    private int mYDown;    /**     * 抬起时的y坐标, 与mYDown一起用于滑动究竟部时推断是上拉还是下拉     */    private int mLastY;    /**     * 是否在载入中 ( 上拉载入很多其它 )     */    private boolean isLoading = false;    /**     * @param context     */    public RefreshLayout(Context context) {        this(context, null);    }    public RefreshLayout(Context context, AttributeSet attrs) {        super(context, attrs);        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();        mListViewFooter = LayoutInflater.from(context).inflate(R.layout.listview_footer, null,                false);    }    @Override    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {        super.onLayout(changed, left, top, right, bottom);        // 初始化ListView对象        if (mListView == null) {            getListView();        }    }    /**     * 获取ListView对象     */    private void getListView() {        int childs = getChildCount();        if (childs > 0) {            View childView = getChildAt(0);            if (childView instanceof ListView) {                mListView = (ListView) childView;                // 设置滚动监听器给ListView, 使得滚动的情况下也能够自己主动载入                mListView.setOnScrollListener(this);                Log.d(VIEW_LOG_TAG, "### 找到listview");            }        }    }    /*     * (non-Javadoc)     * @see android.view.ViewGroup#dispatchTouchEvent(android.view.MotionEvent)     */    @Override    public boolean dispatchTouchEvent(MotionEvent event) {        final int action = event.getAction();        switch (action) {            case MotionEvent.ACTION_DOWN:                // 按下                mYDown = (int) event.getRawY();                break;            case MotionEvent.ACTION_MOVE:                // 移动                mLastY = (int) event.getRawY();                break;            case MotionEvent.ACTION_UP:                // 抬起                if (canLoad()) {                    loadData();                }                break;            default:                break;        }        return super.dispatchTouchEvent(event);    }    /**     * 能否够载入很多其它, 条件是到了最底部, listview不在载入中, 且为上拉操作.     *      * @return     */    private boolean canLoad() {        return isBottom() && !isLoading && isPullUp();    }    /**     * 推断是否到了最底部     */    private boolean isBottom() {        if (mListView != null && mListView.getAdapter() != null) {            return mListView.getLastVisiblePosition() == (mListView.getAdapter().getCount() - 1);        }        return false;    }    /**     * 是否是上拉操作     *      * @return     */    private boolean isPullUp() {        return (mYDown - mLastY) >= mTouchSlop;    }    /**     * 假设到了最底部,并且是上拉操作.那么运行onLoad方法     */    private void loadData() {        if (mOnLoadListener != null) {            // 设置状态            setLoading(true);            //            mOnLoadListener.onLoad();        }    }    /**     * @param loading     */    public void setLoading(boolean loading) {        isLoading = loading;        if (isLoading) {            mListView.addFooterView(mListViewFooter);        } else {            mListView.removeFooterView(mListViewFooter);            mYDown = 0;            mLastY = 0;        }    }    /**     * @param loadListener     */    public void setOnLoadListener(OnLoadListener loadListener) {        mOnLoadListener = loadListener;    }    @Override    public void onScrollStateChanged(AbsListView view, int scrollState) {    }    @Override    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,            int totalItemCount) {        // 滚动时到了最底部也能够载入很多其它        if (canLoad()) {            loadData();        }    }    /**     * 载入很多其它的监听器     *      * @author mrsimple     */    public static interface OnLoadListener {        public void onLoad();    }}
listview_footer.xml:

使用演示样例

refresh.xml布局文件:
activity中的使用 : 
/** * @author mrsimple */public class MainActivity extends Activity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);          setContentView(R.layout.refresh);        // 模拟一些数据        final List
datas = new ArrayList
(); for (int i = 0; i < 20; i++) { datas.add("item - " + i); } // 构造适配器 final BaseAdapter adapter = new ArrayAdapter
(this, android.R.layout.simple_list_item_1, datas); // 获取listview实例 ListView listView = (ListView) findViewById(R.id.listview); listView.setAdapter(adapter); // 获取RefreshLayout实例 final RefreshLayout myRefreshListView = (RefreshLayout) findViewById(R.id.swipe_layout); // 设置下拉刷新时的颜色值,颜色值须要定义在xml中 myRefreshListView .setColorScheme(R.color.umeng_comm_text_topic_light_color, R.color.umeng_comm_yellow, R.color.umeng_comm_green, R.color.umeng_comm_linked_text); // 设置下拉刷新监听器 myRefreshListView.setOnRefreshListener(new OnRefreshListener() { @Override public void onRefresh() { Toast.makeText(MainActivity.this, "refresh", Toast.LENGTH_SHORT).show(); myRefreshListView.postDelayed(new Runnable() { @Override public void run() { // 更新数据 datas.add(new Date().toGMTString()); adapter.notifyDataSetChanged(); // 更新完后调用该方法结束刷新 myRefreshListView.setRefreshing(false); } }, 1000); } }); // 载入监听器 myRefreshListView.setOnLoadListener(new OnLoadListener() { @Override public void onLoad() { Toast.makeText(MainActivity.this, "load", Toast.LENGTH_SHORT).show(); myRefreshListView.postDelayed(new Runnable() { @Override public void run() { datas.add(new Date().toGMTString()); adapter.notifyDataSetChanged(); // 载入完后调用该方法 myRefreshListView.setLoading(false); } }, 1500); } }); } }

效果图

github链接 : 。
演示样例在android_my_pull_demoproject中。进入demo后点击最后一个button查看效果就可以。注意,在刷新和载入时,须要有一定的延时才干看到效果,这里我们用postDelay来模拟网络请求等延时操作,否则将看不到载入效果。这里仅仅提供一个实现思路,代码不太完好,须要用的请自行完好并測试。
注意
假设出现
HeaderViewListAdapter
转换异常,那么请使用
函数为ListView设置Adapter,
这样能够确保在设置Adapter之前已经加入了Footer。

你可能感兴趣的文章
读《计算机网络——潘爱明》后感
查看>>
Java内存分配浅析2
查看>>
bash 特性详解需整理
查看>>
spring中service调用service的事务控制
查看>>
dubbo学习之dubbo管理控制台装配及集成zookeeper集群部署(1)【转】
查看>>
jsp提交登陆信息,servlet返回一个html页面(不做验证,无数据库)
查看>>
CentOS7 使用的定制
查看>>
SSM(九)反射的实际应用-构建日志对象
查看>>
CSS技巧收集
查看>>
装饰模式
查看>>
Redis+Mysql模式和内存+硬盘模式的异同
查看>>
Android第二十七天
查看>>
[转].NET StockTrader 6 Sample Application
查看>>
[Windows Azure] How to Manage Cloud Services?
查看>>
SpringCloud中Feign调Token丢失解决办法
查看>>
centos6 配置vlan trunk口
查看>>
----- java导出xml
查看>>
springboot-项目属性配置
查看>>
<a> href Post提交请求
查看>>
Linux下DHCP服务管理
查看>>