今天空闲,就下载了chrisbanes的Android-PullToRefresh,对其Sample进行了简单的修改,完成分页获取网络数据。(数据放于七牛云上了)
上代码
/*******************************************************************************
* Copyright 2011, 2012 Chris Banes.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************/
package com.handmark.pulltorefresh.samples;
import java.util.ArrayList;
import java.util.List;
import android.annotation.SuppressLint;
import android.app.ListActivity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.text.format.DateUtils;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.handmark.pulltorefresh.library.PullToRefreshBase;
import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode;
import com.handmark.pulltorefresh.library.PullToRefreshBase.OnLastItemVisibleListener;
import com.handmark.pulltorefresh.library.PullToRefreshBase.OnRefreshListener;
import com.handmark.pulltorefresh.library.PullToRefreshBase.State;
import com.handmark.pulltorefresh.library.PullToRefreshListView;
import com.handmark.pulltorefresh.library.extras.SoundPullEventListener;
import com.handmark.pulltorefresh.samples.GetNetJsonData.ItemAttri;
/**
* ①布局文件中使用PullToRefreshListView,findViewById
*
* ②设置滑动模式
*
* ③设置刷新监听事件
*
* a、getCurrentMode 判断当前刷新的Mode:上拉、下拉
*
* b、上拉刷新只请求首页数据 toPage = 1、isMore = true
*
* c、下拉刷新 toPage++,根据isMore来提示显示信息
*
* ④异步线程请求数据
*
* a、有返回数据isMore=true;
*
* b、否则,isMore=false 并通知主线程
*
* ⑤异步线程完成 执行onRefreshComplete操作
*
*/
@SuppressLint("HandlerLeak")
public final class PullToRefreshListActivity extends ListActivity {
private final String TAG = "PullToRefreshListActivity";
/** 首次网络请求页码 */
private static final int FIRST_PAGE = 1;
/** 数据请求页码 **/
private int toPage = 1;
/** 更多的网络数据 **/
private boolean isMore = true;
private List<ItemAttri> mListData;// 存储网络数据
private PullToRefreshListView mPullRefreshListView;
private ListViewAdapter mAdapter;// listView的适配器
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ptr_list);
initView();
// 初始化监听
initEvent();
// ListView actualListView = mPullRefreshListView.getRefreshableView();
// Need to use the Actual ListView when registering for Context Menu
// registerForContextMenu(actualListView);
// 获取首页数据并设置listView
mListData = new ArrayList<GetNetJsonData.ItemAttri>();
new GetDataTask().execute(FIRST_PAGE);
}
private void initView() {
mPullRefreshListView = (PullToRefreshListView) findViewById(R.id.pull_refresh_list);
// 滑动模式设置为双向滑动
mPullRefreshListView
.setMode(mPullRefreshListView.getMode() == Mode.BOTH ? Mode.PULL_FROM_START
: Mode.BOTH);
}
/**
* 初始化监听事件
*/
private void initEvent() {
// 设置listView的滑动刷新监听
mPullRefreshListView
.setOnRefreshListener(new OnRefreshListener<ListView>() {
@Override
public void onRefresh(
PullToRefreshBase<ListView> refreshView) {
// 获取当前时间并格式化
String label = DateUtils.formatDateTime(
getApplicationContext(),
System.currentTimeMillis(),
DateUtils.FORMAT_SHOW_TIME
| DateUtils.FORMAT_SHOW_DATE
| DateUtils.FORMAT_ABBREV_ALL);
// Update the LastUpdatedLabel
refreshView.getLoadingLayoutProxy()
.setLastUpdatedLabel(label);
if (PullToRefreshBase.Mode.PULL_FROM_START == mPullRefreshListView
.getCurrentMode()) {// 下拉刷新
mPullRefreshListView.getLoadingLayoutProxy()
.setRefreshingLabel("请稍等...");
mPullRefreshListView.getLoadingLayoutProxy()
.setPullLabel("下拉刷新...");
mPullRefreshListView.getLoadingLayoutProxy()
.setReleaseLabel("松开自动刷新");
// 重置集合数据
mListData = new ArrayList<ItemAttri>();
new GetDataTask().execute(FIRST_PAGE);
// 还原toPage初始值
toPage = 1;
// 还原上拉加载控制变量
isMore = true;
} else if (PullToRefreshBase.Mode.PULL_FROM_END == mPullRefreshListView
.getCurrentMode()) {// 上拉刷新
// 上拉刷新时,逐步加载新界面
toPage++;
if (isMore) {// 上一次请求有数据
// 自定义上拉header内容
mPullRefreshListView.getLoadingLayoutProxy()
.setPullLabel("上拉刷新...");
mPullRefreshListView.getLoadingLayoutProxy()
.setRefreshingLabel("正在为你加载更多赛程内容...");
mPullRefreshListView.getLoadingLayoutProxy()
.setReleaseLabel("松开自动刷新...");
} else {
// 上一次请求已经没有数据了
mPullRefreshListView.getLoadingLayoutProxy()
.setPullLabel("没有更多了...");
mPullRefreshListView.getLoadingLayoutProxy()
.setRefreshingLabel("没有更多了...");
mPullRefreshListView.getLoadingLayoutProxy()
.setReleaseLabel("没有更多了...");
}
new GetDataTask().execute(toPage);
}
}
});
// Add an end-of-list listener
mPullRefreshListView
.setOnLastItemVisibleListener(new OnLastItemVisibleListener() {
@Override
public void onLastItemVisible() {
// listView最后一个item可见时触发
Toast.makeText(PullToRefreshListActivity.this,
"End of List!", Toast.LENGTH_SHORT).show();
}
});
/**
* Add Sound Event Listener
*/
//SoundPullEventListener<ListView> soundListener = new SoundPullEventListener<ListView>(
// this);
//soundListener.addSoundEvent(State.PULL_TO_REFRESH, R.raw.pull_event);
//soundListener.addSoundEvent(State.RESET, R.raw.reset_sound);
//soundListener.addSoundEvent(State.REFRESHING, R.raw.refreshing_sound);
//mPullRefreshListView.setOnPullEventListener(soundListener);
}
private class GetDataTask extends AsyncTask<Integer, Void, Void> {
@Override
protected Void doInBackground(Integer... params) {
// 本次请求的数据集合
List<ItemAttri> currData = new ArrayList<ItemAttri>();
currData = new GetNetJsonData().getDataFromJson(params[0]);
if (!currData.isEmpty()) {
// 有数据返回
// 数据加入集合中
mListData.addAll(currData);
} else {
// 没有数据
isMore = false;
// 向主线程发送通知
mHandler.sendEmptyMessage(0);
// 没有数据toPage--
toPage--;
}
return null;
}
@Override
protected void onPostExecute(Void v) {
if (mAdapter == null) {
mAdapter = new ListViewAdapter();
// You can also just use setListAdapter(mAdapter) or
// mPullRefreshListView.setAdapter(mAdapter)
mPullRefreshListView.setAdapter(mAdapter);
} else {
mAdapter.notifyDataSetChanged();
}
Log.i(TAG, "page:" + toPage);
// Call onRefreshComplete when the list has been refreshed.
mPullRefreshListView.onRefreshComplete();// 完成刷新动作
super.onPostExecute(v);
}
}
/**
* 接收子线程传递出来的信息
*/
private Handler mHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
Toast.makeText(PullToRefreshListActivity.this, "没有更多了",
Toast.LENGTH_SHORT).show();
}
};
private class ListViewAdapter extends BaseAdapter {
@Override
public int getCount() {
return mListData.size();
}
@Override
public Object getItem(int position) {
return mListData.get(position);
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
convertView = getLayoutInflater().inflate(
R.layout.item_list_view, null);
holder.tvTitle = (TextView) convertView
.findViewById(R.id.tv_title);
holder.tvTime = (TextView) convertView
.findViewById(R.id.tv_time);
holder.tvContent = (TextView) convertView
.findViewById(R.id.tv_content);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.tvTitle.setText(mListData.get(position).title);
holder.tvTime.setText(mListData.get(position).time);
holder.tvContent.setText(mListData.get(position).content);
return convertView;
}
private class ViewHolder {
TextView tvTitle;
TextView tvTime;
TextView tvContent;
}
}
}
模拟数据存放在七牛云上
GetNetJsonData.java
package com.handmark.pulltorefresh.samples;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.util.Log;
/**
* 获取模拟数据
*/
public class GetNetJsonData {
/**
* 获取网络json数据
*
* @return 返回数据的list形式
* @throws Exception
*/
public List<ItemAttri> getDataFromJson(int pageNum) {
List<ItemAttri> dataList = new ArrayList<ItemAttri>();
String path = "http://jp-testdata.qiniudn.com/%40%2FlistDataPage"
+ pageNum + ".json";
URL url;
try {
url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(5000);
conn.setRequestMethod("GET");
if (HttpURLConnection.HTTP_OK == conn.getResponseCode()) {
InputStream instream = conn.getInputStream();
dataList = parseJSON(instream);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
for (int i = 0; i < dataList.size(); i++) {
Log.i("GetSimulationData", "" + dataList.get(i).title);
}
return dataList;
}
/**
* 解析JSON
*/
private List<ItemAttri> parseJSON(InputStream instream) {
List<ItemAttri> lst = new ArrayList<ItemAttri>();
byte[] data;
try {
data = IOUtils.read(instream);
String jsonStr = new String(data);
JSONArray array = new JSONArray(jsonStr);
for (int i = 0; i < array.length(); i++) {
JSONObject jsonObj = (JSONObject) array.getJSONObject(i);
ItemAttri v = new ItemAttri(jsonObj.getString("content"),
jsonObj.getString("time"), jsonObj.getString("title"));
lst.add(v);
}
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return lst;
}
/**
* 模拟实体类
*/
public class ItemAttri {
public String content;
public String time;
public String title;
public ItemAttri(String content, String time, String title) {
super();
this.content = content;
this.time = time;
this.title = title;
}
}
}
class IOUtils {
/**
* 读取输入流为byte[]数组
*/
static byte[] read(InputStream instream) throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while ((len = instream.read(buffer)) != -1) {
bos.write(buffer, 0, len);
}
return bos.toByteArray();
}
}