如何在Android中使用API创建具有输入验证的动态EditText。

huangapple go评论50阅读模式
英文:

How create dynamic edittext from using api with input validation in android

问题

我需要从API在Android中生成动态输入字段。我还需要添加适当的输入验证,如不能为空、有效数字等,以及提交按钮。我尝试生成下面图片中的文本字段:

如何在Android中使用API创建具有输入验证的动态EditText。

我的API JSON如下:

{
    "fields": [
        {
            "code": "ACCT_NO",
            "type": "textbox",
            "required": true,
            "default_value": null,
            "options": null,
            "regex": "^[0-9]*$",
            "config": null,
            "label": "Enter Account No:"
        },
        {
            "code": "AMNT",
            "type": "textbox",
            "required": true,
            "default_value": null,
            "options": null,
            "regex": "^[0-9]*$",
            "config": null,
            "label": "Enter Amount:"
        },
        {
            "code": "ADD_MSISDN",
            "type": "textbox",
            "required": false,
            "default_value": null,
            "options": null,
            "regex": null,
            "config": null,
            "label": "Additional MSISDN (Optional):"
        }
    ]
}

以下是用于生成输入文本字段的XML代码(input_field_layout.xml):

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.cardview.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:layout_marginBottom="8dp"
        android:layout_marginStart="5dp"
        android:layout_marginEnd="5dp"
        android:elevation="8dp"
        android:background="#FFFFFF"
        tools:ignore="MissingConstraints">

        <com.google.android.material.textfield.TextInputLayout
            android:id="@+id/textInputLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingStart="8dp"
            android:paddingEnd="8dp"
            android:paddingTop="16dp"
            android:paddingBottom="16dp">

            <com.google.android.material.textfield.TextInputEditText
                android:id="@+id/textInputEditText"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textColorHint="#9E9E9E"
                android:maxLines="1"
                android:inputType="text"
                android:textSize="16sp" />

        </com.google.android.material.textfield.TextInputLayout>
    </androidx.cardview.widget.CardView>

</androidx.constraintlayout.widget.ConstraintLayout>

以下是活动XML代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/containerLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
</LinearLayout>

以下是生成字段的代码:

fun populateFields(fields: List<Field>) {
    val inflater = LayoutInflater.from(this)
    for (x in fields) {
        if (x.type == "textbox") {
            val inputFieldLayout = inflater.inflate(R.layout.input_field_layout, containerLayout, false)
            val textInputLayout = inputFieldLayout.findViewById<TextInputLayout>(R.id.textInputLayout)
            val textInputEditText = inputFieldLayout.findViewById<TextInputEditText>(R.id.textInputEditText)
            textInputEditText.inputType = InputType.TYPE_CLASS_TEXT
            textInputLayout.hint = x.label
            if (x.required) {
                if (x.regex != null && x.regex != "") {
                    val regexPattern = x.regex
                    textInputEditText.addTextChangedListener(object : TextWatcher {
                        override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}

                        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}

                        override fun afterTextChanged(s: Editable?) {
                            val value = s.toString()
                            val isValid = value.matches(Regex(regexPattern))
                            if (isValid) {
                                // 有效输入
                                textInputLayout.error = null
                            } else {
                                // 无效输入
                                textInputLayout.error = "无效输入"
                            }
                        }
                    })
                }
            }
            containerLayout.addView(inputFieldLayout)
        }
    }
}

以下是提交按钮的代码:

btnNext.setOnClickListener {
    Log.e("btnNext---","btnNext")
    val fieldValues = mutableMapOf<Int, String>()

    for (editText in editTextList) {
        val value = editText.text.toString()
        val fieldId = editText.id
        fieldValues[fieldId] = value

        Log.e("fieldId-",fieldId.toString())
        Log.e("value-",value.toString())
    }
}

如何将JSON中的字段ID设置为文本字段,该字段在JSON中定义为 "code": "ACCT_NO"?

如何在提交下一步按钮时验证输入字段是否为空或不为空以及其他验证?

英文:

I need to generate dynamic input fields from API in Android. I also need to add proper input validation submit button like not empty, valid number so on. I have tried to generate the text field below like image:

如何在Android中使用API创建具有输入验证的动态EditText。

My API JSON is below:

  fields&quot;: [
                {
                    &quot;code&quot;: &quot;ACCT_NO&quot;,
                    &quot;type&quot;: &quot;textbox&quot;,
                    &quot;required&quot;: true,
                    &quot;default_value&quot;: null,
                    &quot;options&quot;: null,
                    &quot;regex&quot;: &quot;^[0-9]*$&quot;,
                    &quot;config&quot;: null,
                    &quot;label&quot;: &quot;Enter Account No:&quot;
                },
                {
                    &quot;code&quot;: &quot;AMNT&quot;,
                    &quot;type&quot;: &quot;textbox&quot;,
                    &quot;required&quot;: true,
                    &quot;default_value&quot;: null,
                    &quot;options&quot;: null,
                    &quot;regex&quot;: &quot;^[0-9]*$&quot;,
                    &quot;config&quot;: null,
                    &quot;label&quot;: &quot;Enter Amount:&quot;
                },
                {
                    &quot;code&quot;: &quot;ADD_MSISDN&quot;,
                    &quot;type&quot;: &quot;textbox&quot;,
                    &quot;required&quot;: false,
                    &quot;default_value&quot;: null,
                    &quot;options&quot;: null,
                    &quot;regex&quot;: null,
                    &quot;config&quot;: null,
                    &quot;label&quot;: &quot;Additional MSISDN (Optional):&quot;
                }
            ]

Here is my XML code named input_field_layout.xml for generate input textfield:

            &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
        &lt;androidx.constraintlayout.widget.ConstraintLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
            xmlns:tools=&quot;http://schemas.android.com/tools&quot;

            android:layout_width=&quot;match_parent&quot;
            android:layout_height=&quot;match_parent&quot;&gt;

            &lt;androidx.cardview.widget.CardView
                android:layout_width=&quot;match_parent&quot;
                android:layout_height=&quot;wrap_content&quot;
                android:layout_marginTop=&quot;8dp&quot;
                android:layout_marginBottom=&quot;8dp&quot;
                android:layout_marginStart=&quot;5dp&quot;
                android:layout_marginEnd=&quot;5dp&quot;
                android:elevation=&quot;8dp&quot;
                android:background=&quot;#FFFFFF&quot;
                tools:ignore=&quot;MissingConstraints&quot;&gt;

                &lt;com.google.android.material.textfield.TextInputLayout
                    android:id=&quot;@+id/textInputLayout&quot;
                    android:layout_width=&quot;match_parent&quot;
                    android:layout_height=&quot;wrap_content&quot;
                    android:paddingStart=&quot;8dp&quot;
                    android:paddingEnd=&quot;8dp&quot;
                    android:paddingTop=&quot;16dp&quot;
                    android:paddingBottom=&quot;16dp&quot;&gt;

                    &lt;com.google.android.material.textfield.TextInputEditText
                        android:id=&quot;@+id/textInputEditText&quot;
                        android:layout_width=&quot;match_parent&quot;
                        android:layout_height=&quot;wrap_content&quot;
                        android:textColorHint=&quot;#9E9E9E&quot;
                        android:maxLines=&quot;1&quot;
                        android:inputType=&quot;text&quot;
                        android:textSize=&quot;16sp&quot; /&gt;

                &lt;/com.google.android.material.textfield.TextInputLayout&gt;
            &lt;/androidx.cardview.widget.CardView&gt;

        &lt;/androidx.constraintlayout.widget.ConstraintLayout&gt;

Here is my Activity XML code:

        &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
    &lt;LinearLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
        android:id=&quot;@+id/containerLayout&quot;
        android:layout_width=&quot;match_parent&quot;
        android:layout_height=&quot;match_parent&quot;
        android:orientation=&quot;vertical&quot;&gt;

    &lt;/LinearLayout&gt;

Here is the fields generate code:

        fun poplulateFields(fields: List&lt;Field&gt;){
            val inflater = LayoutInflater.from(this)
            for (x in fields) {
                if (x.type.equals(&quot;textbox&quot;)){
                    val inputFieldLayout = inflater.inflate(R.layout.input_field_layout, containerLayout, false)
                    val textInputLayout = inputFieldLayout.findViewById&lt;TextInputLayout&gt;(R.id.textInputLayout)
                    val textInputEditText = inputFieldLayout.findViewById&lt;TextInputEditText&gt;(R.id.textInputEditText)
                    textInputEditText.inputType = InputType.TYPE_CLASS_TEXT
                    textInputLayout.hint = x.label
                    if(x.required){
                        if(x.regex != null || x.regex !=&quot;&quot;){
                            val regexPattern = x.regex
                            textInputEditText.addTextChangedListener(object : TextWatcher {
                                override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}

                                override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}

                                override fun afterTextChanged(s: Editable?) {
                                    val value = s.toString()
                                    val isValid = value.matches(Regex(regexPattern))
                                    if (isValid) {
                                        // Valid input
                                        textInputLayout.error = null
                                    } else {
                                        // Invalid input
                                        textInputLayout.error = &quot;Invalid input&quot;
                                    }
                                }
                            })
                        }

                    }
                    containerLayout.addView(inputFieldLayout)
                    // Add the EditText to the list for later use
                    editTextList.add(textInputEditText)
                }

            }
        }

