Android控件SwipeRefreshLayout实现下拉刷新上拉加载

46 篇文章 0 订阅
13 篇文章 1 订阅

Android控件SwipeRefreshLayout实现上下拉加载

App基本都有下拉刷新的功能,以前基本都使用别人的PullToRefresh’框架或者自己写一个下拉刷新,但是我最近发现,android官方在其实已经有一个能很简单就实现下拉刷新的控件SwipeRefreshLayout,上拉加载也是可以通过自己重写这个类实现。

所有我觉得简单的下拉和上拉效果使用SwipeRefreshLayout控件来实现就可以了,没有必要去加载一大堆pullToRefresh类似的jar包工程!

但是V4的jar包还是需要的,因为这个类就在里面。需要的可以在源码地址在复制。

效果一:

s1

上面是下拉刷新,使用几句代码就可以实现!

效果二:

s2

一.SwipeRefreshLayout的使用介绍

(一)布局文件

  <android.support.v4.widget.SwipeRefreshLayout
            android:id="@+id/swipe_refresh"
            android:layout_width="match_parent"
            android:layout_height="match_parent" >

        <ListView
                android:id="@+id/listview"
                android:layout_width="match_parent"
                android:layout_height="match_parent" >
        </ListView>
    </android.support.v4.widget.SwipeRefreshLayout>

使用V4包下的SwipeRefreshLayout,里面可以放其他放任何控件。

(二)控件对象实例化

 private SwipeRefreshLayout swipeLayout;   //下拉刷新
 swipeLayout = (SwipeRefreshLayout) this.findViewById(R.id.swipe_refresh);

(三)设置下拉监听

   swipeLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                //延迟一秒钟再执行任务
        new Handler().postDelayed(new Runnable() {
            public void run() {
                swipeLayout.setRefreshing(false);     //取消刷新状态
                infoList.add(index + "line");
                index++;
                adapter.notifyDataSetChanged();
            }
        }, 1000);  
            }
        });

设置前面三步,就已经有下拉刷新效果了,是不是很简单。
在实际应用中一般是在onRefreshff里面使用子线程请求数据,然后数据请求完毕后关闭刷新状态。

(四)判断下拉进度条是否是在显示中的方法

Boolean flag= swipeLayout.isRefreshing(); 

(五)取消刷新对话框的方法

  swipeLayout.setRefreshing(false);     //取消刷新状态

(六)设置刷新时的圆形进度条的样式代码

// 顶部刷新的样式,可以设置多个颜色
        swipeLayout.setColorScheme(android.R.color.holo_red_light, 
        android.R.color.holo_green_light, android.R.color.holo_blue_bright, 
        android.R.color.holo_orange_light);

二.下面是第一种效果的设计代码

(一)布局文件,跟上面一样

(二)java代码

package com.example.refreshDemo;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.widget.SwipeRefreshLayout;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;

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

/**
 * 只有下拉刷新功能的Demo
 */
public class MyActivity extends Activity implements SwipeRefreshLayout.OnRefreshListener, AdapterView.OnItemClickListener {

    private SwipeRefreshLayout swipeLayout;   //下拉刷新

    private ListView listView; //ListView

    private ListViewAdapter adapter; // ListView适配器

    private List<String> infoList = new ArrayList<String>();
    ;  //

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

        swipeLayout = (SwipeRefreshLayout) this.findViewById(R.id.swipe_refresh);
        swipeLayout.setOnRefreshListener(this);
        // 顶部刷新的样式
        swipeLayout.setColorScheme(android.R.color.holo_red_light, android.R.color.holo_green_light,
                android.R.color.holo_blue_bright, android.R.color.holo_orange_light);

        listView = (ListView) this.findViewById(R.id.listview);
        adapter = new ListViewAdapter(this, infoList);
        listView.setAdapter(adapter);
        listView.setOnItemClickListener(this);


    }

    int index = 1;

    /**
     * 下拉刷新后回调的方法
     */
    public void onRefresh() {
        //延迟一秒钟再执行任务
        new Handler().postDelayed(new Runnable() {
            public void run() {
                swipeLayout.setRefreshing(false);     //取消刷新状态
                infoList.add(index + "line");
                index++;
                adapter.notifyDataSetChanged();
            }
        }, 1000);
    }

    /**
     * ListView的条目点击事件
     *
     * @param parent
     * @param view
     * @param position
     * @param id
     */
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        if (position % 2 == 0) {
            startActivity(new Intent(this, MyActivity2.class));
        }

    }
}

