簡體   English   中英

在 ImageView 中獲取可繪制對象的 ID

[英]Get the ID of a drawable in ImageView

我有一個ImageView並在其上設置了一個 drawable。 現在我需要在ImageView點擊事件上動態獲取 drawable 的 ID。 我怎么才能得到它?

imgtopcolor = (ImageView) findViewById(R.id.topcolor); 
imgtopcolor.setImageResource(R.drawable.dr);  // How do I get this back?

現在在imgtopcolor觸摸事件上,我需要可繪制 id,因為我每次都設置不同的可繪制對象,並希望將可繪制對象與其他對象進行比較

我想如果我理解正確的話,這就是你在做什么。

ImageView view = (ImageView) findViewById(R.id.someImage);
view.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View view) {
        ImageView imageView = (ImageView) view;
        assert(R.id.someImage == imageView.getId());

        switch(getDrawableId(imageView)) {
            case R.drawable.foo:
                imageView.setDrawableResource(R.drawable.bar);
                break;
            case R.drawable.bar:
            default:
                imageView.setDrawableResource(R.drawable.foo);
            break;
        }
    });

對? 因此該函數getDrawableId()不存在。 您無法獲得實例化可繪制對象的 id,因為該 id 只是對設備上有關如何構造可繪制對象的數據位置的引用。 一旦構建了可繪制對象,它就無法取回用於創建它的 resourceId。 但是你可以使用標簽讓它像這樣工作

ImageView view = (ImageView) findViewById(R.id.someImage);
view.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View view) {
        ImageView imageView = (ImageView) view;
        assert(R.id.someImage == imageView.getId());

        // See here
        Integer integer = (Integer) imageView.getTag();
        integer = integer == null ? 0 : integer;

        switch(integer) {
        case R.drawable.foo:
            imageView.setDrawableResource(R.drawable.bar);
            imageView.setTag(R.drawable.bar);
            break;
        case R.drawable.bar:
        default:
            imageView.setDrawableResource(R.drawable.foo);
            imageView.setTag(R.drawable.foo);
            break;
        }
    });

我已經在另一個問題中回答了類似的問題,但會為這個問題稍微改變一下。

不幸的是,沒有getImageResource()getDrawableId() 但是,我通過使用 ImageView 標簽創建了一個簡單的解決方法。

在 onCreate() 中:

imageView0 = (ImageView) findViewById(R.id.imageView0);
imageView1 = (ImageView) findViewById(R.id.imageView1);
imageView2 = (ImageView) findViewById(R.id.imageView2);

imageView0.setTag(R.drawable.apple);
imageView1.setTag(R.drawable.banana);
imageView2.setTag(R.drawable.cereal);

然后,如果您願意,可以創建一個簡單的函數來獲取可繪制 ID:

private int getDrawableId(ImageView iv) {
    return (Integer) iv.getTag();
}

太容易了。

截至今天,尚不支持此功能。 但是,我發現了一個小技巧。

 imageView.setImageResource(R.drawable.ic_star_black_48dp);
 imageView.setTag(R.drawable.ic_star_black_48dp);

因此,如果您想獲取視圖的 ID,只需獲取它的標簽即可。

if (imageView.getTag() != null) {
   int resourceID = (int) imageView.getTag();

   //
   // drawable id.
   //   
}

一個簡單的解決方案可能是將 drawable id 存儲在一個臨時變量中。 我不確定這對您的情況有多實用,但這絕對是一個快速解決方案。

在 StackOverflow 上尋找類似問題的答案,我發現人們通常建議兩種方法:

  • 將可繪制對象加載到內存中,並將ConstantState或位圖本身與其他對象進行比較。
  • 將帶有可繪制 ID 的標簽設置到視圖中,並在需要時比較標簽。

就我個人而言,出於性能原因,我喜歡第二種方法,但用適當的標簽標記一堆視圖既痛苦又耗時。 這在大型項目中可能會非常令人沮喪。 就我而言,我需要編寫大量 Espresso 測試,這些測試需要比較TextView可繪制對象、 ImageView資源、 View背景和前景。 很多工作。

所以我最終想出了一個解決方案,將“骯臟”的工作委托給自定義充氣機。 在每個膨脹的視圖中,我都會搜索特定的屬性,並為視圖設置一個帶有資源 ID 的標簽(如果找到)。 這種方法與書法家使用的方法幾乎相同。 我為此編寫了一個簡單的庫: TagView

如果你使用它,你可以檢索任何預定義的標簽,包含在 xml 布局文件中設置的可繪制資源 ID:

TagViewUtils.getTag(view, ViewTag.IMAGEVIEW_SRC.id)
TagViewUtils.getTag(view, ViewTag.TEXTVIEW_DRAWABLE_LEFT.id)
TagViewUtils.getTag(view, ViewTag.TEXTVIEW_DRAWABLE_TOP.id)
TagViewUtils.getTag(view, ViewTag.TEXTVIEW_DRAWABLE_RIGHT.id)
TagViewUtils.getTag(view, ViewTag.TEXTVIEW_DRAWABLE_BOTTOM.id)
TagViewUtils.getTag(view, ViewTag.VIEW_BACKGROUND.id)
TagViewUtils.getTag(view, ViewTag.VIEW_FOREGROUND.id)

實際上,該庫支持任何屬性。 您可以手動添加它們,只需查看 Github 上的自定義屬性部分。 如果在運行時設置 drawable,則可以使用方便的庫方法:

setImageViewResource(ImageView view, int id)

在這種情況下,標記是在內部為您完成的。 如果您使用 Kotlin,您可以編寫一個方便的擴展來調用視圖本身。 像這樣的東西:

fun ImageView.setImageResourceWithTag(@DrawableRes int id) {
    TagViewUtils.setImageViewResource(this, id)
}

您可以在運行時標記中找到更多信息

我最近遇到了同樣的問題。 我通過實現我自己的 ImageView類來解決它。

這是我的Kotlin 實現

class MyImageView(context: Context): ImageView(context) {
    private var currentDrawableId: Int? = null

    override fun setImageResource(resId: Int) {
        super.setImageResource(resId)
        currentDrawableId = resId
    }

    fun getDrawableId() {
        return currentDrawableId
    }

    fun compareCurrentDrawable(toDrawableId: Int?): Boolean {
        if (toDrawableId == null || currentDrawableId != toDrawableId) {
            return false
        }

        return true
    }

}

更簡單:只需將R.drawable id 存儲在視圖的 id 中:使用v.setId() 然后用v.getId()取回它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM