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