我正在尝试构建一个复杂的表单,其中几乎所有元素都是可选的。它以一个字段和一个“添加元素”按钮开始。当您点击添加时,表单会显示一个 Spinner
,其中包含您可以添加到表单中的元素类型(位置、照片、详细注释、除“现在”之外的时间戳等)。当您选择一个项目时,它将启动一个Activity
,并且每个项目都有一个不同关联的Activity
。
此外,每个选择都会有几位数据,最好以某种方式“与”Activity
一起存储这些数据:
Spinner
中的图标和显示名称- 用于在数据库中存储数据(以及传递给网络服务)的 key
- 关于如何在原始表单上显示结果的布局(即照片的缩略图、位置的纬度/经度等)
我正在考虑一组类,它们都扩展了一个抽象的 FormElement
类,并且将为上述每个额外数据 fragment 提供静态元素。 (此解决方案的另一个障碍是静态上下文中的 Resources
有多痛苦。)
我怎样才能让它尽可能干净和可维护?我真的不喜欢编辑五个不同的文件来向这个表单添加新类型的元素。 (主要是因为我可以保证我会错过一个并花费数小时来追查错误。)
最佳答案
一些提示...
单元测试将防止“调试”:)
当每个
Activity
已经从用户那里获得了它需要的信息,调用Activity#setResult()用Intent
包含您的每种类型的数据。Intent
支持所有Bundle
方法,因此您可以根据需要设置不同类型的数据。要支持 #2,请确保您使用的是
Activity#startActivityForResult(Intent,int)
启动它,并在Activity#onActivityResult(int,Intent)
中收听结果我可能会维护可用“元素”类型的列表以用于
SpinnerAdapter
(例如ArrayList<Class<? extends AbstractFormElement>>
,并在适配器的.getDisplayName()
方法中调用.getActivityClass()
、getView()
等静态方法,以确定要显示的内容和启动的 Activity。这样,您的列表实际上将包含类似
{ MyPhotoElement.class, MyTextElement.class, MyDateElement.class, ...}
的内容).随着每个元素被添加到表单中,将其添加到
ArrayList<AbstractFormElement>
中,它将用于为ListView
支持另一个适配器.该适配器将调度自定义 View 布局的膨胀,以及 ViewHolder 的创建。 ,基于它是什么类型的对象——这将要求每个不同的AbstractFormElement
根据适配器,将有自己的“ View 类型”。参见 BaseAdapter#getItemViewType(int)及相关getViewTypeCount()
.值得注意的是,如果一个不能转换为另一个,则仅这些将需要不同的 View 类型...例如,如果您有两个“元素”,它们只需要显示一串列表中的文本,它们都可以共享“纯文本” View 类型。同样,仅显示照片或可以轻松将一个转换为另一个的两个元素(例如,带有标题的图标与没有标题的照片缩略图)可以共享一个“图像加标题” View 类型。
考虑到上述情况,您实际上最终不得不修改不同的文件以添加新类型(好吧,我想从技术上讲,您可以将它们全部放在一个文件中,作为内部类,但确实没有很好的论据这样做),但是如果你已经正确地完成了你的接口(interface) API,并遵循了良好的 OO 实践,并实现了良好的单元测试,你将大大减少查找错误所需的工作量——仅仅是因为大多数事情都涉及到如果操作不当,添加新类型实际上会导致编译器错误。除此之外,一个适当的单元测试套件将能够以编程方式添加所有可能的类型,并确保一切都正确显示,并且您应该有一个非常简化的过程以便于扩展:)
这听起来工作量很大,乍一看似乎很乏味和冗长...但最终结果实际上更易于维护,尤其是当您的元素类型列表将相当广泛时。
关于安卓模式 : A Spinner where every item launches a different Activity,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6337615/