为R.color使用字符串。“string”

时间:2013-12-18 21:16:01

标签: java android theming

有没有办法让以下脚本更有效? 我想让这段代码易于维护,这就是为什么我想摆脱if else if。 我希望你们能在这里帮助我。在底部是我想要看到的东西,如果可能的话那样。

     if (category.equals("infusion")){
        layout.setBackgroundResource(R.color.infusion);
            title.setText(R.string.title_infusion);             
     } else if (category.equals("pills")){
            layout.setBackgroundResource(R.color.pills);
            title.setText(R.string.title_pills);
     } else if (category.equals("pumps")){
            layout.setBackgroundResource(R.color.pumps);
            title.setText(R.string.title_pumps);
     } else if (category.equals("oxygen")){
            layout.setBackgroundResource(R.color.oxygen);
            title.setText(R.string.title_oxygen);
     } else if (category.equals("scores")){
            layout.setBackgroundResource(R.color.scores);
            title.setText(R.string.title_scores);
     } else if (category.equals("converters")){
            layout.setBackgroundResource(R.color.converters);
            title.setText(R.string.title_converters);
     }

这样的东西?

layout.setBackgroundResource(R.color.*category*);
title.setText(R.string.title_*category*);

6 个答案:

答案 0 :(得分:3)

我很确定你所做的所有“简化”操作都涉及到反思,并且最终可能会让你的代码更慢更难理解。你所拥有的是一种非常有效的方法来做这个设置,对读者来说非常清楚,并且不涉及任何奇怪的技术。

即。这有效,为什么修复它?

好的,编辑:

启动时,您可以通过哈希映射将String值映射到资源ID。

类似的东西:

HashMap map = new HashMap();
map.put("infusion",R.id.infusion);

然后是:

layout.setBackgroundResource(map.get(category));
title.setText(category);   

可能会工作,但同样不是真正的改进imo。

答案 1 :(得分:2)

签出Resources.getIndentifier()可以有一个帮助函数,如:

public static int resourceNameToId(Context context, String name, String resType) {
    if (name != null && name.length() > 0) {
        return context.getResources().getIdentifier(name, resType, context.getPackageName());
    }

    return 0;
}

然后使用它:

layout.setBackgroundResource(resourceNameToId(getContext(), category, "color"));

答案 2 :(得分:2)

您可以使用这样的枚举来保存您的值和颜色:

public enum ColorValue {

InFusion(android.R.color.black),
Pills(android.R.color.white);

int color;

ColorValue(int Value) {
    color = Value;
}

public int getColorResource() {
    return color;
}

} 

然后访问类似于此

的枚举值
 ColorValue x=ColorValue.InFusion;
 x.getColorResource();

答案 3 :(得分:0)

使用代码构造无法实现此目的。

使用类似:

layout.setBackgroundResource(getColorByCategory(category));
title.setText(getCategoryTitle(category));

其中getColorByCategory()getCategoryTitle()是您自己的功能。

答案 4 :(得分:0)

我可以通过两种方式思考问题。哈希映射和/或使用Resources对象。

有地图会涉及一些设置,如下:

private static final Map<String, Integer> COLOURS = new HashMap<String, Integer>();

static {
    COLOURS.put("pills", R.color.red);
    COLOURS.put("pumps", R.color.green);
}

然后以后很容易设置颜色:

layout.setBackgroundColor(COLOURS.get(category));

如果您所拥有的数据不能保证完美,您可能需要在设置之前检查地图中出现的颜色。

或者,您可以使用Resources对象,如下所示。

Resources resources = context.getResources();
resources.getColor(resources.get("colour_" + category, "color", context.getPackageName()));

答案 5 :(得分:0)

您可以使用枚举更有效地执行此操作:

(在你班上)声明

public enum Category {
    infusion (R.color.infusion, R.string.title_infusion, "infusion"),
    pills (R.color.pills, R.string.title_pills, "pills") //,
    //etc... comma-seperated values. Those are handled like any other enum
    ;
    public final int relatedBackground;
    public final String relatedTitle;
    public final String identifier; //To keep the identifiers you used previously

    private Category (int back, String title, String id) {
        this.relatedBackground = back;
        this.relatedTitle = title;
        this.identifier = id;
    }
}

你的方法看起来像这样:

public void foo(Category cat) { //You pass in your enum type
    //Do what you want
    if(cat != null) { //Avoid NullPointerException if necessary
        layout.setBackgroundResource(cat.relatedBackground); 
        title.setText(cat.relatedTitle);
    }
}

此方法是解决问题的好方法,因为您可以维护您通过添加新值来投影到逗号分隔列表。你也不需要担心每次从某个表中查找值

缺点是在运行时期间很难/ 无法调整枚举。因为枚举中的所有变量都必须是最终的,因为枚举本身不可修改,所以你不能做像

这样的事情。
cat.relatedbackground = someValue; // Can't do that: all fields are final

如果你想这样做,你将不得不使用extern表。除此之外,它是一个优秀的解决方案