本篇文章翻译自Ravi Tamada的Android Swipe Down to Refresh ListView Tutorial

首先来看一下效果图

你应该发现很多的android app比如Twitter,Google+都提供了一个下拉刷新数据的功能。仅仅要用户从上往下滑动,新的内容就会载入出来,这篇文章我们将学习怎样开发出相同的功能。

1.Android SwipeRefreshLayout

实现SwipeRefreshLayout很easy。我们将SwipeRefreshLayout作为根布局,将一个子布局包裹在内。本例中我们使用ListView,而且在Activity中中实现SwipeRefreshLayout.OnRefreshListener接口,当用户下拉时,会触发onRefresh()方法。在onRefresh()中我们发起网络请求而且获取最新的数据。

<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"> <!-- place your view here --> </android.support.v4.widget.SwipeRefreshLayout>

2.JSON URL

URL:http://api.androidhive.info/json/imdb_top_250.php?

offset=0

3.新建一个project

1.打开Android Studio,选择File->New Project project起名为MySwipeRefreshLayout

2.右键MySwipeRefreshLayout,选择New->Module 加入我们的Volley库,起名为Volley



将Volley.jar拷贝到Volley的libs目录下

打开Volley下的build.gradle。加入例如以下代码

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.2.0'
compile files('libs/volley.jar')
}

3.打开src/res/values/colors.xml。加入例如以下代码

<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="movie_serial_bg">
<item>#24c6d5</item>
<item>#57dd86</item>
<item>#ad7dcf</item>
<item>#ff484d</item>
<item>#fcba59</item>
<item>#24c6d5</item>
</string-array>
</resources>

4.新建一个Application来初始化我们的Volley

public class MyApplication extends Application {

    public static final String TAG = MyApplication.class
.getSimpleName(); private RequestQueue mRequestQueue; private static MyApplication mInstance; @Override
public void onCreate() {
super.onCreate();
mInstance = this;
} public static synchronized MyApplication getInstance() {
return mInstance;
} public RequestQueue getRequestQueue() {
if (mRequestQueue == null) {
mRequestQueue = Volley.newRequestQueue(getApplicationContext());
} return mRequestQueue;
} public <T> void addToRequestQueue(Request<T> req, String tag) {
req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
getRequestQueue().add(req);
} public <T> void addToRequestQueue(Request<T> req) {
req.setTag(TAG);
getRequestQueue().add(req);
} public void cancelPendingRequests(Object tag) {
if (mRequestQueue != null) {
mRequestQueue.cancelAll(tag);
}
}
}

5.打开AndroidManifest.xml加入网络权限

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="info.androidhive.swiperefresh"> <uses-permission android:name="android.permission.INTERNET"/> <application
android:name="com.example.zhangqi.myswiperefreshlayout.MyApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<activity
android:name="com.example.zhangqi.myswiperefreshlayout.MainActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application> </manifest>

6.创建list_row.xml 作为ListView每一个item的布局

<?

xml version="1.0" encoding="utf-8"?

>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"> <TextView
android:id="@+id/serial"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="25dp"
android:layout_margin="5dp"
android:layout_alignParentLeft="true"
android:textSize="20dp"
android:textStyle="bold" /> <TextView
android:id="@+id/title"
android:layout_toRightOf="@id/serial"
android:layout_centerVertical="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold"
android:paddingLeft="20dp"
android:textSize="18dp" /> </RelativeLayout>

7.创建实体类Movie.java

public class Movie {
public int id;
public String title; public Movie() {
} public Movie(int id, String title) {
this.title = title;
this.id = id;
}
}

8.创建Adapter

public class SwipeListAdapter extends BaseAdapter {
private Activity activity;
private LayoutInflater inflater;
private List<Movie> movieList;
private String[] bgColors; public SwipeListAdapter(Activity activity, List<Movie> movieList) {
this.activity = activity;
this.movieList = movieList;
bgColors = activity.getApplicationContext().getResources().getStringArray(R.array.movie_serial_bg);
} @Override
public int getCount() {
return movieList.size();
} @Override
public Object getItem(int location) {
return movieList.get(location);
} @Override
public long getItemId(int position) {
return position;
} @Override
public View getView(int position, View convertView, ViewGroup parent) { if (inflater == null)
inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null)
convertView = inflater.inflate(R.layout.list_row, null); TextView serial = (TextView) convertView.findViewById(R.id.serial);
TextView title = (TextView) convertView.findViewById(R.id.title); serial.setText(String.valueOf(movieList.get(position).id));
title.setText(movieList.get(position).title); String color = bgColors[position % bgColors.length];
serial.setBackgroundColor(Color.parseColor(color)); return convertView;
} }

