zoukankan      html  css  js  c++  java
  • 滚动ListView时图像顺序混乱

    本文选自StackOverflow(简称:SOF)精选问答汇总系列文章之一,本系列文章将为读者分享国外最优质的精彩问与答,供读者学习和了解国外最新技术。本文将为读者讲解滚动ListView时图像顺序混乱的解决方法。


    问题:

    zeitgeist

    ListView有两个TextViews 和一个ImageView。图片是从网上下载的,缓存在LruCache。当在ListView滚动时,图片会出现几秒钟的混乱。直到正确的图片完全加载之前是不应该有任何图片出现的。我发现了几个同样的问题,但是没人能帮助我。

    这是我的代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    public class NewsAdapter extends BaseAdapter {
        private static LayoutInflater inflater;
        private List<Item> items = new LinkedList<Item>();
        private LruCache<String, Bitmap> mMemoryCache;
     
        public NewsAdapter(Context context) {
            inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
     
            // Bitmap Cache
            final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
            final int cacheSize = maxMemory / 8;
            mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
                @Override
                protected int sizeOf(String key, Bitmap bitmap) {
                    return getSizeInBytes(bitmap) / 1024;
                }
            };
        }
     
        public void add(Item item) {
            items.add(item);
        }
     
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder viewHolder = new ViewHolder();
            if(convertView == null) {
                convertView = inflater.inflate(R.layout.list_item_item, null);
                viewHolder.ivPic = (ImageView) convertView.findViewById(R.id.ivPic);
                viewHolder.tvTitle = (TextView) convertView.findViewById(R.id.tvTitle);
                viewHolder.tvShortDesc = (TextView) convertView.findViewById(R.id.tvShortDesc);
                convertView.setTag(viewHolder);
            } else {
                viewHolder = (ViewHolder) convertView.getTag();
            }
     
            final Item item = items.get(position);
            viewHolder.tvTitle.setText(item.getTitle());
            viewHolder.tvShortDesc.setText(Html.fromHtml(item.getShortDesc()));
     
            Bitmap bitmap = mMemoryCache.get(item.getPicUrl());
            if (bitmap != null) {
                viewHolder.ivPic.setImageBitmap(bitmap);
            } else {
                GetBitmap gb = new GetBitmap(item.getPicUrl(), viewHolder.ivPic);
                gb.execute();
            }
     
            return convertView;
        }
     
        static class ViewHolder {
            ImageView ivPic;
            TextView tvTitle;
            TextView tvShortDesc;
        }
     
        @Override
        public int getCount() {
            return items.size();
        }
     
        @Override
        public Item getItem(int position) {
            return items.get(position);
        }
     
        @Override
        public long getItemId(int position) {
            return 0;
        }
     
        @SuppressLint("NewApi")
        public static int getSizeInBytes(Bitmap bitmap) {
            if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                return bitmap.getByteCount();
            } else {
                return bitmap.getRowBytes() * bitmap.getHeight();
            }
        }
     
        private class GetBitmap extends AsyncTask<Void, Bitmap, Bitmap> {
            private String url;
            private ImageView ivPic;
     
            public GetBitmap(String url, ImageView ivPic) {
                this.url = url;
                this.ivPic = ivPic;
            }
     
            @Override
            protected Bitmap doInBackground(Void... params) {
                Bitmap bitmap = null;
                try {
                    URL url = new URL(this.url);
                    bitmap = BitmapFactory.decodeStream(url.openConnection().getInputStream());
                } catch (Exception e) {
                    e.printStackTrace();
                }
     
                return bitmap;
            }
     
            @Override
            protected void onPostExecute(Bitmap bitmap) {
                super.onPostExecute(bitmap);
                if (bitmap != null) ivPic.setImageBitmap(bitmap);
            }
     
        }
     
    }

    如果谁能帮助我那就太好了!先谢过!

    PS:我忘记了一些东西,请不要建议任何库,我想在不使用外部库的情况下完成它。

    答案:

    Rajesh CP

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public GetBitmap(String url, ImageView ivPic, int position) {
        this.url = url;
        this.ivPic = ivPic;
        this.position = position;
        ivPic.setTag(position);
        ivPic.setImageBitmap(null);
    }
     
    @Override
    protected void onPostExecute(Bitmap bitmap) {
         super.onPostExecute(bitmap);
         if(bitmap != null && ((Integer)getTag) == this.position)
             ivPic.setImageBitmap(bitmap);
    }

    问题在于你没有检查图像是否在同一位置。试试上面的代码,希望能帮到你。在代码中,我没有找到任何推动位图加载到缓存的代码。

    user2365568

    可能是这个代码片段:

    1
    ViewHolder viewHolder = new ViewHolder();

    这个片段是在每次调用getView的时候,创建viewHolder的新实例。

    试试用这个来代替:

    1
    final ViewHolder viewHolder;

    然后在if结构中:

    1
    viewHolder = new ViewHolder();

    执行你的代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
       final ViewHolder viewHolder;
     
        if(convertView == null) {
            convertView = inflater.inflate(R.layout.list_item_item, null);
            viewHolder = new ViewHolder();
            viewHolder.ivPic = (ImageView) convertView.findViewById(R.id.ivPic);
            viewHolder.tvTitle = (TextView) convertView.findViewById(R.id.tvTitle);
            viewHolder.tvShortDesc = (TextView) convertView.findViewById(R.id.tvShortDesc);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }
     
        final Item item = items.get(position);
        viewHolder.tvTitle.setText(item.getTitle());
        viewHolder.tvShortDesc.setText(Html.fromHtml(item.getShortDesc()));
     
        Bitmap bitmap = mMemoryCache.get(item.getPicUrl());
        if (bitmap != null) {
            viewHolder.ivPic.setImageBitmap(bitmap);
        } else {
            GetBitmap gb = new GetBitmap(item.getPicUrl(), viewHolder.ivPic);
            gb.execute();
        }
     
        return convertView;
    }

    原文链接:ListView - Images shuffle while scrolling

    文章选自StackOverFlow社区,鉴于其内容对于开发者有所帮助,现将文章翻译于此,供大家参考及学习。9Tech将每日持续更新,读者可点击StackOverflow(简称:SOF)精选问答汇总,查看全部译文内容。同时,我们也招募志同道合的技术朋友共同翻译,造福大家!报名请发邮件至zhangqi_wj#cyou-inc.com。(#换成@)


  • 相关阅读:
    iOS-字符串的连接
    [Win32]Win32 SDK编程系列文章——键盘输入消息
    [置顶] eclipse导入svn下载的项目后无法与服务器的svn项目关联
    iOS-时区 日期处理
    数学之路(3)数据分析(5)
    Filter解决中文乱码问题
    Mac OS X 10.8.3搭建Android工程源码的编译环境(解决找不到GCC、GIT、PYTHON的问题)
    paypal租用
    Java通过内部类实现回调功能
    处理9path图片边缘的小黑点
  • 原文地址:https://www.cnblogs.com/aikongmeng/p/3697328.html
Copyright © 2011-2022 走看看