有没有办法找到可绘制资源的资源ID?

27

有没有办法获取Drawable资源的ID?例如,我正在使用一个ImageView,可能最初使用icon.png作为它的图像,但后来可能会将图像更改为icon2.png。我想通过代码找出我的ImageView正在使用哪个资源的图像。有没有办法?


2
可能是为什么没有从Drawable对象获取资源名称的方法的重复问题。 - CommonsWare
我不确定你的意思。为什么不能回到代码中并进行更改呢? - ahodder
1
@AedonEtLIRA: 我的意思是,我有一个带有播放图像的ImageView,但是当我滑动行时,播放图像会变成删除图像。因此,根据当前设置的图像,我想执行操作。这就是为什么我想知道正在使用什么图像,以便可以相应地执行操作。有任何线索吗??? - Farhan
7个回答

16

当您在程序中点击ImageView时,这是找出R.drawable.img1值的最佳方法。该方法类似于主程序中的以下操作。首先像这样将图像值保存在标签中。

public...activity 
{
    //-----this resource name is retrieved through the tag value of the drawable of (touched) ImageView //image ontouchlistener event...
    ImageView imgview1.setTag("img1"); //as of R.drawable.img1
    ImageView imgview2.setTag("img2"); //as of R.drawable.img2

    onTouchListnener event... on imageView
    {    
        Object tag = imageView.getTag();                    
        int id = getResources().getIdentifier( tag, "drawable", this.getPackageName() );
        switch(id)
        {
            case R.drawable.img1:
                //do someoperation of ur choice
                break;
            case R.drawable.img2:
                //do someoperation of ur choice
                break:
        }//end of switch

    }//end of touch listener event

}//end of main activity

"PIR FAHIM SHAH/kpk uet mardan campus"


7
您是否试图确定ImageView上的当前图像,以便将其更改为其他图像?如果是这样,我建议您使用代码而不是XML完成所有操作。即在初始化期间使用setImageResource()设置初始图像,并在代码的某个位置跟踪使用的resource id。例如,您可以有一个ImageViews数组和一个相应的包含每个ImageViewresource idint数组。然后,每当您想要更改图像时,请循环遍历该数组并查看id是什么。

1
我正在尝试编写一个测试来确定设置在ImageView上的可绘制资源的资源ID,你知道有什么解决方案吗? - Kevin Crain

5
创建自定义ImageView,其余部分很简单。
public class CustomImageView extends ImageView {

    private int resID;

    public CustomImageView(Context context) {
        super(context);
    }

    public CustomImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CustomImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public void setImageResource(int resId) {
        this.resID = resId;
        super.setImageResource(resId);
    }

    public int getResourceId() {
        return resID;
    }
}

0

我知道这个问题已经很老了,但也许有人会觉得它有用。

我有一个带有Drawable的TextView列表,并希望为它们所有设置点击监听器,而无需在布局更改时更改代码。

因此,我将所有的drawable放入哈希映射中,以便稍后获取它们的ID。

main_layout.xml

<LinearLayout android:id="@+id/list" >

    <TextView android:drawableLeft="@drawable/d1" />
    <TextView android:drawableLeft="@drawable/d2" />
    <TextView android:drawableLeft="@drawable/d3" />
    <TextView android:drawableLeft="@drawable/d4" />
    <!-- ... -->
</LinearLayout>

MyActivity.java

import java.lang.reflect.Field;
import java.util.HashMap;

import android.app.Activity;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Drawable.ConstantState;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.LinearLayout;
import android.widget.TextView;

public class MyActivity extends Activity {

