2

我一直在我的一个应用程序中创建微调器控件(组合框/下拉菜单),并且惊讶地发现实现以下所有功能是多么困难:

  1. 面向用户的字符串被外部化,利用了 Android 的 strings.xml 国际化 (I18N) 功能。
  2. 微调器选择使用系统视图进行操作,这有助于不必使用字符串或将字符串映射到有意义的值 (yuck)。
  3. 用户视图到系统视图的映射应该简单、自动化和最小化(即不是为每个组件手动滚动)。

其他人已尝试解决此问题,但据我所知,他们普遍存在以下一个或多个问题:

  1. UI 代码正在蔓延到他们不属于那里的枚举类(混乱),几乎所有现有的解决方案都受此影响。
  2. 在其枚举类中硬编码面向用户的字符串。因为这些不是外部化的,所以您不能使用现有的 Android 功能进行 I18N。
  3. 作者通常将 Fragment 或 Activity 设为 OnItemSelectedListener,这会延续一个常见的继承问题,以方便使用,其中组合更合适。

我已经开发了自己的解决方案:http ://www.androidanalysis.com/android-spinner-externalize-user-strings-mapped-to-system-enum/

我的问题是,我错过了什么吗?这似乎不应该这么难(这让我觉得我可能正在重新发明轮子)。

下面是一些示例代码,显示了我正在使用的解决方案(可从上面的链接获得 Apache 2 许可证)。

String none = getString(R.string.none);
String light = getString(R.string.light);
String medium = getString(R.string.medium); 
String strong = getString(R.string.strong);
SpinnerUtil.createNewSpinner(view, R.id.wind, Arrays.asList(none, light, medium,     strong), WindLevel.values(),
  new SpinnerItemSelectedListener<WindLevel>() {
  public void onItemSelected(Spinner item, WindLevel value) {
    // Take whatever action you wish to here.
  }});
4

2 回答 2

1

我只会使用ArrayAdapter<WindLevel>. 是的,您创建了一个自定义类型的侦听器,但是常规事件侦听器获取position并可以调用getItem()ArrayAdapter<WindLevel>获取WindLevel正确的类型。

恕我直言,绝大多数Spinner小部件将填充从数据库、互联网或其他动态数据源读取的材料,而不是由某种枚举填充,其显示值来自可以提前国际化的静态字符串.

这并不是说您的代码毫无用处:如果您发现它有用,那么它就值得编写。而且我确信有一些应用程序包含您的目标模式(即,Spinner由枚举或等效模式支持,其中显示值是预先已知的并且可以国际化),他们可能会发现您的解决方案也很有用。每个编写足够代码的开发人员都会编写这些帮助类等,以帮助将操作系统或框架模型映射到更适合开发人员自己的心理模型的东西。只要您没有察觉到任何性能问题,一切都很好。

另外,请注意这OnItemSelectedListener是一个接口;在现有类上实现该接口不是继承。

于 2012-09-13T20:14:58.303 回答
0

我相信没有人回答你的原因是:

你想解决什么问题?在您精心设计的尝试之前,微调器就已经存在。

为什么要以与它们在 Android 中完全相同的方式重新发明它们? http://developer.android.com/guide/topics/ui/controls/spinner.html

它确实是你设计的一个漂亮的轮子,但它仍然只是一个轮子 :)

更新: 我想我开始明白你做了什么。这是有趣的。我不确定您为什么不使用 ListPreference 及其条目和条目值实现的模式。
事实上,我不确定我是否理解为什么 Android 团队也没有走这条路。

无论如何,向 Android 框架提出您的想法是值得的。毕竟是开源的。

于 2012-09-07T17:16:08.593 回答