动态显示来自资源/drawable的图像

3

我正在尝试从res/drawable文件夹中将不同的图片(.jpg,.png)动态放入一个ListView中。这些图片的名称来自数据库,而图片本身位于res/drawable文件夹中。

以下是我目前的代码,但有一个错误:

String imgName; --> 这里是我需要从数据库获取的图片名称

Drawable drawable;    
    drawable = Class.appContext.getResources().getDrawable(Class.appContext.getResources().getIdentifier("com.example.test:drawable/"+imgName,null,null));  

然后我为数据库中的每个图像将其存入一个ArrayList(大约有200张图片):

ArrayList<HashMap<String, Object>> list = new ArrayList<HashMap<String, Object>>();
HashMap<String, Object> map = new HashMap<String, Object>();

map = new HashMap<String, Object>();
map.put("img",drawable);

          map.put("text", "some text");
          list.add(map);

现在我返回列表;

在我调用的类中:

listReceive = Class.getImages(appContext); 

listSetup = new SimpleAdapter(this, listReceive, R.layout.row,
                        new String[] {"img", "text"}, new int[] {R.id.IMG_CELL, R.id.TEXT_CELL});
                lvList.setAdapter(listSetup);

XML行是一个ImageView和一个TextView

System.out:在坏位图URI上resolveUri失败: android.drawable.bitmapDrawable@405739 在坏位图URI上resolveUri失败: android.drawable.bitmapDrawable@405639 在坏位图URI上resolveUri失败: android.drawable.bitmapDrawable@405959 在坏位图URI上resolveUri失败: android.drawable.bitmapDrawable@405677... ... ...

当我将图片保存到本地或SD卡内存中,然后将路径放入arraylist中时,它可以正常工作:

map.put("img","/data/data/com.example.test/images/" + imgName);

我不能使用这个,因为那样我就需要将图片从res/drawable复制到本地或SD卡中。这会占用两倍的内存,这是不可行的。

必须有一种方法可以动态地从drawable获取图像。

有人知道我错过了什么吗? 谢谢。

3个回答

5
SimpleAdapter期望一个整数或字符串,指定资源或图像URI:
public void setViewImage (ImageView v, String value)
Since: API Level 1

当没有现有的ViewBinder或现有的ViewBinder无法处理与ImageView的绑定时,由bindView()调用以为ImageView设置图像。默认情况下,该值将被视为图像资源。如果该值不能用作图像资源,则该值将用作图像Uri。如果提供的数据不是int或Integer,则调用此方法而不是setViewImage(ImageView, int)。
我认为应该使用setViewBinderSimpleAdapter提供一个ViewBinder,以处理将Drawable数据绑定到ImageView。基本上,除非调用您的图像视图,否则setViewValue()方法应返回false。当为您的图像视图调用它时,该方法应设置视图中的数据并返回true。返回值指示ViewBinder是否能够设置视图或适配器是否应尝试通过其默认行为自行绑定数据。
private final SimpleAdapter.ViewBinder mViewBinder =
    new SimpleAdapter.ViewBinder() {
        @Override
        public boolean setViewValue(
                final View view,
                final Object data,
                final String textRepresentation) {

            if (view instanceof ImageView) {
                ((ImageView) view).setImageDrawable((Drawable) data);
                return true;
            }

            return false;
        }
    };

...

listSetup .setViewBinder(mViewBinder);

我曾经使用SimpleCursorAdapter和它的ViewBinder做过类似的事情


1
哥们,你太棒了!我刚刚实现了你的解决方案,它像魔法一样运行得很好!谢谢! - user601302
1
非常感谢您对 setViewValue 应该返回什么的解释! - LA_
@LA_ - 很高兴我的回答对你有帮助。感谢你的反馈。 - Bert F

1
简单的适配器期望地图中的字符串。但是你的地图包含了键“img”的可绘制对象。
相反,尝试扩展BaseAdapter类。覆盖getView方法,然后手动将可绘制对象设置为imageview并将文本设置为textview。
另一个想法是,保留每个可绘制对象可能不是一个好主意。而是在渲染列表行时动态获取可绘制对象。

谢谢,我将来肯定会使用BaseAdapter。看起来非常方便。 - user601302

0

以下这种方法或方式也有效 - 如果还有人感兴趣的话

List<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>();
Integer flags[] = new Integer[listdetail.size()];
Resources resources = getResources();
for (int i = 0; i < listdetail.size(); i += 2) {
    listName = listdetail.get(i).getName();
    int dynamicId = resources.getIdentifier(listdetail.get(i).getName().replaceAll(" ", "").toLowerCase(), "drawable", getActivity().getPackageName());
    if(dynamicId == 0) {
        dynamicId = R.drawable.test_image;
        flags[i] = dynamicId;
    }else {
        flags[i] = dynamicId;
    }
    HashMap<String, String> hm = new HashMap<String, String>();
    hm.put("value1", listdetail.get(i).getName());
    hm.put("valueImage1", Integer.toString(flags[i]));
    list.add(hm);
}

String[] from = { "value1", "valueImage1"};
int[] to = { R.id.textview, R.id.imageView };
SimpleAdapter adapter = new SimpleAdapter(getActivity().getBaseContext(), list, R.layout.listlayout, from, to);

ListView listView = (ListView) getActivity().findViewById(R.id.listview);
listView.setAdapter(adapter);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接