    private final HashMap<ConstantState, Integer> drawables = new HashMap<ConstantState, Integer>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.main_layout);

        for (int id : getAllResourceIDs(R.drawable.class)) {
            Drawable drawable = getResources().getDrawable(id);
            drawables.put(drawable.getConstantState(), id);
        }

        LinearLayout list = (LinearLayout)findViewById(R.id.list);

        for (int i = 0; i < list.getChildCount(); i++) {

            TextView textView = (TextView)list.getChildAt(i);       
            setListener(textView);

        }
    }

    private void setListener(TextView textView) {

        // Returns drawables for the left, top, right, and bottom borders.
        Drawable[] compoundDrawables = textView.getCompoundDrawables();

        Drawable left = compoundDrawables[0];

        final int id = drawables.get(left.getConstantState());

        textView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {

                Intent broadcast = new Intent();

                broadcast.setAction("ACTION_NAME");

                broadcast.putExtra("ACTION_VALUE", id);

                sendBroadcast(broadcast);
            }
        });
    }

    /**
     * Retrieve all IDs of the Resource-Classes
     * (like <code>R.drawable.class</code>) you pass to this function.
     * @param aClass : Class from R.X_X_X, like: <br>
     * <ul>
     * <li><code>R.drawable.class</code></li>
     * <li><code>R.string.class</code></li>
     * <li><code>R.array.class</code></li>
     * <li>and the rest...</li>
     * </ul>
     * @return array of all IDs of the R.xyz.class passed to this function.
     * @throws IllegalArgumentException on bad class passed.
     * <br><br>
     * <b>Example-Call:</b><br>
     * <code>int[] allDrawableIDs = getAllResourceIDs(R.drawable.class);</code><br>
     * or<br>
     * <code>int[] allStringIDs = getAllResourceIDs(R.string.class);</code>
     */
    private int[] getAllResourceIDs(Class<?> aClass) throws IllegalArgumentException {
            /* Get all Fields from the class passed. */
            Field[] IDFields = aClass.getFields();

            /* int-Array capable of storing all ids. */
            int[] IDs = new int[IDFields.length];

            try {
                    /* Loop through all Fields and store id to array. */
                    for(int i = 0; i < IDFields.length; i++){
                            /* All fields within the subclasses of R
                             * are Integers, so we need no type-check here. */

                            // pass 'null' because class is static
                            IDs[i] = IDFields[i].getInt(null);
                    }
            } catch (Exception e) {
                    /* Exception will only occur on bad class submitted. */
                    throw new IllegalArgumentException();
            }
            return IDs;
    }

}

我从这里使用了getAllResourceIDs方法。


0

这需要几个步骤:

  1. 创建一个integer-array的xml文件来保存drawable的名称(例如:"@drawable/icon1" … "@drawable/iconN")

  2. 使用上面的getIdentifier方法获取“array”的ID

  3. 有了drawable列表的ID,使用getStringArray方法将为您提供在步骤1中指定的drawable名称的数组。

  4. 然后再次使用getIdentifier中的任何一个drawable名称来获取drawable ID。 这里使用“drawable”而不是“array”类型。

  5. 使用此ID为您的视图设置图像。

希望这能有所帮助。


0
另一种方法是:您只需要创建自己的定制视图和onCreate。然后迭代AttributeSet对象(attrs)以查找您属性的索引。然后只需使用索引调用getAttributeResourceValue,然后您将获得初始ResouceID值。一个简单的示例是扩展ImageView以获取背景的ResourceID:
public class PhoneImageView extends ImageView {

    private static final String BACKGROUND="background";
    private int imageNormalResourceID;

    public PhoneImageView(Context context) {
        super(context);
    }

    public PhoneImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
        for (int i = 0; i <attrs.getAttributeCount() ; i++) {
            if(attrs.getAttributeName(i).equals(BACKGROUND)){
                imageNormalResourceID =attrs.getAttributeResourceValue(i,-1);
            }
        }
    }

    public PhoneImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }


}

这种方法适用于想要存储初始值的人。Bojan Kseneman提供的解决方案(+1票)是在视图更改时保持对资源ID的引用。


-4

您可以通过以下代码,根据名称获取图像的ID。

int drawableImageId = getResources().getIdentifier(imageName,"drawable", getPackageName());

我不能使用上面的方法,因为我不想使用imageName..因为imageName就是我要找的。获取资源部分中图像的ID并不是问题。问题是如何知道当前正在使用的图像..希望你能理解我的问题..有人能帮忙吗? - Farhan
你尝试过像下面这样吗?imageView.getId() 这里的imageView是你的ImageView类的对象引用。 - Senthil Mg

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