自定义 TextInputLayout 在后按时设置错误的值
Posted
技术标签:
【中文标题】自定义 TextInputLayout 在后按时设置错误的值【英文标题】:Custom TextInputLayout gets wrong values set on back pressed 【发布时间】:2021-03-13 00:01:51 【问题描述】:在我的应用中,我正在使用包含 TextInputLayout
的自定义视图,代码如下:
<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_
android:layout_>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/input_layout"
style="@style/UbiInput2"
android:layout_
android:layout_
android:hint="-"
android:orientation="horizontal"
app:boxBackgroundColor="@color/white">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/input_value"
android:layout_
android:layout_
android:inputType="textPersonName" />
</com.google.android.material.textfield.TextInputLayout>
</androidx.appcompat.widget.LinearLayoutCompat>
还有科特林
class TextInputView(context: Context, attrs: AttributeSet?) : LinearLayout(context, attrs)
var errorMessage: String? = ""
init
inflate(context, R.layout.text_input_view, this)
val attributes = context.obtainStyledAttributes(attrs, R.styleable.TextInputView)
val inputLayout = findViewById<TextInputLayout>(R.id.input_layout)
val inputValue = findViewById<TextInputEditText>(R.id.input_value)
inputLayout.hint = attributes.getString(R.styleable.TextInputView_hint)
inputValue.hint = attributes.getString(R.styleable.TextInputView_placeholderText)
inputLayout.isExpandedHintEnabled =
attributes.getBoolean(R.styleable.TextInputView_expandedHintEnabled, true)
errorMessage = attributes.getString(R.styleable.TextInputView_errorMessage)
inputLayout.isHelperTextEnabled = false
inputValue.inputType =
attributes.getInt(
R.styleable.TextInputView_android_inputType,
InputType.TYPE_CLASS_TEXT
)
if (attributes.hasValue(R.styleable.TextInputView_android_maxLength))
inputValue.filters += InputFilter.LengthFilter(
attributes.getInt(
R.styleable.TextInputView_android_maxLength,
100
)
)
inputValue.gravity =
attributes.getInt(R.styleable.TextInputView_android_gravity, Gravity.START)
if (attributes.getBoolean(R.styleable.TextInputView_android_gravity, false))
inputLayout.helperText = attributes.getString(R.styleable.TextInputView_helperText)
if (attributes.getBoolean(R.styleable.TextInputView_helperTextEnabled, false))
inputLayout.isHelperTextEnabled = true
inputLayout.helperText = attributes.getString(R.styleable.TextInputView_helperText)
inputLayout.startIconDrawable =
attributes.getDrawable(R.styleable.TextInputView_startIconDrawable)
attributes.recycle()
@BindingAdapter("textValue")
fun TextInputView.setTextValue(value: String?)
value?.let
setValue(value)
@InverseBindingAdapter(attribute = "textValue")
fun TextInputView.getTextValue(): String
return value()
@BindingAdapter("textValueAttrChanged")
fun TextInputView.setListener(textAttrChanged: InverseBindingListener)
val inputValue = findViewById<TextInputEditText>(R.id.input_value)
inputValue.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?)
textAttrChanged.onChange()
)
我有以下屏幕,点击按钮会转到下一个片段。使用导航组件。
但是在下一个屏幕上,当我按返回按钮返回搜索表单时,hint
和 helperText
的 TextInputLayout
值都相同。
我设置这些的唯一位置是在自定义视图中。而且从调试中我可以看到当时设置了所有正确的值。
我对那里发生的事情有点不知所措。任何提示将不胜感激。
使用的材质库版本:1.3.0-alpha04
所有代码库已迁移到视图绑定according the latest changes
视图使用如下:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="viewModel"
type="com.ubigo.features.v2.products.taxi.SearchViewModel" />
<variable
name="dateFormat"
type="com.ubigo.ubicore.date.UbiDate" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/rental_search_root"
android:layout_
android:layout_
android:background="@color/background">
<androidx.cardview.widget.CardView
android:id="@+id/rental_search_form"
style="@style/WhiteCardView"
android:layout_
android:layout_
android:layout_marginTop="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView10">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/constraintLayout3"
android:layout_
android:layout_>
<com.ubigo.ubicore.ui.TextInputView
android:id="@+id/pickup"
android:layout_
android:layout_
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
app:hint="@string/product_start"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:startIconDrawable="@drawable/ic_calendar"
app:textValue="@dateFormat.getPrettyDate(viewModel.pickupDateTime)" />
<View
android:id="@+id/divider6"
android:layout_
android:layout_
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:background="?android:attr/listDivider"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/pickup" />
<com.ubigo.ubicore.ui.TextInputView
android:id="@+id/dropoff"
android:layout_
android:layout_
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
app:hint="@string/product_end"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/divider6"
app:startIconDrawable="@drawable/ic_calendar"
app:textValue="@dateFormat.getPrettyDate(viewModel.destinationDatetime)" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
<com.ubigo.ubicore.ui.LoaderButton
android:id="@+id/rental_search_button"
android:layout_
android:layout_
android:layout_marginStart="16dp"
android:layout_marginTop="32dp"
android:layout_marginEnd="16dp"
android:text="@string/product_rental_show_car"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/rental_search_location" />
<androidx.cardview.widget.CardView
android:id="@+id/rental_search_location"
style="@style/WhiteCardView"
android:layout_
android:layout_
android:layout_marginTop="32dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/rental_search_form">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/constraintLayout4"
android:layout_
android:layout_>
<com.ubigo.ubicore.ui.TextInputView
android:id="@+id/user_location"
android:layout_
android:layout_
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
app:helperText="@string/product_rental_location"
app:helperTextEnabled="true"
app:hint="@string/product_pickup_location"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:startIconDrawable="@drawable/ic_location_on_black_24dp"
app:textValue="@viewModel.depAddress" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
<TextView
android:id="@+id/textView10"
android:layout_
android:layout_
android:layout_marginStart="32dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="32dp"
android:text="@string/product_rental_weekend"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
以及Fragment的初始化:
class RentalSearchFragment : Fragment()
val viewModel: SearchViewModel by viewModel()
private val binding get() = _binding!!
private var _binding: FragmentRentalSearchBinding? = null
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View?
if (_binding == null)
_binding = FragmentRentalSearchBinding.inflate(inflater, container, false)
binding.lifecycleOwner = viewLifecycleOwner
binding.viewModel = viewModel
binding.dateFormat = UbiDate()
return binding.root
override fun onDestroyView()
super.onDestroyView()
_binding = null
【问题讨论】:
同样的问题,你找到解决办法了吗? 在 for 循环中动态添加 TextInputLayout 时出现类似问题。通过在 post 方法中调用 infalte 和 addView 来解决。 View.post //inflate //添加视图 您找到解决此问题的方法了吗? 【参考方案1】:我能够通过实现 onSaveInstanceState、onRestoreInstanceState、dispatchSaveInstanceState、dispatchRestoreInstanceState 和 setValues 来解决这个确切的问题,如此处所述
http://www.devexchanges.info/2016/03/custom-compound-view-in-android.html
上面的链接详细介绍了如何实现这些功能。毫无疑问,您还可以找到无数其他资源来了解如何实现这个 android 范例。
【讨论】:
正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center。 仅供参考,该评论已被看到您答案的人删除。只是软件没有显示分享反馈的人。别担心,它不是机器人自动丢弃 cmets! 虽然您编辑中的论点可能是有效的,但它是元评论,即它与问题或答案的技术内容无关,因此不适合在答案框中。请不要在答案中添加此类文本。此外,您回复的评论只是建议您扩展您的答案;是否要这样做完全取决于您。以上是关于自定义 TextInputLayout 在后按时设置错误的值的主要内容,如果未能解决你的问题,请参考以下文章
Android:TextInputLayout - 自定义提示、底线和错误消息的颜色
登录界面AutoUtils 屏幕适配自定义Edittext(显示密码可见和一键清空)和 TextInputLayout的使用。