代码之家  ›  专栏  ›  技术社区  ›  Jan MalouÅ¡ek

将图标与Arralist关联的最佳实践?

  •  0
  • Jan MalouÅ¡ek  · 技术社区  · 7 年前

    我的android应用程序中有一组cca 50运动图标,我需要有一个函数,我将运动名称交给该函数,该函数返回运动图标。

    现在我这样处理这个问题:

    public static int getSportIcon(String sport){
        if(sport != null) {
            switch (sport) {
                case "Swimming": {
                    return R.drawable.swimming;
                }
                case "Bicycling": {
                    return R.drawable.bicycling;
                }
                case "Football": {
                    return R.drawable.football;
                }
                case "Badminton": {
                    return R.drawable.badminton;
                }
                case "Hockey": {
                    return R.drawable.hockey;
                }
                case "Skiing": {
                    return R.drawable.skiing;
                }
                case "TableTennis": {
                    return R.drawable.table_tennis;
                }
                case "Tennis": {
                    return R.drawable.tennis;
                }
                case "Volleyball": {
                    return R.drawable.volleyball;
                }
                case "Basketball":
                    return R.drawable.basketball;
                default: {
                    return R.drawable.ic_android_black_24dp;
                }
            }
        }
        else {
            return R.drawable.ic_android_black_24dp;
        }
    }
    

    有更好的方法吗?

    谢谢

    3 回复  |  直到 7 年前
        1
  •  2
  •   Martin Zeitler    7 年前

    还可以定义关联 String & Drawable 在里面 array.xml 同样地链接字符串更方便,否则需要为每种语言维护这些数组。可以选择添加 name="" 属性到 item 节点(该字符串在任何语言中都是相同的,它只支持按名称查找,而不是按索引查找)。

    <string-array name="sports_string">
        <item>@string/swimming</item>
        <item>@string/bicycling</item>
        <item>@string/football</item>
        <item>@string/badminton</item>
        <item>@string/hockey</item>
        <item>@string/skiing</item>
        <item>@string/table_tennis</item>
        <item>@string/tennis</item>
        <item>@string/volleyball</item>
        <item>@string/basketball</item>
    </string-array>
    
    <string-array name="sports_drawable">
        <item>@drawable/swimming</item>
        <item>@drawable/bicycling</item>
        <item>@drawable/football</item>
        <item>@drawable/badminton</item>
        <item>@drawable/hockey</item>
        <item>@drawable/skiing</item>
        <item>@drawable/table_tennis</item>
        <item>@drawable/tennis</item>
        <item>@drawable/volleyball</item>
        <item>@drawable/basketball</item>
    </string-array>
    

    甚至可以引用整个数组 <item>@array/swimming</item> ,这样每个项目可以有一个数组,这可能是最方便的,因此它将成为:

    <string-array name="swimming">
        <item name="title">@string/swimming</item>
        <item name="icon">@drawable/swimming</item>
    </string-array>
    ...
    <string-array name="sports">
        <item>@array/swimming</item>
        <item>@array/bicycling</item>
        <item>@array/football</item>
        <item>@array/badminton</item>
        <item>@array/hockey</item>
        <item>@array/skiing</item>
        <item>@array/table_tennis</item>
        <item>@array/tennis</item>
        <item>@array/volleyball</item>
        <item>@array/basketball</item>
    </string-array>
    

    为了将这些关联数组指定给 BaseAdapter 。。。

    public class SomeAdapter extends BaseAdapter {
        private ArrayList<SomeItem> mItems = new ArrayList<>();
        public SomeAdapter(Context context, @ArrayRes int strings, @ArrayRes int drawables) {
    
            /* these TypedArray hold the relevant resource ids */
            TypedArray resString = context.getResources().obtainTypedArray(strings);
            TypedArray resDrawable = context.getResources().obtainTypedArray(drawables);
    
            /* check if both TypedArray have the same length. */
            if(resString.length() != resDrawable.length()) {return false;}
    
            /* populate this.mItems in a loop,  whatever type these items may have. */
            for (int i=0; i < resString.length(); i++) {
    
                /* checking if there is a resource */
                int resIdTitle = resString.getResourceId(i, -1);
                if (resIdTitle < 0) {continue;}
    
                int resIdIcon = resDrawable.getResourceId(i, -1);
                if (resIdIcon < 0) {continue;}
    
                ...
            }
    
            /* TypedArray needs to be recycled */
            resString.recycle();
            resDrawable.recycle();
        }
    }
    

    假设一个数组可以直接分配给 AppCompatSpinner 在XML中,但当有多个输入数组或输入数组有多个维度时,为了转换为所需类的对象,必须以某种方式对其进行处理-使用备用数组结构(使用 @array 引用),只需嵌套循环,但其工作原理大致相同。

    访问 TypedArray 只有一次,例如,在实例化适配器时,可能比按名称查找每一项要快(因为这些方法很可能只是加载、扫描,而且必须在内部进行循环)-因此 .getIdentifier() 对于单个资源查找似乎很有用,以便转换 name 把某事归因于某人 resId

        2
  •  1
  •   Gabe Sechan    7 年前
    int id = context.getResources().getIdentifier(sport.toLowerCase(), "drawable", context.getPackageName());
    

    这将获得一个具有匹配字符串名称的drawable。我会把结果缓存在某个地方,这样你就不必经常使用它(这不是最快的函数,尤其是在绘图时使用)。

        3
  •  -1
  •   Younes Ben Tlili    7 年前

    您可以从字符串和drawables创建列表。然后按索引设置每个图标。

     <string-array name="list_menu">
        <item>title1</item>
        <item>title2</item>
        <item>title3</item></<string-array >
    
      <integer-array name="icons_menus">
        <item>@drawable/title1</item>
        <item>@drawable/title2</item>
        <item>@drawable/title3</item></integer-array>