Android 自定义编辑文本值被另一个自定义编辑文本更改
Posted
技术标签:
【中文标题】Android 自定义编辑文本值被另一个自定义编辑文本更改【英文标题】:Android custom edit text value is changed by another custom edit text 【发布时间】:2020-06-22 16:40:54 【问题描述】:简介
在我的一个项目中,我尝试创建带有标题和一些自定义验证的自定义 EditText。当我用屏幕旋转和活动娱乐测试这个自定义视图时,我遇到了一个奇怪的问题。
什么问题
休闲前
当应用程序启动时,所有编辑文本都有正确的值,这些值是从活动静态设置的。如下图:
休闲后
在我旋转屏幕或重新创建活动后,EditText 的值将被弄乱。 CustomEditText 值设置为 XML 中上次编辑文本的值。简单(Basic android EditText)编辑文本值设置正常。
代码
我从出现此问题的项目中复制了代码。
主要活动
class MainActivity : AppCompatActivity()
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
first_custom_edit_text.header = "First header"
first_custom_edit_text.setText("First text")
third_custom_edit_text.header = "Third header"
third_custom_edit_text.setText("Third text")
first_simple_edit_text.setText("First simple - Not affected")
second_custom_edit_text.header = "Second header"
second_custom_edit_text.setText("Second text")
second_simple_edit_text.setText("Second simple - Not affected")
自定义编辑文本
class CustomEditText : LinearLayout
fun setText(value: String?)
this.input_edit_text.text = Editable.Factory.getInstance().newEditable(value ?: "")
fun getText(): String
return this.input_edit_text.text.toString()
var header: String?
get() = this.header_text_view.text.toString()
set(value)
this.header_text_view.text = Editable.Factory.getInstance().newEditable(value ?: "")
constructor(context: Context) : super(context)
init(context, null)
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
init(context, attrs)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
init(context, attrs)
private fun init(context: Context, attrs: AttributeSet?)
inflate(context, R.layout.ui_custom_edit_text, this)
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_
android:layout_
tools:context=".MainActivity"
android:orientation="vertical">
<com.example.customedittextbug.CustomEditText
android:layout_
android:layout_
android:id="@+id/first_custom_edit_text"/>
<com.example.customedittextbug.CustomEditText
android:layout_
android:layout_
android:id="@+id/second_custom_edit_text"/>
<EditText
tools:hint="input@hint.example"
android:layout_
android:layout_
android:layout_marginLeft="-4dp"
android:layout_marginRight="-4dp"
android:textColor="@android:color/black"
android:textSize="18sp"
android:inputType="text"
android:id="@+id/first_simple_edit_text"/>
<com.example.customedittextbug.CustomEditText
android:layout_
android:layout_
android:id="@+id/third_custom_edit_text"/>
<EditText
tools:hint="input@hint.example"
android:layout_
android:layout_
android:layout_marginLeft="-4dp"
android:layout_marginRight="-4dp"
android:textColor="@android:color/black"
android:textSize="18sp"
android:inputType="text"
android:id="@+id/second_simple_edit_text"/>
</LinearLayout>
ui_custom_edit_text.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:orientation="vertical">
<TextView
tools:text="Input header"
android:layout_
android:layout_
android:textColor="@android:color/black"
android:textStyle="bold"
android:textSize="17sp"
android:id="@+id/header_text_view"/>
<LinearLayout
android:layout_
android:layout_
android:orientation="vertical"
android:id="@+id/validations_errors_holder"/>
<RelativeLayout
android:layout_
android:layout_
android:id="@+id/common_input_holder">
<EditText
tools:hint="input@hint.example"
android:layout_
android:layout_
android:layout_marginLeft="-4dp"
android:layout_marginRight="-4dp"
android:textColor="@android:color/black"
android:textSize="18sp"
android:inputType="text"
android:id="@+id/input_edit_text"/>
<LinearLayout
android:layout_
android:layout_
android:layout_alignEnd="@+id/input_edit_text"
android:layout_centerVertical="true"
android:layout_marginEnd="4dp"
android:layout_marginStart="4dp"
android:gravity="end"
android:orientation="horizontal"
android:id="@+id/right_view_holder"/>
</RelativeLayout>
</LinearLayout>
更新
我发现这两个指南很好地解释了我的问题得到解答后如何解决此问题。
Link1, Link2
【问题讨论】:
【参考方案1】:状态恢复以 ID 为键,所有自定义视图都有一个具有相同 ID 的子视图:input_edit_text
。因此,它们都恢复到相同的状态,因为它们都获得了以该 ID 保存的最后一个。
您可以通过在 EditText
上设置 android:saveEnabled="false"
来避免这种情况(尽管您可能希望自己在 CustomEditText
中保存/恢复实例状态)。
【讨论】:
【参考方案2】:我厌倦了搜索,但这对我有用。
添加到 CustomEditText 类
companion object
private const val SPARSE_STATE_KEY = "SPARSE_STATE_KEY"
private const val SUPER_STATE_KEY = "SUPER_STATE_KEY"
override fun dispatchSaveInstanceState(container: SparseArray<Parcelable>)
dispatchFreezeSelfOnly(container)
override fun dispatchRestoreInstanceState(container: SparseArray<Parcelable>)
dispatchThawSelfOnly(container)
override fun onSaveInstanceState(): Parcelable?
Log.i("ByHand", "onSaveInstanceState")
return Bundle().apply
Log.i("ByHand", "Writing children state to sparse array")
putParcelable(SUPER_STATE_KEY, super.onSaveInstanceState())
putSparseParcelableArray(SPARSE_STATE_KEY, saveChildViewStates())
override fun onRestoreInstanceState(state: Parcelable?)
Log.i("ByHand", "onRestoreInstanceState")
var newState = state
if (newState is Bundle)
Log.i("ByHand", "Reading children children state from sparse array")
val childrenState = newState.getSparseParcelableArray<Parcelable>(SPARSE_STATE_KEY)
childrenState?.let restoreChildViewStates(it)
newState = newState.getParcelable(SUPER_STATE_KEY)
super.onRestoreInstanceState(newState)
fun ViewGroup.saveChildViewStates(): SparseArray<Parcelable>
val childViewStates = SparseArray<Parcelable>()
children.forEach child -> child.saveHierarchyState(childViewStates)
return childViewStates
fun ViewGroup.restoreChildViewStates(childViewStates: SparseArray<Parcelable>)
children.forEach child -> child.restoreHierarchyState(childViewStates)
this link for details
【讨论】:
如果不是同一件事,我在基类中做了类似的事情。 github.com/backbonesk/parent/blob/master/app/src/main/java/sk/…以上是关于Android 自定义编辑文本值被另一个自定义编辑文本更改的主要内容,如果未能解决你的问题,请参考以下文章