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

时间:2017-04-05 17:30:30

标签: android performance android-layout

我希望Android开发领域的某个人之前遇到过这个问题/用例,并且有一个相对直接的实施方法。

我有一个客户端Android应用程序,需要呈现最终用户随后填写的字段列表。每个字段都是某种已知类型,例如" Text"或" Radio"," MultiSelect"等。当用户点击表单时,会对后端进行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 / PUT新数据发回API。

处理此问题的方法是什么?我认为自己是Android的初学者,从目前为止我提出的可能不是最好的解决方案(并且可能不会超出50个问题,因为"渲染& #34;以及"提交"此活动的某些部分将变慢:

  1. 进行API调用,获取数据(上例)。
  2. 对于每个schema类型,.inflate()一个XML布局,即.typenumbertextradio等等),构造一个表示该模式JSON类型的Java类型(FormElement就是我所谓的)。在.inflate()之后,.setTag(formElement)和"附加"那个Java FormElement就可以了。
  3. 在我们刚刚膨胀的布局中获取窗口小部件,如果我们从JSON中的fields映射中获得相应的数据,请将数据设置为任何内容。如果没有,请留空。
  4. 当用户点击"提交"时,抓住父表单视图,并获取它的孩子。循环遍历每个孩子,并通过FormElement取出.getTag()。获取FormElement#getType以查找视图的类型,然后向后工作并了解我们正在迭代的视图,投射它,获取它的内部数据值,构建生成的JSON数据,以及{ {1}}到API。
  5. 我可能会根据PUT中的UUID(UUID是v1),为表示数据入口点(文本,广播等)的每个Widget分配一个唯一ID,因此一种方法是得到时间戳,并希望最好,因为我们将从128位转到32位)。然后在我需要在用户点击提交后拉出数据时使用此ID。

    在Android的数据绑定库中看起来有一些很有前景的功能,但我不认为Android的数据绑定可以处理动态""布局此UI的性质,使用具有不同数据类型的不同窗口小部件(其中一些是下拉菜单)。

    1. 数据绑定是一种更好的方法吗?
    2. 数据绑定可以处理两者在此处呈现UI的问题,帮助从该UI获取数据,最终将我的API schema请求重新组合回服务器?
    3. 我到目前为止看过的资源,它们对这个整体问题有所了解:

      提前谢谢大家!

1 个答案:

答案 0 :(得分:1)

您应该在内存中创建这些字段的表示(例如Collection的{​​{1}})。 然后,您可以使用RecyclerView有效地布局它们。 在RecyclerView中,您可以拥有知道如何处理特定字段的视图类型(每个字段类型一个)。 在RecyclerView内部,要绑定视图,可以使用数据绑定。 github上有一个演示,演示如何有效地使用与RecyclerView的数据绑定。

最后但并非最不重要的是,确保您的网络操作与UI完全分离。 UI只读取集合,因此每次执行网络请求时,它都会更新集合,通知更改,RecyclerView将自行更新。 (您可能希望对集合进行乐观更新,因为网络请求可能需要一些时间,但这是一个很大的主题。)