首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Android 循環動態設置多個 ImageView 圖片資源的反射方案

     編輯:程式設計綜合問答

問題

R.drawable.image1 是 int 常量,無法直接用字符串拼接 "image"+i 獲取。

方案對比

方案優點缺點
反射獲取 R.drawable 字段代碼少、無需改動資源命名反射較慢、混淆後字段名變更失效
資源名數組映射無反射、編譯期安全、支持混淆需手動維護數組
getResources().getIdentifier()API 簡單、支持動態包名比反射更慢、不推薦高頻調用

推薦:資源名數組映射(最佳性能與穩定性)

// 1. 定義資源 ID 數組(編譯期常量,無反射)
private static final int[] IMG_RES = {
    R.drawable.image1, R.drawable.image2, R.drawable.image3,
    R.drawable.image4, R.drawable.image5 /*, ... */ 
};
private static final int[] IMG_VIEW_ID = {
    R.id.imageView1, R.id.imageView2, R.id.imageView3,
    R.id.imageView4, R.id.imageView5
};

// 2. 循環設置
for (int i = 0; i < IMG_RES.length; i++) {
    ImageView iv = findViewById(IMG_VIEW_ID[i]);
    if (iv != null) {
        iv.setImageResource(IMG_RES[i]);
    }
}

若必須用反射(資源名動態生成)

for (int i = 1; i <= 5; i++) {
    try {
        // 獲取 drawable 字段
        Field drawableField = R.drawable.class.getField("image" + i);
        int resId = drawableField.getInt(null); // static 字段傳 null
        
        // 獲取 id 字段
        Field idField = R.id.class.getField("imageView" + i);
        int viewId = idField.getInt(null);
        
        ImageView iv = findViewById(viewId);
        if (iv != null) iv.setImageResource(resId);
    } catch (Exception e) {
        Log.w("IMG", "Resource not found for index " + i, e);
    }
}

混淆保護規則

-keepclassmembers class **.R$* {
    public static <fields>;
}
-keep class **.R$drawable { *; }
-keep class **.R$id { *; }

**能用數組映射絕不反射**。反射僅作為「資源名完全動態(如服務端下發)」的最後手段。數組映射編譯期檢查、運行期零開銷、混淆友好,是工程標準解法。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved