android开发ListView+Json+异步网络图片加载+滚动翻页的例子(图片能缓存,图片不错乱)

例子中用于解析Json的Gson请自己Google下载

主Activity:

package COM.Example.Main;

import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import COM.Example.Main.R;
import COM.Example.Main.stringGetJson.User;
import android.app.Activity;
import android.app.ListActivity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;

public class stringListActivity extends ListActivity {

    
private MyAdapter mMyAdapter;
    
private LinkedList<User> users = null;
    
// 当前Activity中的ListView
    ListView listView = null;
    
int lastItem = 0;
    LinearLayout loadingLayout 
= null;

    @Override
    
public void onCreate(Bundle savedInstanceState) {
        
super.onCreate(savedInstanceState);
        setContentView(R.layout.foodlistactivity);

        listView 
= getListView();
        setLoadingLayout();
        
new readTask().execute(null);
    }

    
private final class MyAdapter extends ArrayAdapter<User> {
        
public MyAdapter(Activity activity, List<User> newsList) {
            
super(activity, 0, newsList);
        }

        
private Map<Integer, View> viewMap = new HashMap<Integer, View>();

        @Override
        
public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder;

            View rowView 
= this.viewMap.get(position);

            
if (rowView == null) {
                User user 
= users.get(position);
                LayoutInflater inflater 
= ((Activity) this.getContext())
                        .getLayoutInflater();
                holder 
= new ViewHolder();
                rowView 
= inflater
                        .inflate(R.layout.foodlistactivity_item, 
null);
                holder.mNameText 
= (TextView) rowView
                        .findViewById(R.id.foodItemUsername);
                holder.mPhoto 
= (ImageView) rowView
                        .findViewById(R.id.foodItemPic);
                rowView.setTag(holder);

                holder.mNameText.setText(user.Name);

                
if (!holder.mPhoto.isDrawingCacheEnabled()) {
                    holder.mPhoto.setTag(user.Pic);
                    
new downImageTask().execute(holder.mPhoto);
                    holder.mPhoto.setDrawingCacheEnabled(
true);
                }
                viewMap.put(position, rowView);
            } 
else {
                holder 
= (ViewHolder) rowView.getTag();
            }

            
return rowView;
        }

        
public class ViewHolder {
            
public TextView mNameText;
            
public ImageView mPhoto;
        }

    }

    
public void setLoadingLayout() {
        LinearLayout layout 
= new LinearLayout(this);
        layout.setOrientation(LinearLayout.HORIZONTAL);
        ProgressBar progressBar 
= new ProgressBar(this);
        progressBar.setPadding(
00150);
        layout.addView(progressBar);
        TextView textView 
= new TextView(this);
        textView.setText(
"加载中...");
        textView.setGravity(Gravity.CENTER_VERTICAL);
        layout.addView(textView);
        layout.setGravity(Gravity.CENTER);
        loadingLayout 
= new LinearLayout(this);
        loadingLayout.addView(layout);
        loadingLayout.setGravity(Gravity.CENTER);
    }
    
    
private class scrollListener implements OnScrollListener {
        @Override
        
public void onScroll(AbsListView view, int firstVisibleItem,
                
int visibleItemCount, int totalItemCount) {
            
// 当listView中没有数据,或者数据超过100条,或者不是10的整数倍(即数据不足)时隐藏“更多”并取消onScroll事件的绑定
            if (mMyAdapter.getCount() >= 100 || mMyAdapter.getCount() % 10 > 0
                    
|| mMyAdapter.getCount() == 0) {
                listView.removeFooterView(loadingLayout);
                listView.setOnScrollListener(
null);
            }
            lastItem 
= firstVisibleItem + visibleItemCount - 1;// 这里减一是因为有FootView
        }

        @Override
        
public void onScrollStateChanged(AbsListView view, int scrollState) {
            
if (lastItem == mMyAdapter.getCount()
                    
&& scrollState == OnScrollListener.SCROLL_STATE_IDLE) {
                
// 进行翻页操作
                new scrollTask().execute(null);
            }

        }
    }
    
    
public class readTask extends AsyncTask<Object, Void, Void> {
    
        @Override
        
protected Void doInBackground(Object... arg0) {
            users 
= new stringGetJson().getJson();
            
return null;
        }

        @Override
        
protected void onPostExecute(Void result) {
            listView.addFooterView(loadingLayout);
            
            mMyAdapter 
= new MyAdapter(stringListActivity.this, users);
            setListAdapter(mMyAdapter);
            listView.setOnScrollListener(
new scrollListener());
        }
    }

    