9.如今我们在activity_main.xml的SwipeRefreshLayout下加入一个ListView

<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"> <ListView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/listView"> </ListView> </android.support.v4.widget.SwipeRefreshLayout>

10.最后。打开MainActivity.java来完毕最后工作

实现SwipeRefreshLayout.OnRefreshListener而且重写OnRefresh()方法

使用Volley的JsonArrayRequest来获取最新的数据而且更新listview,抽取为一个方法fetchMovies()

当用户下拉刷新时触发OnRefresh(),在这里调用fetchMovies()

public class MainActivity extends ActionBarActivity implements SwipeRefreshLayout.OnRefreshListener {

    private String TAG = MainActivity.class.getSimpleName();

    private String URL_TOP_250 = "http://api.androidhive.info/json/imdb_top_250.php?

offset=";

    private SwipeRefreshLayout swipeRefreshLayout;
private ListView listView;
private SwipeListAdapter adapter;
private List<Movie> movieList; // initially offset will be 0, later will be updated while parsing the json
private int offSet = 0; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); listView = (ListView) findViewById(R.id.listView);
swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh_layout); movieList = new ArrayList<>();
adapter = new SwipeListAdapter(this, movieList);
listView.setAdapter(adapter); swipeRefreshLayout.setOnRefreshListener(this); /**
* Showing Swipe Refresh animation on activity create
* As animation won't start on onCreate, post runnable is used
*/
swipeRefreshLayout.post(new Runnable() {
@Override
public void run() {
swipeRefreshLayout.setRefreshing(true); fetchMovies();
}
}
); } /**
* This method is called when swipe refresh is pulled down
*/
@Override
public void onRefresh() {
fetchMovies();
} /**
* Fetching movies json by making http call
*/
private void fetchMovies() { // showing refresh animation before making http call
swipeRefreshLayout.setRefreshing(true); // appending offset to url
String url = URL_TOP_250 + offSet; // Volley's json array request object
JsonArrayRequest req = new JsonArrayRequest(url,
new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString()); if (response.length() > 0) { // looping through json and adding to movies list
for (int i = 0; i < response.length(); i++) {
try {
JSONObject movieObj = response.getJSONObject(i); int rank = movieObj.getInt("rank");
String title = movieObj.getString("title"); Movie m = new Movie(rank, title); movieList.add(0, m); // updating offset value to highest value
if (rank >= offSet)
offSet = rank; } catch (JSONException e) {
Log.e(TAG, "JSON Parsing error: " + e.getMessage());
}
} adapter.notifyDataSetChanged();
} // stopping swipe refresh
swipeRefreshLayout.setRefreshing(false); }
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, "Server Error: " + error.getMessage()); Toast.makeText(getApplicationContext(), error.getMessage(), Toast.LENGTH_LONG).show(); // stopping swipe refresh
swipeRefreshLayout.setRefreshing(false);
}
}); // Adding request to request queue
MyApplication.getInstance().addToRequestQueue(req);
} }

大功告成。

