安卓自定义ListView滚动时非常缓慢

6

各位,我在使用listview时遇到了一个问题。当滚动时,它运行得非常缓慢,有人能帮我吗?我的listview是自定义布局,每一行都有3个textview和1个imageview,并且所有内容都从网络获取。我使用了自定义适配器和视图持有者。

下面是我如何使用适配器的代码:

public class MessageList extends ListActivity {


    @Override
    public void onCreate(Bundle icicle) {
     super.onCreate(icicle);
        setContentView(R.layout.listarticle);

        loadFeed(link);
        setListAdapter(new IconAdapter(this));

    }

 /* This method load xml file and parse it into message object*/
 private void loadFeed(String link){
     try{
      BaseFeedParser parser = new BaseFeedParser(link);
      messages = parser.parse();
      titles = new ArrayList<String>(messages.size());
      image = new ArrayList<String>(messages.size());
      date_post = new ArrayList<String>(messages.size());
      descs = new ArrayList<String>(messages.size());
      for (Message msg : messages){
       titles.add(msg.getTitle());
       image.add(msg.getImageLink().toString());
       date_post.add(msg.getDate());
       descs.add(msg.getDescription());

      }
       } catch (Throwable t){
      Log.e("AndroidNews",t.getMessage(),t);
     }
    }

 /*this is my custom baseadapter */
 class IconAdapter extends BaseAdapter{
  private LayoutInflater mInflater;


  public IconAdapter(Context cxt){
   mInflater = LayoutInflater.from(cxt);


  }

  public class ViewHolder{
   private TextView title;
   private TextView date;
   private TextView desc;
   private ImageView thumb;
  }

  public View getView(int positiion, View convertView, ViewGroup parent){
   ViewHolder holder;

   if (convertView==null){
    convertView = mInflater.inflate(R.layout.row, null);

    holder = new ViewHolder();

    holder.title = (TextView) convertView.findViewById(R.id.title);
    holder.date = (TextView) convertView.findViewById(R.id.date);
    holder.desc = (TextView) convertView.findViewById(R.id.deskripsi);
    holder.thumb = (ImageView) convertView.findViewById(R.id.thumbnail);

    convertView.setTag(holder);
   }else{

    holder = (ViewHolder) convertView.getTag();
   }

   holder.title.setText(titles.get(positiion));
   holder.date.setText(date_post.get(positiion));
   holder.desc.setText(descs.get(positiion).substring(0, 55)+"...");
   Drawable draw = LoadImageFromWebOperation(image.get(positiion));

   holder.thumb.setImageDrawable(draw);

   return convertView;
  }
  /* this method take image from url that retrieve from xml*/
  public Drawable LoadImageFromWebOperation(String url){
   try{
    InputStream is = (InputStream) new URL(url).getContent();
    Drawable d = Drawable.createFromStream(is, "src name");
    return d;
   }catch (Exception e){
    Log.d("image", url, e);
    return null;
   }
  }

  @Override
  public int getCount() {
   return messages.size();
  }

  @Override
  public Object getItem(int position) {
   return messages.get(position);
  }

  @Override
  public long getItemId(int position) {
   return position;
  }

 }

编辑和格式化你的代码问题,以更好地理解你的问题。 - Vikas Patidar
@Raha,在你的构造函数中,将所有的URL请求并将它们存储在一个数组中,在getView方法中不要再次加载它们...这样会加快速度。 - st0le
现在我明白了。所以我应该先使用一个可绘制列表来保存它们,然后将它们放在适配器上? - Rahadyanteja
@st0le 兄弟,这真的让我在滚动时更快地浏览列表。非常感谢你的帮助。 - Rahadyanteja
@Raha,没问题。我会把它作为答案发布,以防万一... - st0le
显示剩余3条评论
4个回答

12
  public View getView(int positiion, View convertView, ViewGroup parent){
      ...
      Drawable draw = LoadImageFromWebOperation(image.get(positiion));
      ...
  }

这是问题所在。您永远不应该在UI线程中进行网络操作。为此工作实现一些异步任务。 此外,您可以使用traceview http://developer.android.com/guide/developing/tools/traceview.html 工具来确定性能瓶颈。


4
这就是你的问题所在。
Drawable draw = LoadImageFromWebOperation(image.get(positiion)); 

不要在getView()中重复发起URL请求,而是一次性发起所有请求并将Drawables存储在一个数组中,然后在getView中使用该数组。这样可以大大提高速度...


是的,我已经做到了,而且它完美地运行。感谢您提供的解决方案。 - Rahadyanteja

1

谢谢分享,但我已经使用了ViewHolder并重用了ConvertView。 - Rahadyanteja

0
Please use View Holder pattern in getview.

ViewHolder holder = null;

String fileName = arrfiles.get(position);
        if (convertView == null) {
            holder = new ViewHolder();
            LayoutInflater inflator = ((Activity) context).getLayoutInflater();
            convertView = inflator.inflate(R.layout.unsubmited_row, parent,
                    false);
            convertView.setClickable(false);
        } 
        else 
        {
            holder = (ViewHolder) convertView.getTag();
        }
        holder.txtFileName = (TextView) convertView
                .findViewById(R.id.txtFileName);
        holder.txtisActive = (TextView) convertView
                .findViewById(R.id.txtIsActive);
        holder.txtFileName.setText(fileName);
        convertView.setTag(holder);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接