Android原生下拉刷新SwipeRefreshLayout实践
本篇文章翻译自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); }}
大功告成!
更多相关文章
- 下拉刷新相关
- Android(安卓)内存分析工具 MAT(Memory Analyzer Tool)
- Google Maps Android(安卓)API v2 (google Maps api key 申请)
- Android(安卓)Studio导入项目app module一直不显示
- android 关于prop属性
- Android(安卓)RecyclerView
- android uri用法!!!
- Android代码中添加打印信息
- 安卓 Android之开发简单小应用(二)