· 6 years ago · Sep 02, 2019, 11:50 PM
1class FormFragment : Fragment() {
2
3 private val section by lazy { arguments!!.getParcelable<Section>(SECTION) }
4 private val fieldInputs = mutableListOf<FieldInput>()
5
6 override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
7 val view = inflater.inflate(R.layout.form_section_fragment, container, false)
8 return view
9 }
10
11 override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
12 super.onViewCreated(view, savedInstanceState)
13 renderFields(view)
14 }
15
16 // This is the method which does the magic
17 private fun renderFields(view: View) {
18 val formContainer = view.findViewById<LinearLayout>(R.id.formContainer)
19
20 //We iterate through each field and decide which component it corresponds to.
21 //All of these components created by ourselves must follow the same interface, which is FieldInput<T>
22 section.fields.forEach {
23 val fieldInput: FieldInput = when(it.type) {
24 FieldType.TEXT -> { TextInput(requireContext()) }
25 FieldType.DATE -> { DateInput(requireContext()) }
26 else -> {
27 throw IllegalStateException("unknown type")
28 }
29 }
30
31 //we must set a key to each field so we send it back to the api as a map of the key and the value inserted
32 fieldInput.apply {
33 key = it.key
34 setLabel(it.label)
35 }
36
37 //Then we add this field to the list of the fields, so we can validate all of them and get their values
38 fieldInputs.add(fieldInput)
39
40 //Our view only as a linear layout to hold the fields and place them one on each line
41 formContainer.addView(fieldInput as View)
42 }
43 }
44
45 companion object {
46 const val SECTION = "section"
47
48 fun newInstance(section: Section): FormFragment {
49 val fragment = FormFragment()
50 val bundle = Bundle().apply {
51 putParcelable(SECTION, section)
52 }
53 fragment.arguments = bundle
54 return fragment
55 }
56 }
57}