如何最好地管理ListView的适配器

时间:2013-12-24 01:33:13

标签: android android-listview

我管理一个效果很好的listView。它不应该有很多数据,它是用于评论, 但它可以让图片慢慢来。

每次在arrayList中显示的数据中进行更改时,我都会这样做:

adap = new ReviewListAdapter(ctx, comments); // Comments is the modified arrayList
    lv_reviews.setAdapter(adap);

但是,由于我管理图片,它变得非常慢。

有没有办法加快它? 使用notifyDataSetChanged?

4 个答案:

答案 0 :(得分:1)

我建议您在适配器中查看getView()方法,然后使用Picasso将图像加载到ImageView中,因为有100种方法可以搞砸加载图像。

编辑: 确保使用常见的ViewHolder模式。看看Making ListView Scrolling Smooth

答案 1 :(得分:1)

除了@ejohansson已经说过的内容之外,您还必须使用getItemViewType来区分包含TextView的布局和包含Image的布局。

有关更多信息和示例,请参阅this stack overflow问题。其余的(ViewHolder,Picasso等)只是优化,但你必须从头开始拥有一个好的架构。

答案 2 :(得分:1)

如上所述。首先使用ViewHolder模式,也可以使用picasso轻松实现图像缓存,如果你需要使用ImageSpannables,可以使用下面的picasso。

ViewHolder {
    ImageView icon;
    TextView name;
    TextView time;
    TextView comment;
}

在适配器中getView()执行此操作

public View getView(int position, View convertView, ViewGroup parent) {
    if (convertView == null) {
        convertView = new View(); // use a layout inflator to inflate view
    }
    ViewHolder holder = (ViewHolder) convertView.getTag();

    if (holder == null) {
        holder.name = convertView.findViewById(R.id.nameView);
        ... // other views
    }

    holder.name.setText("new name");
    new SetImageOnTextViewAsyncTask(context, holder.comment).execute("http://...");
}

创建一个AsyncTask,它接受你想要设置Image的视图并使用Picasso

public SetImageOnTextViewAsyncTask extends AsyncTask<String, Void, Bitmap bmp> {
    private final TextView textview;
    private final Context context;

    public SetImageOnTextViewAsyncTask(Context context, TextView textview) {
        this.textView = textview;
        this.context = context;
    }

    @Override
    protected String doInBackground(String... urls) {
        return Picasso.with(context).load(urls[0]).get(); // Picasso will cache you image and only download it once
    }

     @Override
    protected void onPostExecute(ImageView result) {
        textView.setText( new ImageSpan( result ), BufferType.SPANNABLE);
    }
}

最后,不是一直创建新的适配器,只需更新它的数据结构并调用notifyDataSetChanged。有一个名为updateData的方法或类似的方法,你可以根据你需要做的事情来附加项目或更改它们。

答案 3 :(得分:0)

我认为你的帮助。

适配器类。

public class Singer_Adapter extends BaseAdapter { 

private Context context; 
private final String image[]; 
private final String name[]; 
private final String singer_id[]; 

SharedPreferences.Editor sh1; 
public ImageLoader imageLoader; 

public Singer_Adapter(Context context, String image[], String name[], 
        String singer_id[]) { 
    this.context = context; 
    this.image = image; 
    this.name = name; 
    this.singer_id = singer_id; 

    sh1 = PreferenceManager.getDefaultSharedPreferences(context).edit(); 
    imageLoader = ImageLoader.getInstance(); 
} 

@Override
public int getCount() { 
    return image.length; 
} 

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

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

public View getView(final int position, View convertView, ViewGroup parent) { 

    LayoutInflater inflater = (LayoutInflater) context 
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 

    final ViewHolder holder; 
    View gridView = convertView; 

    if (convertView == null) { 

        gridView = new View(context); 

        // get layout from mobile.xml 
        gridView = inflater.inflate(R.layout.singers_view_row, null); 

        holder = new ViewHolder(); 

        holder.image1 = (ImageView) gridView.findViewById(R.id.list_iamge_singers); 
        holder.name1 = (TextView) gridView.findViewById(R.id.list_singer_name_singers); 
        holder.singer_id1 = (TextView)                       gridView.findViewById(R.id.list_singer_id_singers); 
        holder.album_list = (TextView)       gridView.findViewById(R.id.btn_albumlist_singers); 

        gridView.setTag(holder); 

    } else { 
        holder = (ViewHolder) gridView.getTag(); 
    } 

//  imageLoader.DisplayImage(image[position].toString(), holder.image1); 
    imageLoader.init(ImageLoaderConfiguration.createDefault(context)); 
    imageLoader.displayImage(image[position].toString(), holder.image1,      CommonUtilities.options); 
    holder.name1.setText(name[position].toString()); 
    holder.singer_id1.setText(singer_id[position].toString()); 

    holder.image1.setOnClickListener(new OnClickListener() { 

        @Override
        public void onClick(View arg0) { 

            /* 
             * holder.name1.setText(name[position].toString()); 
             * sh1.putString("singer_name", 
             * holder.name1.getText().toString()); 
             *  
             * sh1.putString("singer_image", image[position].toString()); 
             */

            holder.singer_id1.setText(singer_id[position].toString()); 
            sh1.putString("singer_id", holder.singer_id1.getText().toString()); 
            sh1.commit(); 

            Intent i = new Intent(context, Singers_Detail.class); 
            context.startActivity(i); 
        } 
    }); 

    holder.album_list.setOnClickListener(new OnClickListener() { 

        @Override
        public void onClick(View arg0) { 

            /* 
             * holder.name1.setText(name[position].toString()); 
             * sh1.putString("singer_name", 
             * holder.name1.getText().toString()); 
             *  
             * sh1.putString("singer_image", image[position].toString()); 
             */

            holder.singer_id1.setText(singer_id[position].toString()); 
            sh1.putString("singer_id", holder.singer_id1.getText().toString()); 
            sh1.commit(); 

            Intent i = new Intent(context, Singers_Detail.class); 
            context.startActivity(i); 
        } 
    }); 

    return gridView; 
} 

static class ViewHolder { 
    ImageView image1; 
    TextView singer_id1; 
    TextView name1; 
    TextView album_list; 
}
}