• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.settings.wifi.utils
18 
19 import android.text.Editable
20 import android.text.TextWatcher
21 import android.util.Log
22 import android.view.View
23 import android.widget.EditText
24 import com.google.android.material.textfield.TextInputLayout
25 
26 /** A widget that wraps the relationship work between a TextInputLayout and an EditText. */
27 open class TextInputGroup(
28     val view: View,
29     private val layoutId: Int,
30     private val editTextId: Int,
31     private val errorMessageId: Int,
32 ) {
33 
34     val layout: TextInputLayout
35         get() = view.requireViewById(layoutId)
36 
37     val editText: EditText
38         get() = view.requireViewById(editTextId)
39 
40     val errorMessage: String
41         get() = view.context.getString(errorMessageId)
42 
43     private val textWatcher =
44         object : TextWatcher {
beforeTextChangednull45             override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
46 
onTextChangednull47             override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
48 
afterTextChangednull49             override fun afterTextChanged(s: Editable?) {
50                 layout.isErrorEnabled = false
51             }
52         }
53 
54     init {
55         addTextChangedListener(textWatcher)
56     }
57 
addTextChangedListenernull58     fun addTextChangedListener(watcher: TextWatcher) {
59         editText.addTextChangedListener(watcher)
60     }
61 
62     var label: String
63         get() = layout.hint?.toString() ?: ""
64         set(value) {
65             layout.setHint(value)
66         }
67 
68     var text: String
69         get() = editText.text?.toString() ?: ""
70         set(value) {
71             editText.setText(value)
72         }
73 
74     var helperText: String
75         get() = layout.helperText?.toString() ?: ""
76         set(value) {
77             layout.setHelperText(value)
78             if (value.isEmpty()) layout.isHelperTextEnabled = false
79         }
80 
81     var error: String
82         get() = layout.error?.toString() ?: ""
83         set(value) {
84             layout.setError(value)
85             if (value.isEmpty()) layout.isErrorEnabled = false
86         }
87 
validatenull88     open fun validate(): Boolean {
89         if (!editText.isShown) return true
90 
91         val isValid = text.isNotEmpty()
92         if (!isValid) {
93             Log.w(TAG, "validate failed in ${layout.hint ?: "unknown"}")
94             error = errorMessage
95         }
96         return isValid
97     }
98 
99     companion object {
100         const val TAG = "TextInputGroup"
101     }
102 }
103