如何通过Drawable图像名称从ArrayList<String>动态设置ImageView的来源?

6

我有一个ListView,每行都包括一个ImageView、一个TextView和另一个ImageView。

以下代码是列表视图行的XML:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="60dp"
android:background="#FFF">
<ImageView
android:id="@+id/left"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:src="@drawable/ic_default"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp" />
<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:layout_weight="1"
android:textSize="16sp" />
<ImageView
android:id="@+id/right"
android:layout_width="50dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:src="@drawable/ic_cena_play"
android:layout_marginRight="0dp"
android:layout_marginLeft="10dp"
android:clickable="true"
android:background="@drawable/mybuttonplay" />
</LinearLayout>

我有一个ArrayList<String>,其中包含我想要放在行的第一个ImageView中的Drawable的名称。我希望动态地将ImageView的源“ic_default”更改为具有ArrayList中名称的那些源。

在我的Activity中,在onCreate()中,我正在使用Adapter,如下面的代码:

ArrayList<String> items = new ArrayList();
items.add("Star");
items.add("Moon");
items.add("Dog");
items.add("Bird");
items.add("Tree");
ArrayList<String> itemsimg = new ArrayList();
itemsimg.add("ic_star");
itemsimg.add("ic_moon");
itemsimg.add("ic_dog");
itemsimg.add("ic_bird");
itemsimg.add("ic_tree");
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.scenesrow, R.id.text, items) {
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View row =  super.getView(position, convertView, parent);
            ImageView left = (ImageView) row.findViewById(R.id.left);
            //here I want to change the resource
            //Like if I had a function called getRosourceId(). DOES IT EXIST?!
            int x = getResourceId( itemsimg.get(position) );
            left.setImageResource(x);
            View right = row.findViewById(R.id.right);
            right.setTag(position);
            right.setOnClickListener(ScenesActivity.this);
            return row;
        }
    };

更新

感谢您的回答!现在我可以动态更改ImageView的来源(但尚未从ArrayList<String>中更改)。 setImageResource()方法以前不可用,因为我有一个View。通过将所有人建议的转换为ImageView,问题的大部分都解决了。但是,这些答案并没有涉及“资源名称”的动态问题。

现在最后的问题是left.setImageResource(resId)方法要求从资源获取ID,而我只有一个字符串。怎么做呢?

对不起,其他代码版本有一些错误。现在已经修复了。我认为最后的问题现在很清楚了。


我认为创建自定义的POJO类(getter/Setter方法)和创建自定义适配器,您可以轻松地使用自定义适配器和POJO类更改图像。 - Sanket990
1
因为您正在使用View而不是ImageView,请查看我的答案来完成您的工作。 - Shayan Pourvatan
4个回答

14
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.scenesrow, R.id.text, items) {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
        View row =  super.getView(position, convertView, parent);
        ImageView left = (ImageView)row.findViewById(R.id.left);
        left.setOnClickListener(ScenesActivity.this);
        ImageView right = (ImageView)row.findViewById(R.id.right);
        right.setTag(position);

       right.setImageResource(itemsimg.get(position));
       left.setImageResource(itemsimg.get(position));

       right.setOnClickListener(ScenesActivity.this);
       return row;
    }

用以下内容替换itemsimg:

ArrayList<Integer> itemsimg = new ArrayList<Integer>();
itemsimg.add(R.drawable.ic_star);
itemsimg.add(R.drawable.ic_moon);
itemsimg.add(R.drawable.ic_dog);
itemsimg.add(R.drawable.ic_bird);
itemsimg.add(R.drawable.ic_tree);

要通过String获取drawableId,您可以这样做:

Context context = imageView.getContext();
int id = context.getResources().getIdentifier("ic_tree", "drawable", context.getPackageName());
imageView.setImageResource(id);

虽然不够高效,但它可以用来查找偶尔需要的资源。


1
这不是从字符串“ic_star”获取“R.drawable.ic_star”整数的方法吗?我认为这应该解决最后一个问题。 - Sarah Sakamoto
你必须使用Integer,如果需要最后一部分(“ic_star”),则需要使用substring方法获取它,或将其存储在另一个数组中。 - Shayan Pourvatan
请查看我的编辑@SarahSakamoto并更改itemsImg - Shayan Pourvatan
1
但是这种方式是从Drawable中插入整数,而不是根据字符串信息动态获取它。我想要一种将字符串转换为相应的可绘制资源ID的方法。有什么办法可以做到吗? - Sarah Sakamoto

3
尝试这个:
right.setImageResource(R.drawable.addphoto);/*select a picture from drawable*/

同样适用于左侧。
left.setImageResource(R.drawable.addphoto);/*select a picture from drawable*/

讨论后

       ArrayList<String> items = new ArrayList();
    items.add("ic_star");
    items.add("ic_moon");
    items.add("ic_dog");
    items.add("ic_bird");
    items.add("ic_tree");
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.scenesrow, R.id.text, items) {
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                View row =  super.getView(position, convertView, parent);
/*View : not required to declare everytimes*/
                ImageView left = row.findViewById(R.id.left);
                left.setOnClickListener(ScenesActivity.this);
                ImageView right = row.findViewById(R.id.right);
                right.setTag(position);
                right.setOnClickListener(ScenesActivity.this);
                right.setImageResource(R.drawable.addphoto);/*select a picture from drawable*/
                left.setImageResource(R.drawable.addphoto);/*select a picture from drawable*/

                return row;
            }
        };

