ListView动态加载网络数据的解决办法

来源:互联网 发布:mysql 联表查询 count 编辑:程序博客网 时间:2024/06/02 22:37

1.滚动加载

listView.setOnScrollListener(new OnScrollListener() {
//添加滚动条滚到最底部,加载余下的元素

@Override
public void onScrollStateChanged(AbsListView view, int
 scrollState) {
if (scrollState ==
 OnScrollListener.SCROLL_STATE_IDLE) {
loadRemnantListItem();
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int
 totalItemCount) {}
});


listView.setOnItemSelectedListener(
new
 OnItemSelectedListener() {
//按键选择List中的item,焦点落在最下面的view上加载余下的item

@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long
 id) {
if(footerView ==
 view) {
loadRemnantListItem();
listView.setSelection(position 
- 1
);
}
}
@Override
publicvoid onNothingSelected(AdapterView<?>
 parent) {}
});

privatevoid loadRemnantListItem() {//
滚到加载余下的数据
//
动态的改变listAdapter.getCount()的返回值
//使用Handler调用listAdapter.notifyDataSetChanged();更新数据

}

 

2.滚动翻页

//listView监听器代码相同
privatevoid loadRemnantListItem() {//滚到加载余下的数据
//
重新listView.setAdapter(newsAdapter);
//使用Handler调用listAdapter.notifyDataSetChanged();更新数据

}
注:在listView最下面可以使用listView.addFooterView(footerView, null, true);来显示“加载中...”等的字样来美化用户体验,在loadRemnantListItem()方法中动态控制“加载中...”的显示和不显示。
具体例子1:

ListView异步加载图片是非常实用的方法,凡是是要通过网络获取图片资源一般使用这种方法比较好,用户体验好,不用让用户等待下去,下面就说实现方法,先贴上主方法的代码:

package  cn.wangmeng.test;

import  Java.io.IOException;
import  java.io.InputStream;
import  java.lang.ref.SoftReference;
import  java.NET.MalformedURLException;
import  java.net.URL;
import  java.util.HashMap;

import  Android.graphics.drawable.Drawable;
import  android.os.Handler;
import  android.os.Message;

public   class  AsyncImageLoader {

      private  HashMap < String, SoftReference < Drawable >>  imageCache;
      
      public  AsyncImageLoader() {
             imageCache  =   new  HashMap < String, SoftReference < Drawable >> ();
         }
      
      public  Drawable loadDrawable( final  String imageUrl,  final  ImageCallback imageCallback) {
              if  (imageCache.containsKey(imageUrl)) {
                 SoftReference < Drawable >  softReference  =  imageCache.get(imageUrl);
                 Drawable drawable  =  softReference.get();
                  if  (drawable  !=   null ) {
                      return  drawable;
                 }
             }
              final  Handler handler  =   new  Handler() {
                  public   void  handleMessage(Message message) {
                     imageCallback.imageLoaded((Drawable) message.obj, imageUrl);
                 }
             };
              new  Thread() {
                 @Override
                  public   void  run() {
                     Drawable drawable  =  loadImageFromUrl(imageUrl);
                     imageCache.put(imageUrl,  new  SoftReference < Drawable > (drawable));
                     Message message  =  handler.obtainMessage( 0 , drawable);
                     handler.sendMessage(message);
                 }
             }.start();
              return   null ;
         }
      
     public   static  Drawable loadImageFromUrl(String url) {
            URL m;
            InputStream i  =   null ;
             try  {
                m  =   new  URL(url);
                i  =  (InputStream) m.getContent();
            }  catch  (MalformedURLException e1) {
                e1.printStackTrace();
            }  catch  (IOException e) {
                e.printStackTrace();
            }
            Drawable d  =  Drawable.createFromStream(i,  " src " );
             return  d;
        }
      
     public   interface  ImageCallback {
              public   void  imageLoaded(Drawable imageDrawable, String imageUrl);
         }


以上代码是实现异步获取图片的主方法,SoftReference是软引用,是为了更好的为了系统回收变量,重复的URL直接返回已有的资源,实现回调函数,让数据成功后,更新到UI线程。


ViewCache是辅助获取adapter的子元素布局

package  cn.wangmeng.test;

import  java.util.List;

import  cn.wangmeng.test.AsyncImageLoader.ImageCallback;

import  android.app.Activity;
import  android.graphics.drawable.Drawable;
import  android.view.LayoutInflater;
import  android.view.View;
import  android.view.ViewGroup;
import  android.widget.ArrayAdapter;
import  android.widget.ImageView;
import  android.widget.ListView;
import  android.widget.TextView;

public   class  ImageAndTextListAdapter  extends  ArrayAdapter < ImageAndText >  {

         private  ListView listView;
         private  AsyncImageLoader asyncImageLoader;

         public  ImageAndTextListAdapter(Activity activity, List < ImageAndText >  imageAndTexts, ListView listView) {
             super (activity,  0 , imageAndTexts);
             this .listView  =  listView;
            asyncImageLoader  =   new  AsyncImageLoader();
        }

         public  View getView( int  position, View convertView, ViewGroup parent) {
            Activity activity  =  (Activity) getContext();

             //  Inflate the views from XML 
            View rowView  =  convertView;
            ViewCache viewCache;
             if  (rowView  ==   null ) {
                LayoutInflater inflater  =  activity.getLayoutInflater();
                rowView  =  inflater.inflate(R.layout.image_and_text_row,  null );
                viewCache  =   new  ViewCache(rowView);
                rowView.setTag(viewCache);
            }  else  {
                viewCache  =  (ViewCache) rowView.getTag();
            }
            ImageAndText imageAndText  =  getItem(position);

             //  Load the image and set it on the ImageView 
            String imageUrl  =  imageAndText.getImageUrl();
            ImageView imageView  =  viewCache.getImageView();
            imageView.setTag(imageUrl);
            Drawable cachedImage  =  asyncImageLoader.loadDrawable(imageUrl,  new  ImageCallback() {
                 public   void  imageLoaded(Drawable imageDrawable, String imageUrl) {
                    ImageView imageViewByTag  =  (ImageView) listView.findViewWithTag(imageUrl);
                     if  (imageViewByTag  !=   null ) {
                        imageViewByTag.setImageDrawable(imageDrawable);
                    }
                }
            });
             if  (cachedImage  ==   null ) {
                imageView.setImageResource(R.drawable.default_image);
            } else {
                imageView.setImageDrawable(cachedImage);
            }
             //  Set the text on the TextView 
            TextView textView  =  viewCache.getTextView();
            textView.setText(imageAndText.getText());

             return  rowView;
        }

}


ImageAndTextListAdapter是实现ListView的Adapter,里面有个技巧就是 imageView.setTag(imageUrl),setTag是存储数据的,这样是为了保证在回调函数时,listview去更新自己对应 item,大家仔细阅读就知道了。

具体例子2:
01package cn.riddles.activity;
02
03import android.app.Activity;
04import android.os.Bundle;
05import android.widget.ListView;
06
07public class MainActivity extends Activity {
08    private ListView lv;
09    @Override
10    public void onCreate(Bundle savedInstanceState) {
11        super.onCreate(savedInstanceState);
12        setContentView(R.layout.main);
13        lv = (ListView) this.findViewById(R.id.test_lv);
14        lv.setAdapter(new SongListAdapter(this));
15    }
16}
01package cn.riddles.activity;
02
03import android.content.Context;
04import android.util.Log;
05import android.view.LayoutInflater;
06import android.view.View;
07import android.view.ViewGroup;
08import android.widget.BaseAdapter;
09import android.widget.ImageView;
10import android.widget.TextView;
11/**
12 * @author riddlezhang 歌曲条目适配器
13 */
14public class SongListAdapter extends BaseAdapter {
15    private static final String TAG = "SongListAdapter";
16    private Context mContext;
17    private String[] strings = {"王力宏","吴尊","何润东","金城武","吴彦祖"};
18    private String[] paths = {"http://list.image.baidu.com/t/image_category/galleryimg/menstar/hk/wang_li_hong.jpg",
19            "http://list.image.baidu.com/t/image_category/galleryimg/menstar/hk/wu_zun.jpg",
20            "http://list.image.baidu.com/t/image_category/galleryimg/menstar/hk/he_run_dong.jpg",
21            "http://list.image.baidu.com/t/image_category/galleryimg/menstar/hk/jin_cheng_wu.jpg",
22            "http://list.image.baidu.com/t/image_category/galleryimg/menstar/hk/wu_yan_zu.jpg"};
23    public SongListAdapter(Context mContext) {
24        this.mContext = mContext;
25    }
26
27    public void setmContext(Context mContext) {
28        this.mContext = mContext;
29    }
30
31    public int getCount() {
32        return paths.length;
33    }
34
35    public Object getItem(int position) {
36        return position;
37    }
38
39    public long getItemId(int position) {
40        return position;
41    }
42
43    public View getView(int position, View convertView, ViewGroup parent) {
44        convertView = LayoutInflater.from(mContext).inflate(R.layout.lv_adapter, null);
45        ImageView image = (ImageView) convertView.findViewById(R.id.image);
46        TextView songer = (TextView) convertView.findViewById(R.id.songer);
47        image.setTag(paths[position]);
48        songer.setText(strings[position]);
49        new CanvasImageTask().execute(image);//异步加载图片
50        Log.i(TAG, "execute:"+strings[position]);
51        return convertView;
52    }
53     
54}
view sourceprint?
01package cn.riddles.activity;
02
03import java.io.InputStream;
04import java.net.HttpURLConnection;
05import java.net.URL;
06
07import android.graphics.drawable.Drawable;
08import android.os.AsyncTask;
09import android.util.Log;
10import android.view.View;
11import android.webkit.URLUtil;
12
13
14/**
15 * @author riddlezhang
16 *  异步加载图片
17 */
18public class AsyncViewTask extends AsyncTask<View, Void, Drawable>{
19    private View mView;
20    protected Drawable doInBackground(View... views) {
21        Drawable drawable = null;
22        View view=views[0];
23        if (view.getTag() != null) {
24            try {
25                if (URLUtil.isHttpUrl(view.getTag().toString())) {//如果为网络地址。则连接url下载图片
26                    URL url = new URL(view.getTag().toString());
27                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
28                    conn.setDoInput(true);
29                    conn.connect();
30                    InputStream stream = conn.getInputStream();
31                    drawable = Drawable.createFromStream(stream, "src");
32                    stream.close();
33                }else {//如果为本地数据,直接解析
34                    drawable = Drawable.createFromPath(view.getTag().toString());
35                }
36            catch (Exception e) {
37                Log.v("img", e.getMessage());
38                return null;
39            }
40        }
41        this.mView=view;
42        return drawable;
43    }
44
45    protected void onPostExecute(Drawable drawable) {
46        if (drawable != null) {
47            this.mView.setBackgroundDrawable(drawable);
48            this.mView= null;
49        }
50    }
51
52}
0 0
原创粉丝点击