滚动图像时ListView滞后

时间:2015-08-07 22:02:29

标签: android listview android-studio

当我添加图像时,我的ListView在向上滚动(向下滚动没有问题)时跳转/冻结,当我的键盘启动时不会发生这种情况。

我不拥有DownloadImageWithURLTask课程,我不记得从哪里获得它。

public class chatAdapter extends ArrayAdapter<chatModel> {

    private Context context;

    public String userName = null;
    public ImageView hold = null;

    private static class ViewHolder{
        TextView userName;
        TextView userMessage;
        ImageView userImage;
    }

    public chatAdapter(Context c, List<chatModel> items){
        super(c, 0, items);
        this.context = c;
    }

    class DownloadImageWithURLTask extends AsyncTask<String, Void, Bitmap> {
        ImageView bmImage;
        public DownloadImageWithURLTask(ImageView bmImage) {
            this.bmImage = bmImage;
        }
        protected Bitmap doInBackground(String... urls) {
            String pathToFile = urls[0];
            Bitmap bitmap = null;
            try {
                InputStream in = new java.net.URL(pathToFile).openStream();
                bitmap = BitmapFactory.decodeStream(in);
            } catch (Exception e) {
                Log.e("Error", e.getMessage());
                e.printStackTrace();
            }
            return bitmap;
        }
        protected void onPostExecute(Bitmap result) {
            bmImage.setImageBitmap(result);
        }
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent){
        final chatModel chatModel = getItem(position);

        final ViewHolder viewHolder;
        if (convertView == null){
            viewHolder = new ViewHolder();
            LayoutInflater inflater = LayoutInflater.from(getContext());
            convertView = inflater.inflate(R.layout.activity_chat_box, parent, false);

            TextView userName = (TextView)convertView.findViewById(R.id.usern);
            TextView userMessage = (TextView)convertView.findViewById(R.id.msg);
            final ImageView userImage = (ImageView)convertView.findViewById(R.id.imageView8);
            userName.setText(chatModel.userName);
            userMessage.setText(chatModel.chatMessage);

            final String userAvatarURL = "http://downtowndons.eu/Downtown/Avatar/" + chatModel.userName;


                    DownloadImageWithURLTask downloadTask = new DownloadImageWithURLTask(userImage);
                    downloadTask.execute(userAvatarURL);
        } else {
            viewHolder = (ViewHolder)convertView.getTag();
        }

        convertView.setAnimation(AnimationUtils.loadAnimation(context, R.anim.abc_slide_in_bottom));

        return convertView;
    }

}

5 个答案:

答案 0 :(得分:1)

如果您使用AsyncTask在imageView中加载Image.While在listview中快速滚动,您可能有机会获得OutofMemory异常。为了解决这些类型的异常,您需要处理内存缓存机制来处理图像。默认情况下有android中有大量的图像加载库。最简单的库之一是Universal Image Loader。     使用通用图像加载程序异步下载图像。

         http://github.com/nostra13/Android-Universal-Image-Loader

图书馆本身有一个下载图片的示例代码。您可以参考它。下载库后添加库与您的项目并在必要的地方插入以下代码

将此代码写入适配器构造函数

ImageLoader  imageloader = ImageLoader.getInstance();

imageloader.init(ImageLoaderConfiguration.createDefault(context));

DisplayImageOptions options; = new DisplayImageOptions.Builder()
                .showImageForEmptyUri(R.drawable.ic_empty)
                .showImageOnFail(R.drawable.ic_error)
                .resetViewBeforeLoading(true).cacheOnDisk(true)
                .imageScaleType(ImageScaleType.EXACTLY)
                .bitmapConfig(Bitmap.Config.RGB_565).considerExifParams(true)
                .cacheInMemory(true)
                .displayer(new FadeInBitmapDisplayer(300)).build();

在getView中替换此代码而不是您的代码。

    if(convertView==null){
    // ... other stuff
    viewHolder.userName=(TextView)convertView.findViewById(R.id.usern);
    viewHolder.userMessage=(TextView)convertView.findViewById(R.id.msg);
    viewHolder.userImage=           (ImageView)convertView.findViewById(R.id.imageView8);
 }else{
    viewHolder=(ViewHolder)convertView.getTag();
 }

 viewHolder.userName.setText(chatModel.userName);
 viewHolder.userMessage.setText(chatModel.chatMessage);

 final String    userAvatarURL="http://downtowndons.eu/Downtown/Avatar/"+chatModel.userName;
 imageloader.displayImage(userAvatarURL,  viewHolder.userImage); 

答案 1 :(得分:0)

要从网上获取图片,请尝试使用此答案中提到的这两个库中的一个:https://stackoverflow.com/a/22862991/1018109

我强烈建议您对此问题发表所有答案和评论:Lazy load of images in ListView

答案 2 :(得分:0)

ListView冻结,因为它试图再次重新下载图像。 在这种情况下,最好的做法之一是使用Android LruCache或磁盘使用DiskLruCache将图像缓存到内存中以提高效率。

检查此链接,它会帮助你很多.. http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html#disk-cache

答案 3 :(得分:0)

最初,您的问题是在滚动时获取和加载图像。此外,您不会将先前下载的图像存储在缓存中。

要解决下载图像问题,请使用任何图像缓存库

与他们中的任何一个一起去,你的问题将得到解决!我已经提到了每个库的示例和listview。看看吧!

答案 4 :(得分:0)

我对此比较陌生,但我的代码丢失了。看起来你实际上并没有使用你的viewholder模式做任何事情。您的查看器应该是每次更新时获取两个文本视图和一个图像视图的快速方法,这样可以加快滚动列表视图的速度。但是,你创建了它,但实际上并没有用它做任何事情。所以模式应该是这样的:

    if(convertView==null){
        // ... other stuff
        viewHolder.userName=(TextView)convertView.findViewById(R.id.usern);
        viewHolder.userMessage=(TextView)convertView.findViewById(R.id.msg);
        viewHolder.userImage=(ImageView)convertView.findViewById(R.id.imageView8);
    }else{
        viewHolder=(ViewHolder)convertView.getTag();
    }

    viewHolder.userName.setText(chatModel.userName);
    viewHolder.userMessage.setText(chatModel.chatMessage);

    final String userAvatarURL="http://downtowndons.eu/Downtown/Avatar/"+chatModel.userName;

    DownloadImageWithURLTask downloadTask=new DownloadImageWithURLTask(viewHolder.userImage);
    downloadTask.execute(userAvatarURL);