免费情感专家在线咨询咨询qq

&&&&android 加载json数据到listview
android 加载json数据到listview
通过读取网络的json数据,并显示到listview中,并具有加载更多的功能
若举报审核通过,可奖励20下载分
被举报人:
imjinxihexi
举报的资源分:
请选择类型
资源无法下载
资源无法使用
标题与实际内容不符
含有危害国家安全内容
含有反动色情等内容
含广告内容
版权问题,侵犯个人或公司的版权
*详细原因:
VIP下载&&免积分60元/年(1200次)
您可能还需要
移动开发下载排行&&&&refresh
+ ListView+Json解析、简单的上滑下拉刷新的实现
+ ListView+Json解析、简单的上滑下拉刷新的实现
+ ListView+Json解析、简单的上滑下拉刷新的实现。。。。
若举报审核通过,可奖励20下载分
被举报人:
举报的资源分:
请选择类型
资源无法下载
资源无法使用
标题与实际内容不符
含有危害国家安全内容
含有反动色情等内容
含广告内容
版权问题,侵犯个人或公司的版权
*详细原因:
VIP下载&&免积分60元/年(1200次)
您可能还需要
Q.为什么我点的下载下不了,但积分却被扣了
A. 由于下载人数众多,下载服务器做了并发的限制。若发现下载不了,请稍后再试,多次下载是不会重复扣分的。
Q.我的积分不多了,如何获取积分?
A. 获得积分,详细见。
完成任务获取积分。
论坛可用分兑换下载积分。
第一次绑定手机,将获得5个C币,C币可。
关注并绑定CSDNID,送10个下载分
下载资源意味着您已经同意遵守以下协议
资源的所有权益归上传用户所有
未经权益所有人同意,不得将资源中的内容挪作商业或盈利用途
CSDN下载频道仅提供交流平台,并不能对任何下载资源负责
下载资源中如有侵权或不适当内容,
本站不保证本站提供的资源的准确性,安全性和完整性,同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
移动开发下载排行
您当前C币:0&&&可兑换 0 下载积分
兑换下载分:&
消耗C币:0&
立即兑换&&
兑换成功你当前的下载分为 。前去下载资源
你下载资源过于频繁,请输入验证码
如何快速获得积分?
你已经下载过该资源,再次下载不需要扣除积分
+ ListView+Json解析、简单的上滑下拉刷新的实现
所需积分:1
剩余积分:0
扫描微信二维码精彩活动、课程更新抢先知
VIP会员,免积分下载
会员到期时间:日
剩余下载次数:1000
+ ListView+Json解析、简单的上滑下拉刷新的实现
剩余次数:&&&&有效期截止到:
你还不是VIP会员VIP会员享免积分 . 专属通道极速下载
VIP下载次数已满VIP会员享免积分 . 专属通道极速下载,请继续开通VIP会员
你的VIP会员已过期VIP会员享免积分 . 专属通道极速下载,请继续开通VIP会员iOS怎样通过这样的JSON数据,实现上下拉刷新加载更多_问答_ThinkSAAS
iOS怎样通过这样的JSON数据,实现上下拉刷新加载更多
iOS怎样通过这样的JSON数据,实现上下拉刷新加载更多
"count": 87,
"next":"",
"posts": [
"author":"",
"body":"u66f4u597dua73u9a73u4e0du4e0du4e0du4e0du4e0du4e0du4e0du4e0du4e0du4e0du4e0du4e0du4e0du4e0du4e0du4e0du4e0du4e0du4e0du4e0d",
"body_html": null,
"body_title": null,
"comment_count": 0,
"comments":"",
"timestamp":"Wed, 24 Jun :03 GMT",
"author":"",
"body":"u770bu770bu770bu770bu61u60u60u",
"body_html": null,
"body_title": null,
"comment_count": 0,
"comments":"",
"timestamp":"Wed, 24 Jun :31 GMT",
"author":"",
"body":"uuuuuuuuuuuuuuuuuuuu6de1u6de1uu6de1uu6de1uu6de1uu6de1uu6de1uu6de1u7684",
"body_html": null,
"body_title": null,
"comment_count": 0,
"comments":"",
"timestamp":"Wed, 24 Jun :44 GMT",
"prev": null
请问怎样通过这样的JSON数据,实现下拉刷新加载更多,是要判断id吗?还是创建时间?或者输出怎样的JSON数据更方便一些?
next字段可以不需要,客户端可以通过count字段计算出下一次请求的页码。
count字段只需要在获取第一页数据时返回。
下拉刷新:清空本地所有数据,加载第一页。
上拉加载:使用当前页码加载数据。
下拉刷新和上拉加载加载网络数据成功后的共同逻辑:加载成功后通过count和获取到的数据总条数对比,如果还有数据,那么页码变量要加一。
下拉刷新上拉加载有一个很好用的库推荐
添加你想要问的问题
PHP开发框架
开发工具/编程工具
服务器环境
ThinkSAAS商业授权:
ThinkSAAS为用户提供有偿个性定制开发服务
ThinkSAAS将为商业授权用户提供二次开发指导和技术支持
让ThinkSAAS更好,把建议拿来。
开发客服微信随便扯扯1,我比较喜欢把判断写成 常量在前,变量在后的形式,主要是由于这样可以规避粗心引起的错误。
例如 &0 == mLength ,可以规避不小心写成mLength = 0;因为书写成 0= mLength会报错,而mLength = 0 不会报错。
若引起阅读不便,请包涵。
今天我们计划要实现一个装满数据的ListView,并且在顶部下拉可以刷新,下滑到底部可以加载更多。分析需求,第一件事就是要将ListView装满数据,那么这个数据从哪里来?从网络来,所以第一件事就是将网络数据下载下来。因此先添加权限:
&uses-permission android:name=&android.permission.INTERNET&/&
&!-- 硬盘缓存--&
&!-- 在SDCard中创建与删除文件权限 --&
&uses-permission android:name=&android.permission.MOUNT_UNMOUNT_FILESYSTEMS& /&
&!-- 往SDCard写入数据权限 --&
&uses-permission android:name=&android.permission.WRITE_EXTERNAL_STORAGE& /&
&!-- 从SDCard读取数据权限 --&
&uses-permission android:name=&android.permission.READ_EXTERNAL_STORAGE& /&
把后面三个也一起添加了吧,因为本例最终的效果要实现双缓存,所以对SD的读写权限也是必须的。
然后进入正题:加载网络数据:
package com.example.asynctaskdemo;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import com.example.asynctaskdemo.NewsAdapter.IRefereshListener;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends Activity {
private final static String TAG = &zxt/MainActivity&;
private final String Url = &/api/teacher?type=4&num=30&;
List&NewsBean& mNewsDatas =
private RefreshListView mListView ;
private TextView mNoDatas;
//下拉数据刷新 改写数组为集合
//public static String[]
public static List&String& urls;
//下拉数据刷新
private NewsAdapter mNewsAdapter;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mListView = (RefreshListView) findViewById(R.id.listView1);
(TextView) findViewById(R.id.tv_nodatas);
new NewTask().execute(Url);
//下拉刷新数据
/* public interface IRefreshCompleteListener{
public void onRefreshComplete();
private IRefreshCompleteListener mRefreshC
public void IRefreshCompleteListener(IRefreshCompleteListener listener){
mRefreshComplete =
public void refreshData(RefreshListView listview){
//获取最新数据
setReflashData();
//?????????
//mRefreshComplete.onRefreshComplete();
//下拉刷新
private int newDataslength ;
private void setReflashData() {
new DownPullTask().execute(Url);
//执行更新 start
/*NewsBean bean = new NewsBean();
bean.NewsNo = &31&;
bean.NewsName = &new Name&;
bean.NewsDescription = &new Des&;
bean.NewsPicResUrl = Math.random()&0.5? &/5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png& :
&http://img.my.csdn.net/uploads//_6518.jpg&;*/
//执行更新 end
private void showList(List&NewsBean& apk_list) {
//NewsAdapter adapter = (NewsAdapter) mListView.getAdapter();
/*if (adapter == null) {
listview = (ReFlashListView) findViewById(R.id.listview);
listview.setInterface(this);
adapter = new MyAdapter(this, apk_list);
listview.setAdapter(adapter);
} else {*/
if(mNewsAdapter!=null)
mNewsAdapter.onDateChange(apk_list);
private class DownPullTask extends AsyncTask&String,Void,List&NewsBean&&{
protected List&NewsBean& doInBackground(String... params) {
Log.i(TAG,&NewTask:doInBackground&);
return getDataByUrl(params[0]);
protected void onPostExecute(List&NewsBean& newsBeens) {
super.onPostExecute(newsBeens);
//fix bug if first nodata
//更新了几条数据
if(null!=newsBeens){
newDataslength = newsBeens.size();
if(null==mNewsDatas ){
mNewsDatas = new ArrayList&NewsBean&();
mNewsDatas.addAll(0,newsBeens);
showList(mNewsDatas);
//??listview ??????????
newDataslength = 0;
mNewsAdapter.refreshComplete(newDataslength);
setHintVisibility(newsBeens);
Log.i(TAG,&NewTask:onPostExecute:&+newDataslength);
Toast.makeText(MainActivity.this,&成功更新&+newDataslength+&条新闻&,Toast.LENGTH_SHORT).show();
//下拉刷新 end
class NewTask extends AsyncTask&String, Void, List&NewsBean&& {
protected List&NewsBean& doInBackground(String... params) {
return getDataByUrl(params[0]);
protected void onPostExecute(List&NewsBean& result) {
super.onPostExecute(result);
//下拉刷新
mNewsAdapter= new NewsAdapter(MainActivity.this, result,mListView);
//下拉刷新
mListView.setAdapter(mNewsAdapter);
mListView.setOnScrollListener(mNewsAdapter);
// 处理下拉刷新
mListView.setOnTouchListener(mNewsAdapter);
mNewsDatas = result;
// 处理下拉刷新
//刷新回调
mNewsAdapter.setIRefereshListener(new IRefereshListener() {
public void onRefresh() {
mListView.postDelayed(new Runnable() {
public void run() {
refreshData(mListView);
//刷新回调
setHintVisibility(result);
//加载更多begin
mNewsAdapter.setIOnScrollBottomListener(new NewsAdapter.IOnScrollBottomListener() {
public void onScrollBottom() {
mListView.postDelayed(new Runnable() {
public void run() {
//加载数据
loadMoreData();
mNewsAdapter.bottomDataLoadComplete();
//加载更多end
//加载更多begin
private int index =100;
private void loadMoreData(){
NewsBean bean = new NewsBean();
bean.NewsNo = &&+index++;
bean.NewsPicResUrl = &/5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png&;
/*List&NewsBean& datas = mNewsAdapter.getDatas();
datas.add(-1,bean);*/
mNewsAdapter.setData(-1,bean);
mNewsAdapter.notifyDataSetChanged();
//加载更多end
private void setHintVisibility(List&NewsBean& result) {
mNoDatas.setVisibility(result==null? View.VISIBLE:View.GONE);
public List&NewsBean& getDataByUrl(String url) {
List&NewsBean& datas =
String jsonString = readStream(new URL(url).openStream());
datas = parseJson(jsonString);
//Log.i(&zxt&, &jsonString:&+jsonString);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
return datas;
private List&NewsBean& parseJson(String jsonString) {
JSONObject jsonObject = new JSONObject(jsonString);
JSONArray jsonArray = jsonObject.getJSONArray(&data&);
JSONObject data =
List&NewsBean& datas =
new ArrayList&NewsBean&();
NewsBean bean =
//处理下拉刷新加入
if(null==urls){
urls = new ArrayList&String&();
List&String& tempUrls = new ArrayList&String&();
//处理下拉刷新加入
for (int i = 0; i & jsonArray.length(); i++) {
data = (JSONObject) jsonArray.get(i);
bean = new NewsBean();
bean.NewsPicResUrl = data.getString(&picSmall&);
//处理下拉刷新加入
tempUrls.add(bean.NewsPicResUrl);
//处理下拉刷新加入
bean.NewsName = data.getString(&name&);
bean.NewsDescription = data.getString(&description&);
bean.NewsNo = data.getString(&id&);
//加载大图加入
bean.NewsPicBigResUrl = data.getString(&picBig&);
//加载大图加入
datas.add(bean);
//处理下拉刷新加入
将新的url 加入到最上方
urls.addAll(0,tempUrls);
//处理下拉刷新加入
return datas;
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
private String readStream(InputStream is) {
StringBuilder jsonString = new StringBuilder();
String line = &&;
InputStreamReader isr = new InputStreamReader(is, &utf-8&);
BufferedReader br = new BufferedReader(isr);
if (null != (line = br.readLine())) {
jsonString.append(line);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return jsonString.toString();
package com.example.asynctaskdemo;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import java.util.List;
public class NewsAdapter extends BaseAdapter implements OnScrollListener,
OnTouchListener {
private static final String TAG = &zxt/NewsAdapter&;
private volatile List&NewsBean& mDatas;
private LayoutInflater mInflater;
private RefreshListView mListView;
private Context mContext;
// 网络图片加载
public List&NewsBean& getDatas() {
return mDatas;
public void setDatas(List&NewsBean& mDatas) {
this.mDatas = mDatas;
public void setData(int pos, NewsBean bean) {
if (-1 != pos) {
mDatas.add(pos, bean);
MainActivity.urls.add(pos, bean.NewsPicResUrl);
mDatas.add(bean);
MainActivity.urls.add(bean.NewsPicResUrl);
private ImageLoader mImageLoader;
public NewsAdapter(Context context, List&NewsBean& mDatas, RefreshListView listView) {
mContext = context;
this.mDatas = mDatas;
this.mInflater = LayoutInflater.from(context);
//抽象成单例后改写 begin
//mImageLoader = new ImageLoader(listView);
mImageLoader = ImageLoader.getInstance(context);
mImageLoader.setmListView(listView);
//抽象成单例后改写 end
mListView = listView;
initHeaderView();
initFooterView();
private void initFooterView() {
mFooterView = mListView.getFooterView();
//下拉刷新数据
public void onDateChange(List&NewsBean& mDatas) {
this.mDatas = mDatas;
this.notifyDataSetChanged();
//下拉刷新数据
private void initHeaderView() {
headerView = mListView.findViewById(R.id.headerview);
// 获取View高度
headerHeight = mListView.getHeaderHeight();
mTipView = (TextView) headerView.findViewById(R.id.tip);
mTimeView = (TextView) headerView.findViewById(R.id.lastupdate_time);
mArrowView = (ImageView) headerView.findViewById(R.id.arrow);
mBar = (ProgressBar) headerView.findViewById(R.id.progress);
public int getCount() {
if (mDatas != null)
return mDatas.size();
public Object getItem(int position) {
// TODO Auto-generated method stub
return mDatas.get(position);
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder =
if (convertView == null) {
//Log.i(TAG, &getView-&缓存为空:& + position);
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.item, parent, false);
holder.pic = (ImageView) convertView.findViewById(R.id.iv_pic);
holder.no = (TextView) convertView.findViewById(R.id.tv_no);
holder.name = (TextView) convertView.findViewById(R.id.tv_name);
holder.description = (TextView) convertView
.findViewById(R.id.tv_description);
convertView.setTag(holder);
//Log.i(TAG, &getView-&缓存过:& + position);
holder = (ViewHolder) convertView.getTag();
NewsBean bean = mDatas.get(position);
// 加载网络图片
holder.pic.setTag(bean.NewsPicResUrl);
// mImageLoader.getImageByAsyncTask(holder.pic, bean.NewsPicResUrl);
holder.pic.setImageResource(R.drawable.ic_launcher);
// 滑动优化 如果有缓存,则加载 否则不加载
final Bitmap pBitmap = mImageLoader.setDefaultBitmap(holder.pic, bean.NewsPicResUrl);
// /滑动优化
holder.name.setText(bean.NewsName);
holder.description.setText(bean.NewsDescription);
holder.no.setText(bean.NewsNo);
//添加事件点击
final String urlBig = bean.NewsPicBigResUrl;
final String urlSmall = bean.NewsPicResUrl;
holder.pic.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Toast.makeText(v.getContext(), &bean.NewsNo:& + urlBig, Toast.LENGTH_SHORT).show();
Intent intent = new Intent(mContext, BigImageActivity.class);
intent.putExtra(&urlBig&, urlBig);
intent.putExtra(&urlSmall&, urlSmall);
mContext.startActivity(intent);
return convertView;
class ViewHolder {
public ImageView pic;
public TextView name;
public TextView description;
public TextView no;
// 滚动时的优化 begin
private int mStart, mEnd;
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (scrollState == SCROLL_STATE_IDLE) {
Log.i(TAG, &scrollState:& + mStart + &-& + mEnd);
loadImages();
Log.i(TAG, &scrollState cancel:&);
mImageLoader.cancelAllTasks();
private void loadImages() {
if (null != mDatas && mDatas.size() & 0) {
//修复bug 滑动时边缘不加载 begin
int start = mStart != 0 ? mStart - 1 : 0;
int end = mEnd != mDatas.size() ? mEnd + 1 : mEnd;
//修复bug 滑动时边缘不加载 end
mImageLoader.loadImages(start, end);
private boolean isInit =
//加载更多 begin
private boolean isLoading =
private View mFooterView;
public interface IOnScrollBottomListener {
void onScrollBottom();
private IOnScrollBottomListener mIOnScrollBottomListener;
public void setIOnScrollBottomListener(IOnScrollBottomListener onScrollBottomListener) {
mIOnScrollBottomListener = onScrollBottomListener;
public void bottomDataLoadComplete() {
//隐藏view 加载数据 改变flag
mFooterView.setVisibility(View.GONE);
isLoading =
//加载更多 end
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
Log.i(TAG, &onScroll():totalItemCount& + totalItemCount + &
,isLoading:& + isLoading + &,
firstVisibleItem:&
+ firstVisibleItem + &
,visibleItemCount:& + visibleItemCount + &, totalItemCount:& + totalItemCount);
mStart = firstVisibleItem;
//其实现在的listview看不到那么多 应该-1 否则最后会空指针
(因为我们add了一个headerview进去)
add 了 footview 所以再-1
mEnd = mStart + visibleItemCount - 1 - 1;
if (visibleItemCount != 0 && isInit) {
loadImages();
//处理滑动加载更多: 2 != totalItemCount 防止没有数据一直在加载更多
if (2 != totalItemCount && firstVisibleItem + visibleItemCount == totalItemCount && !isLoading) {
isLoading =
mFooterView.setVisibility(View.VISIBLE);
//执行加载更多操作
if (null != mIOnScrollBottomListener) {
mIOnScrollBottomListener.onScrollBottom();
// 滚动时的优化 end
// 处理下拉刷新
private int lastY;
private View headerView;
private TextView mTipView;
private TextView mTimeView;
private ImageView mArrowView;
private ProgressBar mBar;
private int headerHeight;
private int gap;
public interface IRefereshListener {
public void onRefresh();
private IRefereshListener mRefereshListener;
public void setIRefereshListener(IRefereshListener listener) {
this.mRefereshListener = listener;
//监听执行完毕 继续滚动
public void refreshComplete(int length) {
Log.i(TAG, &refreshComplete()&);
//其实这里的mStarat =0的
mImageLoader.loadImages(mStart, mStart + length);
rollToInit(1);
public boolean onTouch(View v, MotionEvent event) {
if (mStart == 0 && isMoveEnable) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
lastY = (int) event.getY();
//初始化 几个view的状态显示
mTipView.setText(&下拉可以刷新&);
mArrowView.setVisibility(View.VISIBLE);
mBar.setVisibility(View.GONE);
//初始化 几个view的状态显示
case MotionEvent.ACTION_MOVE:
gap = (int) (event.getY() - lastY);
Log.i(TAG, & ACTION_MOVE gap:& + gap);
//移动View
setPaddingTop(-headerHeight + gap);
//下拉可以刷新(超过宽度)-》松开可以刷新-》
if (gap & headerHeight) {
mTipView.setText(&松开可以刷新&);
//下拉可以刷新(超过宽度)-》松开可以刷新-》
case MotionEvent.ACTION_UP:
//松开-》滑动到View宽度-》
if (gap & headerHeight) {
rollToInit(0);
//正在刷新-》
mTipView.setText(&正在刷新&);
mArrowView.setVisibility(View.GONE);
mBar.setVisibility(View.VISIBLE);
//执行刷新操作
if (mRefereshListener != null) {
mRefereshListener.onRefresh();
//执行刷新操作
//松开-》滑动到View宽度-》
//恢复初始。
rollToInit(1);
Log.i(TAG, &lastY:& + lastY + &headerHeight:& + headerHeight);
private boolean isMoveEnable =
private void rollToInit(int endTop) {
//回去的动画://使用ObjectAnimator 不好实现, 打算用ValueAnimator
/*ObjectAnimator animator = ObjectAnimator.ofFloat(mListView, &Y&,-(headerView.getPaddingTop()+headerHeight));
animator.setDuration(500).start();*/
isMoveEnable =
int top = headerView.getPaddingTop();
//解决 拖动不超过headerheight 不会滑动回去的bug
int end = top & 0 ? -(top + headerHeight) : -(top + headerHeight + headerHeight);
Log.i(TAG, &rollToInit:& + endTop + &
,top:& + top + &, -(top+headerHeight)
& + (-(top + headerHeight)));
ValueAnimator animator = ValueAnimator.ofInt(top, endTop == 1 ? end : endTop);
animator.addUpdateListener(new AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
Integer paddingTop = (Integer) animation.getAnimatedValue();
setPaddingTop(paddingTop);
//添加动画完成监听器
animator.addListener(new AnimatorListenerAdapter() {
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
isMoveEnable =
//添加动画完成监听器
animator.setDuration(500).start();
private void setPaddingTop(int top) {
if (null != headerView) {
headerView.setPadding(headerView.getPaddingLeft(), top, headerView.getPaddingRight(), headerView.getPaddingBottom());
package com.example.asynctaskdemo;
public class NewsBean {
public String NewsPicResUrl;
public String NewsPicBigResUrl;
public String NewsName;
public String NewsDescription;
public String NewsNo;
package com.example.asynctaskdemo;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class RefreshListView extends android.widget.ListView {
private final static String TAG =&zxt/refreshListView&;
private View headerView ;
private View footerView;
public View getFooterView() {
return footerView;
/*public void bottomDataLoadComplete(){
//隐藏view 加载数据 改变flag
footerView.setVisibility(View.GONE);
private int headerHeight;
public int getHeaderHeight() {
return headerHeight;
public RefreshListView(Context context) {
this(context, null);
public RefreshListView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
public RefreshListView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView(context);
private void initView(Context context) {
headerView = LayoutInflater.from(context).inflate(R.layout.header,null);
this.addHeaderView(headerView);
// 测量View
headerView.measure(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
// 获取View高度
headerHeight = headerView.getMeasuredHeight();
Log.d(TAG, &headerHeight:&+headerHeight);
//设置默认隐藏
setPaddingTop(-headerHeight);
//上啦刷新
View footerView = LayoutInflater.from(context).inflate(R.layout.footer_layout,this,false);
this.addFooterView(footerView);
this.footerView = footerView.findViewById(R.id.load_layout);
this.footerView.setVisibility(View.GONE);
private void setPaddingTop(int top){
if(null!=headerView){
headerView.setPadding(headerView.getPaddingLeft(), top, headerView.getPaddingRight(), headerView.getPaddingBottom());
package com.example.asynctaskdemo;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.support.annotation.Nullable;
import android.support.v4.util.LruCache;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import com..mcxtzhang.utils.FileUtils;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashSet;
import java.util.Set;
import libcore.io.DiskLruCache;
public class ImageLoader {
private static final String TAG = &zxt/ImageLoader&;
//抽象成单例 begin
private static class ImageLoaderHolder {
private static final ImageLoader mImageLoader = new ImageLoader();
private static Context mContext;
public static ImageLoader getInstance(Context context){
mContext = context.getApplicationContext();
return ImageLoaderHolder.mImageLoader;
private ImageLoader() {
Log.i(&TAG&,&ImageLoader&);
int maxMemory = (int) Runtime.getRuntime().maxMemory();
mCache = new LruCache&String, Bitmap&(maxMemory / 20) {
protected int sizeOf(String key, Bitmap value) {
return value.getByteCount();
//硬盘缓存 begin
//初始化工作
File cacheDir = FileUtils.getFileCache(mContext, &disk_caches&);
if (!cacheDir.exists()) {
cacheDir.mkdirs();
mDiskCache = DiskLruCache.open(cacheDir, 1, 1, 10 * 1024 * 1024);
} catch (IOException e) {
e.printStackTrace();
//硬盘缓存 end
mSets = new HashSet&NewsImageAsyncTask&();
//抽象成单例 end
//图片缓存 start
private LruCache&String,Bitmap& mCache;
//硬盘缓存
private DiskLruCache mDiskCache;
public Bitmap getBitmapFromCache(String url){
Log.i(TAG, &getBitmapFromCache&);
return mCache.get(url);
public void putBitmapToCache(String url,Bitmap bitmap){
Log.i(TAG, &putBitmapToCache&);
if(null == getBitmapFromCache(url)){
mCache.put(url, bitmap);
//图片缓存 end
public void getImageByAsyncTask(ImageView imageView,String url){
//图片缓存 start
Bitmap bitmap = getBitmapFromCache(url);
if(null == bitmap)
new NewsImageAsyncTask(/*imageView,*/url).execute();
imageView.setImageBitmap(bitmap);
//图片缓存 end
//每次加载一张图片
private class NewsImageAsyncTask extends AsyncTask&Void,Void,Bitmap&{
//private ImageView mImageV
private String mUrl;
public NewsImageAsyncTask(/*ImageView mImageView,*/String url) {
//this.mImageView = mImageV
mUrl = url;
protected Bitmap doInBackground(Void... params) {
//硬盘缓存
// 用了二级缓存 所以要改写获取图片的流程:
/*Bitmap result = getBitmapByUrl(mUrl);
Log.i(TAG, &isCancelled:&+isCancelled());
//内存缓存 start
putBitmapToCache(mUrl, result);
//内存缓存end*/
return getBitmapAndSaveToCacheByUrl(mUrl);
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
//设置图片 防止错位
/*if(mUrl.equals(mImageView.getTag())){
mImageView.setImageBitmap(result);
//滑动优化
ImageView imageView = (ImageView) mListView.findViewWithTag(mUrl);
if(imageView!=null && null != result)
imageView.setImageBitmap(result);
mSets.remove(this);
//滑动优化
public Bitmap getBitmapByUrl(String string) {
InputStream is1=null/*,is2 = null*/;
Bitmap result =
HttpURLConnection conn = (HttpURLConnection) new URL(string).openConnection();
is1 = new BufferedInputStream(conn.getInputStream());
//优化图片加载 begin
/*ByteArrayOutputStream out = new ByteArrayOutputStream();
ImageUtils.copy(is1,out);
is2 = new ByteArrayInputStream(out.toByteArray());*/
result = BitmapFactory.decodeStream(is1);
= ImageUtils.decodeSuitableBitmap(is,60,60);
//result = ImageUtils.decodeSuitableBitmap(string,1,1);
//Log.i(TAG,&resutl size:&+result.getByteCount());
//result = ImageUtils.decodeSampledBitmapFromInputStream(is1,is2,1,1);
Log.i(TAG,&resutl size:&+(result !=null?result.getByteCount():&null&));
/*if (result==null){
Log.i(TAG,&result==null&);
//Log.i(TAG,&result=&+result);
//优化图片加载 end
conn.disconnect();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
if(is1!=null){
is1.close();
/*if(is2!=null){
is2.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return result;
//滚动时的优化 begin
private static Set&NewsImageAsyncTask& mSets ;
private ListView mListView;
public ListView getmListView() {
return mListView;
public void setmListView(ListView mListView) {
this.mListView = mListView;
public void loadImages(int mStart, int mEnd) {
Log.i(TAG, &loadImages:& + mStart+&-&+mEnd);
for (int i = mStart; i & mEnd; i++) {
Log.i(TAG, &loadImages:&+i);
String url = MainActivity.urls.get(i);
Bitmap bm = getBitmapFromCache(url);
ImageView mImageView = (ImageView)mListView.findViewWithTag(url);
if(null!=bm && null!= mImageView){
mImageView.setImageBitmap(bm);
else{//重新下载
NewsImageAsyncTask task = new NewsImageAsyncTask(url);
mSets.add(task);
task.execute();
public void cancelAllTasks() {
if(mSets!=null){
for (NewsImageAsyncTask task : mSets) {
task.cancel(false);
//看缓存中是否有 有则设置 没有则默认图片不管
public Bitmap setDefaultBitmap(ImageView pic, String newsPicResUrl) {
Bitmap bm = getBitmapFromCache(newsPicResUrl);
if(null!=bm){
pic.setImageBitmap(bm);
return bm;
//滚动时的优化 end
//硬盘缓存 加载图片方法(不返回bitmap,为了通用,不仅仅保存图片) 并写入硬缓存 begin
private static boolean getBitmapUrlToStream(String urlString, OutputStream outputStream) {
HttpURLConnection urlConnection =
BufferedOutputStream out =
BufferedInputStream in =
final URL url = new URL(urlString);
urlConnection = (HttpURLConnection) url.openConnection();
in = new BufferedInputStream(urlConnection.getInputStream(), 8 * 1024);
out = new BufferedOutputStream(outputStream, 8 * 1024);
while ((b = in.read()) != -1) {
out.write(b);
} catch (final IOException e) {
e.printStackTrace();
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
if (out != null) {
out.close();
if (in != null) {
in.close();
} catch (final IOException e) {
e.printStackTrace();
//硬盘缓存 加载图片方法 end
//硬盘缓存
下载图片 存入缓存(SD ,内存都存入)方法 begin
private Bitmap getBitmapAndSaveToCacheByUrl(String mUrl) {
String key = FileUtils.toMD5String(mUrl);
FileDescriptor fileDescriptor =
FileInputStream fileInputStream =
DiskLruCache.Snapshot snapShot =
//尝试获取硬缓存里的数据
snapShot = mDiskCache.get(key);
//如果没有缓存
if (snapShot == null) {
//尝试读从网络取并写入
DiskLruCache.Editor editor = mDiskCache.edit(key);
if (editor != null) {
OutputStream outputStream = editor.newOutputStream(0);
if (getBitmapUrlToStream(mUrl, outputStream)) {
editor.abort();
//再次读取
snapShot = mDiskCache.get(key);
if (snapShot != null) {
fileInputStream = (FileInputStream) snapShot.getInputStream(0);
fileDescriptor = fileInputStream.getFD();
//利用读取的硬盘数据,生成bitmap
Bitmap bitmap =
if (fileDescriptor != null) {
bitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor);
//利用bitmap 存入内存缓存
if (bitmap != null) {
putBitmapToCache(mUrl, bitmap);
//返回bitmap
return bitmap;
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fileDescriptor == null && fileInputStream != null) {
fileInputStream.close();
} catch (IOException e) {
//加载大图
public void loadBigBitmap(String url, ImageView imageView, ProgressBar mProgressBar){
if(imageView!=null && null!= url){
new BigImageAsyncTask(imageView,mProgressBar).execute(url);
private class BigImageAsyncTask extends AsyncTask&String,Void,Bitmap& {
private ImageView mImageView;
private ProgressBar mProgressBar;
public BigImageAsyncTask(ImageView imageView, ProgressBar progressBar) {
mImageView = imageView;
mProgressBar = progressBar;
protected Bitmap doInBackground(String... params) {
return getBitmapByUrl(params[0]);
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
if(bitmap!=null)
mImageView.setImageBitmap(bitmap);
if(null!=mProgressBar){
mProgressBar.setVisibility(View.GONE);
package com.example.asynctaskdemo;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.util.Log;
import android.widget.ImageView;
import android.widget.ProgressBar;
* Created by zhangxutong on .
public class BigImageActivity extends Activity{
private ImageView mBigImageView;
private ProgressBar mProgressBar;
private ImageLoader mImageLoader;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bigimage);
initView();
mImageLoader = ImageLoader.getInstance(BigImageActivity.this);
Intent intent = getIntent() ;
String urlBig = intent.getStringExtra(&urlBig&);
String urlSmall = intent.getStringExtra(&urlSmall&);
//设置初始值
if(null!=urlSmall) {
Bitmap bitmap = mImageLoader.getBitmapFromCache(urlSmall);
Log.i(&TAG&,&urlSmall:&+urlSmall+&, bitmap:&+bitmap);
if(null!=bitmap){
mBigImageView.setImageBitmap(bitmap);
//加载大图
mImageLoader.loadBigBitmap(urlBig,mBigImageView,mProgressBar);
private void initView() {
mBigImageView = (ImageView) findViewById(R.id.iv_bigimage);
mProgressBar = (ProgressBar) findViewById(R.id.pb);
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:57425次
积分:1103
积分:1103
排名:千里之外
原创:28篇
评论:273条
我的CSDN博客: http://blog.csdn.net/zxt0601 我的稀土掘金: http://gold.xitu.io/user/56de210b816dfa 我的简书: /users/8e91ff99b072/timeline 我的github: /mcxtzhang
阅读:7691
(1)(4)(4)(4)(4)(3)(2)(2)(3)(1)

我要回帖

更多关于 情感问题在线咨询 的文章

 

随机推荐