android中闪烁的图像

android中闪烁的图像,android,android-layout,listview,android-fragments,android-intent,Android,Android Layout,Listview,Android Fragments,Android Intent,我正在开发社交应用程序,它即将完成,但我遇到了一个问题,那就是图像闪烁。当屏幕上有大约9到10个图像时,如果我滚动页面,图像就会闪烁 @Override public View getView(final int position, View convertView, ViewGroup parent) { final ViewHolder holder; if (convertView == null) { LayoutInflater inf = (Layou

我正在开发社交应用程序,它即将完成,但我遇到了一个问题,那就是图像闪烁。当屏幕上有大约9到10个图像时,如果我滚动页面,图像就会闪烁

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    final ViewHolder holder;
    if (convertView == null) {
        LayoutInflater inf = (LayoutInflater) act.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = inf.inflate(R.layout.view_grid_explore, null);
        holder = new ViewHolder();
        holder.img = (ImageView) convertView.findViewById(R.id.img_grid_album);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }

    ImageLoader.getInstance().displayImage(
            Static_Urls.explore_pic + data.get(position).talk_pic,
            holder.img);
    convertView.setTag(holder);

    notifyDataSetChanged();
    return convertView;
}
  • 注意:不要忘记删除
    notifyDataSetChanged()
这是因为一旦UIL(通用图像加载器)将图像下载到设备中,它就会将图像缓存在内存和设备中

通过使用此代码:

ImageLoader.getInstance().displayImage(Static_Urls.explore_pic +data.get(position).talk_pic,
            holder.img);
ImageLoader imageLoader = ImageLoader.getInstance();

        File file = imageLoader.getDiskCache().get(Static_Urls.explore_pic +data.get(position).talk_pic);
        if (file==null) {
            //Load image from network
             imageLoader.displayImage(Static_Urls.explore_pic +data.get(position).talk_pic,
            holder.img); 
        }
        else {
           //Load image from cache
            holder.img.setImageURI(Uri.parse(file.getAbsolutePath()));
        }
每次调用
getView()
时,UIL都会尝试从网络获取图像,但在它释放图像时,该图像已经被缓存,因此它会在首先发出网络请求后显示图像

因此,为了消除这种闪烁现象,请使用以下代码:

ImageLoader.getInstance().displayImage(Static_Urls.explore_pic +data.get(position).talk_pic,
            holder.img);
ImageLoader imageLoader = ImageLoader.getInstance();

        File file = imageLoader.getDiskCache().get(Static_Urls.explore_pic +data.get(position).talk_pic);
        if (file==null) {
            //Load image from network
             imageLoader.displayImage(Static_Urls.explore_pic +data.get(position).talk_pic,
            holder.img); 
        }
        else {
           //Load image from cache
            holder.img.setImageURI(Uri.parse(file.getAbsolutePath()));
        }

此代码将首先检查映像是否已缓存,然后相应地从网络或缓存中获取映像。

其中的
notifyDataSetChanged()
行是多余的。使用适配器时,请始终记住(在适配器扩展BaseAdapter的情况下),
getView()
方法负责扩展列表项的布局,并在处理时更新UI(通常是这样)

调用
notifyDataSetChanged()
将导致立即再次调用
getView()
,这就是您看到闪烁的原因

仅当您要更新适配器内容时,才应调用
notifyDataSetChanged()
。一个例子是,在适配器中构建一个“refresh()”方法,如:

public void refresh(List<Object> list) {
    data.clear();// Assuming data is a List<> object or an implementation of it like ArrayList();
    data.addAll(list);
    notifyDataSetChanged(); // This will let the adapter know that something changed in the adapter and this change should be reflected on the UI too, thus the getView() method will be called implicitly.
}
公共作废刷新(列表){
data.clear();//假设数据是一个列表对象或它的一个实现,如ArrayList();
data.addAll(列表);
notifyDataSetChanged();//这将让适配器知道适配器中发生了更改,并且此更改也应反映在UI上,因此将隐式调用getView()方法。
}

首先删除notifyDataSetChanged()行。感谢Mike的工作。您使用的是哪个UIL版本。libs/universal-image-loader-1.9.3-with-sources.jar使用此
getDiscCache()
可以很好地使用此解决方案。尝试使用
Gradle
compile code.am使用getDiscCache()导入UIL库,但问题相同