在Android上呈现动态表单的方法?

在Android上呈现动态表单的方法?,android,performance,android-layout,Android,Performance,Android Layout,我希望Android开发界的人以前遇到过这个问题/用例,并且有一个相对直接的实现方法 我有一个客户端Android应用程序,需要呈现最终用户填写的字段列表。每个字段都是特定的已知类型,例如“文本”或“无线电”、“多选择”等。当用户点击表单时,会向后端发出API调用,该后端返回该表单的模式(即:每个字段的UUID、标题、描述、提示文本等),以及该表单的数据,其中一些字段可能已经在以前填写过。我将通过API调用获取哪些数据的示例: { "submittedBy": 8, "updatedBy

我希望Android开发界的人以前遇到过这个问题/用例,并且有一个相对直接的实现方法

我有一个客户端Android应用程序,需要呈现最终用户填写的字段列表。每个字段都是特定的已知类型,例如“文本”或“无线电”、“多选择”等。当用户点击表单时,会向后端发出API调用,该后端返回该表单的模式(即:每个字段的UUID、标题、描述、提示文本等),以及该表单的数据,其中一些字段可能已经在以前填写过。我将通过API调用获取哪些数据的示例:

{
  "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)
    并“附加”该Java
    formElement
  • 将小部件放在我们刚刚膨胀的布局中,如果JSON中的
    字段映射中有相应的数据,则将数据设置为任意值。如果没有,请留空
  • 当用户点击“提交”时,抓取父窗体视图,并获取其子窗体。通过
    .getTag()
    循环遍历每个子级并拉出其
    FormElement
    。获取
    FormElement#getType
    以找到视图的类型,然后向后工作并了解我们正在迭代的视图,转换它,获取它的内部数据值,构建生成的JSON数据备份,然后将其放到API中
  • 我可能会根据模式
    中的UUID为每个表示数据输入点(文本、无线电等)的
    小部件
    分配一个唯一的ID(UUID是v1,因此一种方法是获取时间戳,希望最好,因为我们将从128位变为32位)。然后在用户点击Submit后需要取出数据时使用此ID

    Android的数据绑定库中似乎有一些很有前途的功能,但我认为Android的数据绑定无法处理这个UI布局的“动态”性质,不同的小部件具有不同的数据类型(其中一些是下拉菜单)

  • 数据绑定是一种更好的方法吗
  • 数据绑定能否处理在此处呈现UI以及帮助从该UI获取数据以最终合成API
    PUT
    请求返回服务器这两个问题
  • 到目前为止,我已经查看了一些资源,这些资源对这个总体问题有一定的帮助:

    • 用于根据预定义的XML添加/扩展UI
    • 这是一个非常好的技术讲座,涵盖了数据绑定的一些基础知识
    • .setTag()
      &
      .getTag()
      ——这似乎适合我的用例,我需要让视图“了解”自己的情况(比如它们在JSON响应中的来源)

    提前谢谢大家

    您应该在内存中创建这些字段的表示形式(如
    字段的
    集合
    )。
    然后您可以使用来有效地布局它们。
    在RecyclerView中,您可以拥有知道如何处理特定字段的视图类型(每个字段类型一个)。
    在RecyclerView中,要绑定视图,可以使用数据绑定。上有一个演示,演示了如何通过RecyclerView有效地使用数据绑定


    最后但并非最不重要的一点是,确保您的网络操作与UI完全解耦。UI只是读取集合,所以每次您执行网络请求时,它都会更新集合,并通知更改,RecycleView将自我更新。(您可能希望对收藏进行乐观的更新,因为网络请求可能需要时间,但这是一个很重要的话题。)

    谢谢yigit,我遵循了这一点,到目前为止还不错。我发现的唯一问题是,无法通过布局(XML)来“迭代”构建单个小部件(如RadioButton作为RadioGroup的一部分)。我解决这个问题的方法是将RadioGroup子类化,并尝试将数据绑定到该子类的小部件。让我知道你是怎么做的,我也在做同样的应用程序