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

首先来看一下效果图

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

1.Android SwipeRefreshLayout

实现SwipeRefreshLayout非常容易,我们将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.新建一个工程

1.打开Android Studio,选择File->New 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);    }}

大功告成!

更多相关文章

  1. 下拉刷新相关
  2. Android(安卓)内存分析工具 MAT(Memory Analyzer Tool)
  3. Google Maps Android(安卓)API v2 (google Maps api key 申请)
  4. Android(安卓)Studio导入项目app module一直不显示
  5. android 关于prop属性
  6. Android(安卓)RecyclerView
  7. android uri用法!!!
  8. Android代码中添加打印信息
  9. 安卓 Android之开发简单小应用(二)

随机推荐

  1. Android的UI学习
  2. 在Android实现人脸识别的详细过程
  3. Android的AIDL以及挂断电话
  4. 如何在android平台上实现语音识别
  5. Android中获取控件的宽度以及高度的几种
  6. AndroidStudio查看对象引用,是否内存泄露
  7. 使用Eclipse开发Android
  8. android拦截短信并屏蔽系统的Notificatio
  9. Android学习笔记2-如何开始第一个项目?
  10. Android MotionEvent 坐标获取