1
问题是方法setImageResource()不可用。 - Sarah Sakamoto
1
现在我已经得到了位图,但是没有设置图像资源的方法,我不知道该怎么办。 - Sarah Sakamoto
你的问题在于适配器类。适配器类中存在一些错误。我会告诉你。 - Satyaki Mukherjee
1
请发布完整的适配器类。您的适配器类不是正确的方式。 - Satyaki Mukherjee

2
将你的代码替换为以下内容:
ArrayList<String> items = new ArrayList();
items.add("ic_star");
items.add("ic_moon");
items.add("ic_dog");
items.add("ic_bird");
items.add("ic_tree");
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.scenesrow, R.id.text, items) {
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View row =  super.getView(position, convertView, parent);
            ImageView left = (ImageView) row.findViewById(R.id.left);
            left.setOnClickListener(ScenesActivity.this);
            left.setImageResource(R.drawable.leftphoto);
            ImageView right = (ImageView) row.findViewById(R.id.right);
            right.setTag(position);
            right.setOnClickListener(ScenesActivity.this);
            right.setImageResource(R.drawable.rightphoto);
            return row;
        }
    };

0

另一种简单而有结构的方法是:

1)将资源添加到您的drawable文件夹中,假设为(ic_home、ic_launcher、ic_logout)//您可以添加任意数量的图像

2)在values文件夹中的strings.xml中添加这些名称以及将显示在图像旁边的名称。它看起来会像这样...

 <!-- Drawer List Items -->
<string-array name="nav_drawer_items">
    <item>Home</item>
    <item>Add Category</item>
    <item>Logout</item>
</string-array>
<string-array name="nav_drawer_icons">
    <item>ic_home</item>
    <item>ic_addcategory</item>
    <item>ic_logout</item>
</string-array>

3) 现在创建一个POJO(getter/setter)类,它将在一个对象中保存图标文本和图标ID。就像这样...

public class DrawerItems {

private String icnName;
private int icnId;

/**
 * @return the icnName
 */
public String getIcnName() {
    return icnName;
}

/**
 * @param icnName
 *            the icnName to set
 */
public void setIcnName(String icnName) {
    this.icnName = icnName;
}

/**
 * @return the imageid
 */
public int getIcnId() {
    return icnId;
}

/**
 * @param imageid
 *            the imageid to set
 */
public void setIcnId(int imageid) {
    icnId = imageid;
}}

4) 现在我们需要在将其提供给适配器之前填充它。我们可以以这种方式完成

private DrawerItems navigationDrawerItems;
private ArrayList<DrawerItems> dataObjects;
private String[] mDrawerListItems;
private String[] mDrawerIcons;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    // to fetch the resources from the string files
    mDrawerListItems = getResources().getStringArray(
            R.array.nav_drawer_items);
    mDrawerIcons = getResources().getStringArray(R.array.nav_drawer_items);

    // drawerListAdapter = new DrawerListAdapter(this, mDrawerListItems);
    dataObjects = new ArrayList<DrawerItems>();
    for (int i = 0; i < mDrawerListItems.length; i++) {
        navigationDrawerItems = new DrawerItems();
        navigationDrawerItems.setIcnName(mDrawerListItems[i]);
        navigationDrawerItems.setIcnId(getResources().getIdentifier(
                mDrawerIcons[i], "drawable", this.getPackageName()));
        dataObjects.add(navigationDrawerItems);
    }

    drawerListAdapter = new DrawerListAdapter(this,
            R.layout.list_drawer_row_item, dataObjects);//add name of your layout
}

5) 现在你可以这样实现适配器

public class DrawerListAdapter extends ArrayAdapter {

private Context mContext;
private ArrayList<DrawerItems> mDataObjects;
private int layout;

public DrawerListAdapter(Context context, int resource,
        ArrayList<DrawerItems> dataObjects) {
    super(context, resource, dataObjects);
    mContext = context;
    mDataObjects = dataObjects;
    layout = resource;
}


@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder = null;

    if (convertView == null) {
        holder = new ViewHolder();
        LayoutInflater inflater = (LayoutInflater) mContext
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        convertView = inflater.inflate(layout, parent,
                false);

        holder.txtDrawerListItem = (TextView) convertView
                .findViewById(R.id.txt_drawer_item_name);
        holder.imgDrawerListIcon = (ImageView) convertView
                .findViewById(R.id.img_drawer_item_icon);

        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }

    final DrawerItems dataObj = mDataObjects.get(position);
    holder.txtDrawerListItem.setText(dataObj.getIcnName());
    holder.imgDrawerListIcon.setImageResource(dataObj.getIcnId());

    return convertView;
}

public static class ViewHolder {
    TextView txtDrawerListItem;
    ImageView imgDrawerListIcon;
}
}

6) 你已经准备就绪了...确保你已经初始化了视图和常用的东西


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