在Android上呈现动态表单的方法?
我希望Android开发界的人以前遇到过这个问题/用例,并且有一个相对直接的实现方法 我有一个客户端Android应用程序,需要呈现最终用户填写的字段列表。每个字段都是特定的已知类型,例如“文本”或“无线电”、“多选择”等。当用户点击表单时,会向后端发出API调用,该后端返回该表单的模式(即:每个字段的UUID、标题、描述、提示文本等),以及该表单的数据,其中一些字段可能已经在以前填写过。我将通过API调用获取哪些数据的示例:在Android上呈现动态表单的方法?,android,performance,android-layout,Android,Performance,Android Layout,我希望Android开发界的人以前遇到过这个问题/用例,并且有一个相对直接的实现方法 我有一个客户端Android应用程序,需要呈现最终用户填写的字段列表。每个字段都是特定的已知类型,例如“文本”或“无线电”、“多选择”等。当用户点击表单时,会向后端发出API调用,该后端返回该表单的模式(即:每个字段的UUID、标题、描述、提示文本等),以及该表单的数据,其中一些字段可能已经在以前填写过。我将通过API调用获取哪些数据的示例: { "submittedBy": 8, "updatedBy
{
"submittedBy": 8,
"updatedBy": 8,
"createdBy": 8,
"submittedDateMillis": 1489680600000,
"updatedDateMillis": 1489680600000,
"createdDateMillis": 1489680600000,
"name": "My Form",
"formTemplateId": 3,
"id": 0,
"schema": {
"6051c1e3-b4bf-4e6a-afe3-de2497dbff11": {
"units": "ft.",
"hintText": "Length of measurement",
"required": false,
"description": "Take the length of the measured item to 4 decimal places.",
"title": "Measurement",
"type": "number"
},
"fdf6ff0b-e60d-4591-a3e7-5467cd7bc67e": {
"enum": [
"Foo",
"Bar",
"Baz",
"Bat"
],
"required": true,
"hintText": "",
"description": "This is a description for a multiple choice question",
"title": "Multiple Choice (radio) title",
"type": "radio"
},
"203ef6d8-03fe-48e8-9a45-b18d12721d44": {
"enum": [
"Option 1",
"Option 2",
"Option 3",
"Option 4"
],
"required": true,
"hintText": "",
"description": "This is the description for a multiselect question",
"title": "This is the title for a multiselect question",
"type": "multiselect"
},
"751e9b8f-a59d-4e81-b3da-17ae44daa44e": {
"enum": [
"A dropdown answer",
"This is another option for a dropdown question it's limit is 130 characters"
],
"required": true,
"hintText": "",
"description": "This is the description for a dropdown question",
"title": "This is the title for a dropdown question",
"type": "select"
},
"33e13828-9171-4680-b68b-9838d4d42af8": {
"required": true,
"hintText": "This is the hint text for a text question limit 130 characters",
"description": "This is the description for a text question limit 5000 characters",
"title": "This is the title for a text question limit 130 characters",
"type": "text"
}
},
"fields": {
"6051c1e3-b4bf-4e6a-afe3-de2497dbff11": "5555.5555",
"fdf6ff0b-e60d-4591-a3e7-5467cd7bc67e": "Bar",
"751e9b8f-a59d-4e81-b3da-17ae44daa44e": "A dropdown answer",
"203ef6d8-03fe-48e8-9a45-b18d12721d44": [
"Option 1",
"Option 2",
"Option 4"
],
"33e13828-9171-4680-b68b-9838d4d42af8": "My answer for your text question."
}
}
API调用(比如/API/v1/forms/0
)返回上述数据。因为我有描述字段类型的schema
,还有fields
,它们为我提供了要填充的答案(其中一些可能缺失)。它们都有“匹配”的UUID,所以我知道将哪些字段数据放入哪个表单字段
现在我必须呈现该表单,并允许用户点击“提交”和POST
/将新数据放回API
处理这个问题的方法是什么?我认为自己是Android的初学者,从我提出的到目前为止,可能不是最好的解决方案(而且可能不会超出50个问题,因为这个活动的“渲染”和“提交”部分将变得缓慢):
进行API调用,获取数据(上面的示例)
对于每一个模式
类型,.inflate()
一个XML布局,它是类型(数字
,文本
,无线电
,等等),和构造一个表示该模式JSON类型的Java类型(FormElement
就是我所称的)。在.inflate()
之后,.setTag(formElement)
并“附加”该JavaformElement
将小部件放在我们刚刚膨胀的布局中,如果JSON中的字段映射中有相应的数据,则将数据设置为任意值。如果没有,请留空
当用户点击“提交”时,抓取父窗体视图,并获取其子窗体。通过.getTag()
循环遍历每个子级并拉出其FormElement
。获取FormElement#getType
以找到视图的类型,然后向后工作并了解我们正在迭代的视图,转换它,获取它的内部数据值,构建生成的JSON数据备份,然后将其放到API中
我可能会根据模式
中的UUID为每个表示数据输入点(文本、无线电等)的小部件
分配一个唯一的ID(UUID是v1,因此一种方法是获取时间戳,希望最好,因为我们将从128位变为32位)。然后在用户点击Submit后需要取出数据时使用此ID
Android的数据绑定库中似乎有一些很有前途的功能,但我认为Android的数据绑定无法处理这个UI布局的“动态”性质,不同的小部件具有不同的数据类型(其中一些是下拉菜单)
PUT
请求返回服务器这两个问题- 用于根据预定义的XML添加/扩展UI
- 这是一个非常好的技术讲座,涵盖了数据绑定的一些基础知识
&.setTag()
——这似乎适合我的用例,我需要让视图“了解”自己的情况(比如它们在JSON响应中的来源).getTag()
提前谢谢大家 您应该在内存中创建这些字段的表示形式(如
字段的集合)。
然后您可以使用来有效地布局它们。
在RecyclerView中,您可以拥有知道如何处理特定字段的视图类型(每个字段类型一个)。
在RecyclerView中,要绑定视图,可以使用数据绑定。上有一个演示,演示了如何通过RecyclerView有效地使用数据绑定
最后但并非最不重要的一点是,确保您的网络操作与UI完全解耦。UI只是读取集合,所以每次您执行网络请求时,它都会更新集合,并通知更改,RecycleView将自我更新。(您可能希望对收藏进行乐观的更新,因为网络请求可能需要时间,但这是一个很重要的话题。)谢谢yigit,我遵循了这一点,到目前为止还不错。我发现的唯一问题是,无法通过布局(XML)来“迭代”构建单个小部件(如RadioButton作为RadioGroup的一部分)。我解决这个问题的方法是将RadioGroup子类化,并尝试将数据绑定到该子类的小部件。让我知道你是怎么做的,我也在做同样的应用程序