如何刷新GridView的适配器内的imageView

时间:2014-03-29 22:11:22

标签: android gridview imageview refresh adapter

我一直在玩Android,但我被困住了。我有一个适配器类 在我的gridView中的每个项目的imageview中设置图像。我使用观察者模式来通知调用update方法的活动,并使用notifydatasetchanged刷新适配器,并使gridview本身和imageView无效。

问题是当我更改一个对象(它有一个drawable的引用),并尝试更新时,imageview中没有任何反应。我试图调试,对象被更改,所以我不明白为什么它不更新...

另外,有了它,它可以很好地使图像消失,所以这很笨拙..:shape.setImage(android.R.color.transparent)

@Override
    public void update(Observable arg0, Object arg1)
    {
    //  Toast.makeText(this, "I am notified",0).show();

        adapter.notifyDataSetChanged();
        gridView.findViewById(R.id.picture).invalidate();
        gridView.invalidate();

    }

这是需要显示的对象的示例:

public class Square extends Shape
{
    public Square()
    {
        setImage(R.drawable.square);
    }
    public String print()
    {
        return "s ";
    }
    public String getName()
    {
        return "Square";
    }
}

我的适配器:

public class GridAdapter extends ArrayAdapter<Shape>
{
     Context context;
     int layoutResourceId;   
     List<Shape> data = null;



    public GridAdapter(Context context, int layoutResourceId, List<Shape> data)
     {
            super(context, layoutResourceId, data);
            this.layoutResourceId = layoutResourceId;
            this.context = context;
            this.data = data;
     }
     public View getView(int position, View convertView,ViewGroup parent) 
     {
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            View rowView = inflater.inflate(R.layout.list_item, parent, false);

            rowView.setBackgroundResource(R.drawable.customshape);

            ImageView imgView =(ImageView)rowView.findViewById(R.id.picture);

            imgView.setImageResource(data.get(position).getImage());

            return rowView;
     }

4 个答案:

答案 0 :(得分:2)

我认为这里的实际问题是从UI线程外部更新drawable。 notifyDataSetChanged()不是答案。至少在我的情况下,数据集没有改变。数据集发生了变化,我将drawable设置为null(这是有效的)。后来,当图像完成加载时,我没有从UI线程更新,所以GridView不知道它应该了解ImageView的失效。

我的答案是使用AsyncTask自动使用UI线程和线程同步。

请注意,notifyDatasetChanged()适用于适配器中getViewId()更改的时间 - 与drawable更改时实际上没有任何关系。另请注意,setImageDrawable()会自动使ImageView无效。实际上不需要调用ImageView.invalidate()或任何其他invalidate()。你只需更新UI线程中的drawable,并且AsyncTask带有所有合适的包袱,不仅可以在合适的时间进行,而且可以让GridView在更新各种画布和drawable之前了解它。高速缓存。

我从谷歌Android开发页面和源头潜水中了解了大部分内容。奇怪的是,Android Studio(ctrl-B)中的源头潜水实际上比通过所有文档更容易,希望偶然发现解释问题的正确段落。虽然,这里很好地解释了这个问题:

http://developer.android.com/training/displaying-bitmaps/process-bitmap.html

答案 1 :(得分:0)

  

问题是当我更改一个对象(有一个引用的对象)   一个drawable),并尝试更新,在imageview中没有任何反应。

让我们看一下doc:

public void notifyDataSetChanged()

  

通知附加的观察者基础数据已经存在   已更改,任何反映数据集的视图都应自行刷新。

当您致电notifyDataSetChanged()并且未更新您的网格视图时,唯一的原因是您的adapter数据集和object是两个不同的东西。这意味着您的gridview数据未发生变化。您必须更改传递给gridView构造函数的对象(列表数据)。如果您更改其中任何一个,然后拨打notifyDataSetChanged()它将会起作用。 对象和适配器数据的引用必须相同。

我在网上看到的另一件事是你必须通过使用像(add(), insert(), remove(), clear(), etc.)这样的函数来操作它来更改适配器的数据集。

答案 2 :(得分:0)

我无法评论,所以我将在这里分享我的想法,如果我遗漏了某些内容,请在评论中告诉我。

好像你需要在GridAdapter中添加以下方法:

public void setData(List<Shape> stuff) {
    data.clear();
    data.addAll(stuff);
    notifyDataSetChanged();
}

现在,无论您在活动中创建适配器,都应该有一个传递的List来创建GridAdapter。我们称之为初始列表&#39; data1&#39;。

假设通过刷新&#39;你的意思是你想修改现有的项目。您需要在data1中找到该项并进行更改。然后,您需要找到已创建的GridAdapter实例,然后使用setData方法并传递data1。

希望这不是完全没用的信息。

注意:如果您发布了更多代码,将会很有帮助。

答案 3 :(得分:-3)

问题解决了大声笑,我刚刚制作了一个新的适配器而且工作正常