public class scrollTask extends AsyncTask<Object, Void, Void> {
        
        @Override
        
protected Void doInBackground(Object... arg0) {
            
for (Iterator iterator = new stringGetJson().getJson()
                    .iterator(); iterator.hasNext();) {
                User user 
= (User) iterator.next();
                users.add(user);
            }
            
return null;
        }

        @Override
        
protected void onPostExecute(Void result) {
            mMyAdapter.notifyDataSetChanged();
        }
    }
}


Json数据来源(这里的例子中把json字符串直接写在代码中了,实际项目中需要改成从网络读取,例子中已经使用了多线程):

package COM.Example.Main;

import java.lang.reflect.Type;
import java.util.Iterator;
import java.util.LinkedList;

import android.database.MatrixCursor;
import android.widget.ListView;
import android.widget.TextView;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
public class stringGetJson {
    
    
// 设置临时ID,在项目中将被现实的id取代
    private int id = 0;
    
    
public stringGetJson() {
        
super();
    }

    
//通过getJson方法从Json字符串获取User的列表
    public LinkedList<User> getJson() {
        String jsonData 
= "[{\"Name\":\"xinuxForJson1\",\"Pic\":\"http://www.qqjay.com/uploads/110414/1_234626_5.jpg\"},{\"Name\":\"xinuxForJson2\",\"Pic\":\"http://www.qqjay.com/uploads/110414/1_234626_3.jpg\"},{\"Name\":\"xinuxForJson3\",\"Pic\":\"http://www.qqjay.com/uploads/110414/1_234626_4.jpg\"},{\"Name\":\"xinuxForJson4\",\"Pic\":\"http://sucai.qqjay.com/fengmian/201104/tupian1/8.jpg\"},{\"Name\":\"xinuxForJson5\",\"Pic\":\"http://sucai.qqjay.com/fengmian/201104/tupian1/10.jpg\"},{\"Name\":\"xinuxForJson6\",\"Pic\":\"http://sucai.qqjay.com/fengmian/201104/tupian1/7.jpg\"},{\"Name\":\"xinuxForJson7\",\"Pic\":\"http://sucai.qqjay.com/fengmian/201104/tupian1/11.jpg\"},{\"Name\":\"xinuxForJson8\",\"Pic\":\"http://sucai.qqjay.com/fengmian/201104/tupian1/12.jpg\"},{\"Name\":\"xinuxForJson9\",\"Pic\":\"http://sucai.qqjay.com/fengmian/201104/tupian1/9.jpg\"},{\"Name\":\"xinuxForJson10\",\"Pic\":\"http://sucai.qqjay.com/fengmian/201104/tupian/7.jpg\"}]";
        Type listType 
= new TypeToken<LinkedList<User>>() {}.getType();
        Gson gson 
= new Gson();
        LinkedList
<User> users = gson.fromJson(jsonData, listType);
        
return users;
    }

    
//为getJson提供了数据实体类
    final static class User {
        
public String Name;
        
public String Pic;
    }
}

图片下载AsyncTask

package COM.Example.Main;

import COM.Example.FunctionUtility.Download;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.widget.ImageView;

public class downImageTask extends AsyncTask<ImageView, Void, Bitmap> {
    
    ImageView gView 
= null;
    @Override
    
protected Bitmap doInBackground(ImageView... arg0) {
        gView 
= (ImageView)arg0[0];
        
return Download.getBitmapFromUrl(gView.getTag().toString());
    }

    @Override
    
protected void onPostExecute(Bitmap result) {
        
if(result != null){
        
this.gView.setImageBitmap(result);
        }
        
this.gView = null;
    }
}

网络图片下载类:

package COM.Example.FunctionUtility;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

public class Download {
    
public static Bitmap getBitmapFromUrl(String imgUrl) {
        URL url;
        Bitmap bitmap 
= null;
        
try {
            url 
= new URL(imgUrl);
            InputStream is 
= url.openConnection().getInputStream();
            BufferedInputStream bis 
= new BufferedInputStream(is);
            bitmap 
= BitmapFactory.decodeStream(bis);
            bis.close();
        } 
catch (MalformedURLException e) {
            e.printStackTrace();
        } 
catch (IOException e) {
            e.printStackTrace();
        }
        
return bitmap;
    }
}
原文地址:https://www.cnblogs.com/yeagen/p/2020985.html