将上下文传递给枚举。我的解决方案是否正确?

时间:2016-06-07 11:11:42

标签: android enums

我想使用字符串资源(用于本地化)使用枚举填充微调器。 这是我的测试解决方案:

MyEnum.java:

enum MyEnum {
    FRENCH(R.string.french, new double[] {0.1, 0.2, 0.3}, "French"),
    ENGLISH(R.string.english, new double[] {0.2, 0.3, 0.1}, "English"),
    SPANISH(R.string.spanish, new double[] {0.5, 0.5, 0.5}, "Spanish"),
    ITALIAN(R.string.italian, new double[] {0.6, 0.6, 0.6}, "Italian");

    private final int mResourceId;
    private final double[] mTruc;
    private final String mDefault;

    private static Context sContext;

    private MyEnum(final int id, final double[] truc, final String def) {
        mResourceId = id;
        mTruc = truc;
        mDefault = def;
    }

    static void setContext(final Context context) {
        Log.d(MainActivity.TAG, "setContext 0");
        sContext = context;
        Log.d(MainActivity.TAG, "setContext 1");
    }

    @Override
    public String toString() {
        if (sContext != null) {
            return sContext.getString(mResourceId);
        } else {
            return mDefault;
        }
    }

    double[] getTruc() {
        return mTruc;
    }
}

MainActivity.java:

public class MainActivity extends AppCompatActivity {
    private TextView mTextView;

    protected static final String TAG = "SPINNER";

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

        setContentView(R.layout.activity_main);

        final Spinner spinner = (Spinner) findViewById(R.id.spinner);
        mTextView = (TextView) findViewById(R.id.textview);

        spinner.setAdapter(new ArrayAdapter<MyEnum>(this, android.R.layout.simple_spinner_item, MyEnum.values()));

        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(final AdapterView<?> parent, final View view, final int position, final long id) {
                MyEnum myEnum = (MyEnum) spinner.getSelectedItem();
                String truc = "";
                for (double d : myEnum.getTruc()) {
                    truc += d + " ";
                }
                mTextView.setText(myEnum.toString() + " " + truc);
            }

            @Override
            public void onNothingSelected(final AdapterView<?> parent) {
            }
        });
    }
}

的strings.xml:

<resources>
    <string name="app_name">TestSpinner</string>
    <string name="french">French</string>
    <string name="english">English</string>
    <string name="spanish">Spanish</string>
    <string name="italian">Italian</string>
</resources>

FR / strings.xml中:

<resources>
    <string name="app_name">TestSpinner</string>
    <string name="french">Français</string>
    <string name="english">Anglais</string>
    <string name="spanish">Espagnol</string>
    <string name="italian">Italien</string>
</resources>

经过多次测试,它似乎按预期工作。 我的解决方案是正确的,没有内存泄漏,你可以找到其他解决方案吗?

感谢。

2 个答案:

答案 0 :(得分:1)

嗯,存在潜在的内存泄漏。

static void setContext(final Context context) {
    Log.d(MainActivity.TAG, "setContext 0");
    sContext = context;
    Log.d(MainActivity.TAG, "setContext 1");
}

存储活动的上下文是个坏主意。如果你真的必须通过简单地调用context.getApplicationContext()来保存应用程序上下文。但话又说回来,你想用这个设置完成什么?我的意思是这个枚举似乎有点破碎了。是可变的,我认为应该在其他地方完成。

除了字符串之外,还有string-arrays可以用于语言。然后这些可以馈送到适配器。

答案 1 :(得分:0)

最后,我使用了一个自定义的ArrayAdapter,枚举只给出了资源ID。

编辑:对dropDownView使用simple_spinner_dropdown_item.xml。

这里是MyEnumArrayAdapter.java:

class MyEnumArrayAdapter extends ArrayAdapter<MyEnum> {
    private final MyEnum[] mMyEnum;

    public MyEnumArrayAdapter(final Context context, final MyEnum[] data) {
        super(context, android.R.layout.simple_spinner_item, data);
        mMyEnum = data;
    }

    @Override
    public View getView(final int position, final View convertView, final ViewGroup parent) {
        return initView(position, convertView, parent, android.R.layout.simple_spinner_item);
    }

    @Override
    public View getDropDownView(final int position, final View convertView, final ViewGroup parent) {
        return initView(position, convertView, parent, android.R.layout.simple_spinner_dropdown_item);
    }

    private View initView(final int position, final View convertView, final ViewGroup parent, final int layout) {
        View row = convertView;
        final ViewHolder viewHolder;
        final Context context = getContext();

        if (row == null) {
            final LayoutInflater inflater = LayoutInflater.from(context);
            row = inflater.inflate(layout, parent, false);

            viewHolder = new ViewHolder();
            viewHolder.textView = (TextView) row.findViewById(android.R.id.text1);
            row.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) row.getTag();
        }
        final MyEnum item = mMyEnum[position];
        viewHolder.textView.setText(context.getText(item.getResourceId()));
        return row;
    }

    private static class ViewHolder {
        TextView textView;
    }
}

我的新MyEnum.java:

enum MyEnum {
    FRENCH(R.string.french, new double[] {0.1, 0.2, 0.3}),
    ENGLISH(R.string.english, new double[] {0.2, 0.3, 0.1}),
    SPANISH(R.string.spanish, new double[] {0.5, 0.5, 0.5}),
    ITALIAN(R.string.italian, new double[] {0.6, 0.6, 0.6});

    private final int mResourceId;
    private final double[] mTruc;

    private MyEnum(final int id, final double[] truc) {
        mResourceId = id;
        mTruc = truc;
    }

    int getResourceId() {
        return mResourceId;
    }

    double[] getTruc() {
        return mTruc.clone();
    }
}

MainActivity.java的一部分:

final MyEnumArrayAdapter adapter = new MyEnumArrayAdapter(this, MyEnum.values());
spinner.setAdapter(adapter);

这个解决方案更好吗? 感谢。