Android原生下拉刷新SwipeRefreshLayout实践的更多相关文章

  1. Android listview下拉刷新 SwipeRefreshLayout

    今天在Google+上看到了SwipeRefreshLayout这个名词,遂搜索了下,发现竟然是刚刚google更新sdk新增加的一个widget,于是赶紧抢先体验学习下. SwipeRefreshL ...

  2. Android 官方下拉刷新 SwipeRefreshLayout

    0.build.gradle compile 'com.android.support:support-v4:23+' 1.布局文件 <android.support.v4.widget.Swi ...

  3. Android -- 官方下拉刷新SwipeRefreshLayout

    V4的兼容包 API 大概就这4个常用的方法. code 布局 <RelativeLayout xmlns:android="http://schemas.android.com/ap ...

  4. Android Material Design控件使用(四)——下拉刷新 SwipeRefreshLayout

    使用下拉刷新SwipeRefreshLayout 说明 SwipeRefreshLayout是Android官方的一个下拉刷新控件,一般我们使用此布局和一个RecyclerView嵌套使用 使用 xm ...

  5. Android智能下拉刷新加载框架—看这些就够了

    一些值得学习的几个下拉刷新上拉加载开源库 Android智能下拉刷新框架-SmartRefreshLayout 支持所有的 View(AbsListView.RecyclerView.WebView. ...

  6. Xamarin. Android实现下拉刷新功能

    PS:发现文章被其他网站或者博客抓取后发表为原创了,给图片加了个水印 下拉刷新功能在安卓和iOS中非常常见,一般实现这样的功能都是直接使用第三方的库,网上能找到很多这样的开源库.然而在Xamarin. ...

  7. android官方下拉刷新控件SwipeRefreshLayout的使用

    可能开发安卓的人大多数都用过很多下拉刷新的开源组件,但是今天用了官方v4支持包的SwipeRefreshLayout觉得效果也蛮不错的,特拿出来分享. 简介:SwipeRefreshLayout组件只 ...

  8. Android下拉刷新-SwipeRefreshLayout,RecyclerView完全解析之下拉刷新与上拉加载SwipeRefreshLayout)

    SwipeRefrshLayout是Google官方更新的一个Widget,可以实现下拉刷新的效果.该控件集成自ViewGroup在support-v4兼容包下,不过我们需要升级supportlibr ...

  9. 【转】Android官方下拉刷新控件 SwipeRefreshLayout

    今天在Google+上看到了SwipeRefreshLayout这个名词,遂搜索了下,发现竟然是刚刚google更新sdk新增加的一个widget,于是赶紧抢先体验学习下. SwipeRefreshL ...

随机推荐

  1. 网关协议:CGI、FastCGI、WSGI

    CGI就像是一座桥,把网页和WEB服务器中的执行程序连接起来,它把HTML接收的指令传递给服务器的执行程序,再把服务器执行程序的结果返还给HTML页. CGI CGI即通用网关接口(Common Ga ...

  2. 使用Rancher管理Docker

    使用命令: sudo docker run -it -d --restart=always -p : --name docker-rancher rancher/server 为了更快速的下载应用,推 ...

  3. Codeforces Round #424 A(模拟)

    #include<cstdio> ]; int main(){ scanf("%d",&n); ;i<=n;++i)scanf("%d" ...

  4. Java中byte与(16进制)字符串的互相转换

    java中byte用二进制表示占用8位,而我们知道16进制的每个字符需要用4位二进制位来表示,所以我们就可以把每个byte转换成两个相应的16进制字符,即把byte的高4位和低4位分别转换成相应的16 ...

  5. 优先队列priority_queue

    优先队列容器与队列一样,只能从队尾插入元素,从队首删除元素.但是它有一个特性,就是队列中最大的元素总是位于队首,所以出队时,并非按照先进先出的原则进行,而是将当前队列中最大的元素出队.这点类似于给队列 ...

  6. 【树链剖分】【线段树】bzoj3626 [LNOI2014]LCA

    引用题解: http://blog.csdn.net/popoqqq/article/details/38823457 题目大意: 给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深 ...

  7. 【树链剖分】【dfs序】【线段树】bzoj2836 魔法树

    这道题告诉我们:树链剖分的重标号就是dfs序. #include<cstdio> #include<algorithm> using namespace std; #defin ...

  8. [CSAcademy]Connected Tree Subgraphs

    题目大意: 给你一棵n个结点的树,求有多少种染色方案,使得染色过程中染过色的结点始终连成一块. 思路: 树形DP. 设f[x]表示先放x时,x的子树中的染色方案数,y为x的子结点. 则f[x]=pro ...

  9. 109.关路灯(区间dp)

    1258 关路灯  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 大师 Master 题解 查看运行结果 题目描述 Description 多瑞卡得到了一份有趣而高薪的工作.每 ...

  10. iOS开发-设置在使用NavigateController时View的顶部位置

      最近我在开发中遇到了一个问题,在使用NavigationController时内部的ViewController的View总是与屏幕顶部对齐,而我们有时候不需要这种效果: 在开发过程中,我们可能会 ...