ListView的适配器的代码,一般人都会,这里就不显示的,需要的可以在源码地址中看。

三.添加了上拉加载的程序设计

需要编写一个自定义RefreshLayout类继承SwipeRefreshLayout并监听上拉事件,来实现上拉加载,并且这个类有SwipeRefreshLayout的所有方法和属性。

(一)布局文件

把布局文件中的SwipeRefreshLayout变成自定义的RefreshLayout类就可以。

(二)自定义的RefreshLayout类的代码设计

package com.example.refreshDemo;

import android.content.Context;
import android.support.v4.widget.SwipeRefreshLayout;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.widget.AbsListView;
import android.widget.ListView;

/**
 * 继承自SwipeRefreshLayout,从而实现滑动到底部时上拉加载更多的功能.
 */
public class RefreshLayout  extends SwipeRefreshLayout implements AbsListView.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();
    }
}

(三)实现下拉和上拉功能的代码

package com.example.refreshDemo;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.widget.SwipeRefreshLayout;
import android.widget.ListView;

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

/**
 * 只有下拉刷新功能的Demo
 */
public class MyActivity2 extends Activity implements SwipeRefreshLayout.OnRefreshListener, RefreshLayout.OnLoadListener {

    private RefreshLayout swipeLayout;   //下拉刷新

    private ListView listView; //ListView

    private ListViewAdapter adapter; // ListView适配器

    private List<String> infoList = new ArrayList<String>();
    ;  //

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

        swipeLayout = (RefreshLayout) this.findViewById(R.id.swipe_refresh);
        swipeLayout.setOnRefreshListener(this); //监听下拉加载
        swipeLayout.setOnLoadListener(this);//监听下拉刷新

        // 顶部刷新的样式
        swipeLayout.setColorScheme(android.R.color.holo_red_light, android.R.color.holo_green_light,
                android.R.color.holo_blue_bright, android.R.color.holo_orange_light);

        listView = (ListView) this.findViewById(R.id.listview);
        adapter = new ListViewAdapter(this, infoList);
        listView.setAdapter(adapter);

    }

    int index = 1;

    /**
     * 下拉刷新后回调的方法
     */
    public void onRefresh() {
        //延迟一秒钟再执行任务
        new Handler().postDelayed(new Runnable() {
            public void run() {
                swipeLayout.setRefreshing(false);     //取消刷新状态
                infoList.add(0, index + "上拉刷新");
                index++;
                adapter.notifyDataSetChanged();
            }
        }, 1000);
    }


    @Override
    public void onLoad() {
        //延迟一秒钟再执行任务
        new Handler().postDelayed(new Runnable() {
            public void run() {
                swipeLayout.setLoading(false);      //取消下拉加载状态
                infoList.add(index + "下拉加载");
                index++;
                adapter.notifyDataSetChanged();
            }
        }, 1000);
    }
}

(四)上拉时的进度条的显示布局listview_footer.xml

这是自己设计的圆形进度条,你也可以设计得很炫酷。。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:paddingBottom="8dip"
                android:paddingTop="5dip" >

    <ProgressBar
            android:id="@+id/pull_to_refresh_load_progress"
            style="@android:style/Widget.ProgressBar.Small.Inverse"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_centerHorizontal="true"
            android:paddingRight="100dp"
            android:indeterminate="true" />

    <TextView
            android:id="@+id/pull_to_refresh_loadmore_text"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:gravity="center"
            android:paddingTop="5dip"
            android:text="加载中"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:textColor="@android:color/darker_gray"
            android:textSize="14sp"
            android:textStyle="bold" />

</RelativeLayout>

到这里使用官方的SwipeRefreshLayout就可以实现上拉加载,下拉刷新功能了,并且是比较方便的,如果需要复杂的效果,也是可以在上面的基础上做修改。

源码地址:http://download.csdn.net/detail/wenzhi20102321/9827825

一般的我们都是使用下拉刷新来重新请求页面的数据,而上拉加载,一般都是如果有更多数据在后面添加数据,比如加载下一页的数据。(简单的说就是:下拉就刷新一下,上拉就加载更多)

共勉:再不年轻,我们就老了!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

峥嵘life

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值