Here is my submit button code:

        btnNext.setOnClickListener {
                Log.e(&quot;btnNext---&quot;,&quot;btnNext&quot;)
                val fieldValues = mutableMapOf&lt;Int, String&gt;()

                for (editText in editTextList) {
                    val value = editText.text.toString()
                    val fieldId = editText.id
                    fieldValues[fieldId] = value

                    Log.e(&quot;fieldId-&quot;,fieldId.toString())
                    Log.e(&quot;value-&quot;,value.toString())
                }


            }

How to set the id from JSON to textfield which comes from json defined in "code": "ACCT_NO"?

how to validate input field not empty or not null or other validation on submit next button?

答案1

得分: 0

使用tag来存储代码数据

val inputFieldLayout = inflater.inflate(R.layout.input_field_layout, containerLayout, false)
val textInputLayout = inputFieldLayout.findViewById&lt;TextInputLayout&gt;(R.id.textInputLayout)
val textInputEditText = inputFieldLayout.findViewById&lt;TextInputEditText&gt;(R.id.textInputEditText)
textInputEditText.inputType = InputType.TYPE_CLASS_TEXT
textInputEditText.tag = x.code // 将代码数据存储到编辑文本中
textInputLayout.hint = x.label

tag中检索代码数据

btnNext.setOnClickListener {
    Log.e(&quot;btnNext---&quot;,&quot;btnNext&quot;)
    val fieldValues = mutableMapOf&lt;Int, String&gt;()

    for (editText in editTextList) {
        val value = editText.text.toString()
        val fieldId = editText.tag // 获取代码数据
        fieldValues[fieldId] = value

        Log.e(&quot;fieldId-&quot;,fieldId.toString())
        Log.e(&quot;value-&quot;,value.toString())
    }
}

要在单击下一步按钮时验证输入字段不为空,请使用验证函数和if语句。

// 验证所有字段都不为空
fun checkFieldsNotEmpty(editTextList: List&lt;TextInputEditText&gt;): Boolean {
    for (editText in editTextList) {
        if (editText.text.isNullOrEmpty()) return false
    }

    return true
}

btnNext.setOnClickListener {
    // 如果任何编辑文本为空,则返回
    if (!checkFieldsNotEmpty(editTextList)) return@setOnClickListener

    Log.e(&quot;btnNext---&quot;,&quot;btnNext&quot;)
    val fieldValues = mutableMapOf&lt;Int, String&gt;()

    for (editText in editTextList) {
        val value = editText.text.toString()
        val fieldId = editText.id
        fieldValues[fieldId] = value

        Log.e(&quot;fieldId-&quot;,fieldId.toString())
        Log.e(&quot;value-&quot;,value.toString())
    }
}
英文:

Use tag to store code data

val inputFieldLayout = inflater.inflate(R.layout.input_field_layout, containerLayout, false)
val textInputLayout = inputFieldLayout.findViewById&lt;TextInputLayout&gt;(R.id.textInputLayout)
val textInputEditText = inputFieldLayout.findViewById&lt;TextInputEditText&gt;(R.id.textInputEditText)
textInputEditText.inputType = InputType.TYPE_CLASS_TEXT
textInputEditText.tag = x.code // store code data into edit text
textInputLayout.hint = x.label

and retrieve code data from tag

btnNext.setOnClickListener {
    Log.e(&quot;btnNext---&quot;,&quot;btnNext&quot;)
    val fieldValues = mutableMapOf&lt;Int, String&gt;()

    for (editText in editTextList) {
        val value = editText.text.toString()
        val fieldId = editText.tag // get code data
        fieldValues[fieldId] = value

        Log.e(&quot;fieldId-&quot;,fieldId.toString())
        Log.e(&quot;value-&quot;,value.toString())
    }
}

To validate input fields not empty on clicking the next button, use the validation function and if statement.

// validating all fields are not empty
fun checkFieldsNotEmpty(editTextList: List&lt;TextInputEditText&gt;): Boolean {
    for (editText in editTextList) {
        if (editText.text.isNullOrEmpty()) return false
    }

    return true
}

btnNext.setOnClickListener {
    // any edit text is empty then return
    if (!checkFieldsNotEmpty(editTextList)) return@setOnClickListener

    Log.e(&quot;btnNext---&quot;,&quot;btnNext&quot;)
    val fieldValues = mutableMapOf&lt;Int, String&gt;()

    for (editText in editTextList) {
        val value = editText.text.toString()
        val fieldId = editText.id
        fieldValues[fieldId] = value

        Log.e(&quot;fieldId-&quot;,fieldId.toString())
        Log.e(&quot;value-&quot;,value.toString())
    }
}

huangapple
  • 本文由 发表于 2023年7月17日 12:58:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/76701593.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定