本篇文章翻译自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. Django组件之contenttype的应用

    contenttypes 是Django内置的一个应用,可以追踪项目中所有app和model的对应关系,并记录在ContentType表中. 每当我们创建了新的model并执行数据库迁移后,Conte ...

  2. 求第N个回文数 模板

    备忘. /*看到n可以取到2*10^9.说明普通方法一个个暴力计算肯定会超时的,那打表呢?打表我们要先写个打表的代码,这里不提供.打完表观察数据,我们会发现数据其实是有规律的.完全不需要暴力的把所有数 ...

  3. UVA 10382.Watering Grass-贪心

    10382 - Watering Grass Time limit: 3.000 seconds n sprinklers are installed in a horizontal strip of ...

  4. Verilog的IDE Quartus II

    Quartus II  主要用于Verilog的开发,他是开发FPGA的利器,但他需要和modelsim相互配合,才能实现它的编写和仿真.modelsim是第三方的EDA,需要另外安装,对于Quart ...

  5. 51nod 1137 矩阵乘法【矩阵】

    1137 矩阵乘法 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题  收藏  关注 给出2个N * N的矩阵M1和M2,输出2个矩阵相乘后的结果.   Input 第1行 ...

  6. HDU 1060 Leftmost Digit (数论,快速幂)

    Given a positive integer N, you should output the leftmost digit of N^N.  InputThe input contains se ...

  7. Xamarin XAML语言教程控件模板的模板绑定

    Xamarin XAML语言教程控件模板的模板绑定 控件模板的模板绑定 为了可以轻松更改控件模板中控件上的属性值,可以在控件模板中实现模板绑定功能.模板绑定允许控件模板中的控件将数据绑定到公共属性上. ...

  8. 【枚举】URAL - 2081 - Faulty dial

    //._. ... ._. ._. ... ._. ._. ._. ._. ._. //|.| ..| ._| ._| |_| |_. |_. ..| |_| |_| //|_| ..| |_. ._ ...

  9. 【二分答案】【字符串哈希】bzoj2084 [Poi2010]Antisymmetry

    显然只有偶数长度的串符合题意,并且如果一个串符合题意,那么从其首尾各截掉一个字符也符合题意. 于是枚举中心,二分可以向左右扩展的最远距离,累计答案. #include<cstdio> #i ...

  10. 1.4(学习笔记)JSP自定义标签

    一.JSP自定义标签 JSP自定义标签,可以通过实现Tag接口.继承TagSupport类来设置标签功能. 后续通过配置文件将标签和具体的实现类关联. 二.自定义第一个标签(实现Tag接口) 自定义标 ...