为什么的EditText在自定义复合视图重新使用另一种化合物视图实例中输入的文本?视图、自定义、化合物、实例

2023-09-05 10:42:54 作者:君心今何在°

我想写一个的TextView 的EditText ,_compound_view.xml_组成的自定义复合视图

 < LinearLayout中的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
机器人:ID =@ + ID / compoundText
机器人:layout_width =match_parent
机器人:layout_height =WRAP_CONTENT>

<的TextView
    机器人:ID =@ + ID /为textLabel
    机器人:layout_width =WRAP_CONTENT
    机器人:layout_height =WRAP_CONTENT
    机器人:文本=标签/>

<的EditText
    机器人:ID =@ + ID /文本编辑
    机器人:layout_width =match_parent
    机器人:layout_height =WRAP_CONTENT
    机器人:提示=输入文字在这里>
< /的EditText>
 

这是扩展类的LinearLayout

 公共类CompoundView扩展的LinearLayout {

公共CompoundView(上下文的背景下,ATTRS的AttributeSet){
    超(背景下,ATTRS);

    readAttributes(背景下,ATTRS);
    的init(上下文);
}

公共CompoundView(上下文的背景下){
    超(上下文);

    的init(上下文);
}

私人无效的init(上下文C){

    最后LayoutInflater充气=(LayoutInflater)C
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    inflater.inflate(R.layout.compound_view,这一点);

}
   }
 

现在,如果我用2这些查看在我_activity_main.xml _:

 < RelativeLayout的的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
的xmlns:工具=htt​​p://schemas.android.com/tool​​s
机器人:layout_width =match_parent
机器人:layout_height =match_parent
工具:上下文=MainActivity。>
< it.moondroid.compoundview.example.CompoundView
    机器人:ID =@ + ID / compoundview1
    机器人:layout_width =match_parent
    机器人:layout_height =WRAP_CONTENT
    机器人:layout_alignParentTop =真/>

< it.moondroid.compoundview.example.CompoundView
    机器人:ID =@ + ID / compoundview2
    机器人:layout_width =match_parent
    机器人:layout_height =WRAP_CONTENT
    机器人:layout_below =@ ID / compoundview1/>
< / RelativeLayout的>
 
Android自定义EditText 你需要一款简单实用的SuperEditText 一键删除 自定义样式

和在活动code我只吹了RelativeLayout的,无管理的onSaveInstanceState:

  @覆盖
保护无效的onCreate(包savedInstanceState){
    super.onCreate(savedInstanceState);
    的setContentView(R.layout.activity_main);

}
 

然后当我写的东西在2 的EditText 和我转动我的设备,同样的文本出现在第一个自定义的的EditText 查看

为什么会发生这种行为?

编辑:

我通过删除的的Andr​​oid解决的问题:ID 的和使用的安卓标记的的的EditText 在compound_view。 XML,然后管理储蓄的EditText国家在CompoundView类:

  @覆盖
保护Parcelable的onSaveInstanceState(){

    束束=新包();
    bundle.putParcelable(instanceState,super.onSaveInstanceState());
    bundle.putString(currentEdit,mEditText.getText()的toString());
    bundle.putBoolean(isFocused,mEditText.hasFocus());
    返回包;

}

@覆盖
保护无效onRestoreInstanceState(Parcelable州){

    如果(州的instanceof捆绑){
        束束=(包)的状态;
        mEditText.setText(bundle.getString(currentEdit));
        如果(bundle.getBoolean(isFocused)){
            mEditText.requestFocus();
        }
        super.onRestoreInstanceState(bundle.getParcelable(instanceState));
        返回;
    }

    super.onRestoreInstanceState(州);
}
 

解决方案

我会说,我还没有证实这...但我使用的是复合视图,类似时候遇​​到了同样的问题,开始你在做什么。

我认为,问题的根源在于如何Android的自动保存的的EditText 控件的状态,我认为它的身份证保存它。所以,如果你在你的XML具有相同的身份证多个控件,然后当它保存的状态,然后恢复状态,具有相同ID的所有控件都得到相同的值。您可以通过添加试试这个2 的EditText contols你正常的XML,并给他们同样的机器人:ID 值,看看如果他们最终得到了相同的值。

在你的情况,你可以尝试不使用IDS的复合视图,而找到的元素的另一种方式,或者通过标签( View.findViewWithTag ),或者通过名称,看看是否有差别。

在我的情况,我做了后者的解决了这个问题。

I'm trying to write a custom compound view composed by a TextView and an EditText, _compound_view.xml_:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/compoundText"
android:layout_width="match_parent"
android:layout_height="wrap_content" >

<TextView
    android:id="@+id/textLabel"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Label" />

<EditText
    android:id="@+id/textEdit"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="enter text here" >
</EditText>

and this is the class extending LinearLayout:

public class CompoundView extends LinearLayout {

public CompoundView(Context context, AttributeSet attrs) {
    super(context, attrs);

    readAttributes(context, attrs);
    init(context);
}

public CompoundView(Context context) {
    super(context);

    init(context);
}

private void init(Context c) {

    final LayoutInflater inflater = (LayoutInflater) c
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    inflater.inflate(R.layout.compound_view, this);

}
   }

Now, if I use 2 of these View in my _activity_main.xml_:

<RelativeLayout 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"
tools:context=".MainActivity" >
<it.moondroid.compoundview.example.CompoundView
    android:id="@+id/compoundview1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true" />

<it.moondroid.compoundview.example.CompoundView
    android:id="@+id/compoundview2"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_below="@id/compoundview1" />
</RelativeLayout>

and in the Activity code I only inflate the RelativeLayout, without managing onSaveInstanceState:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

}

then when I write something in the 2nd EditText and I rotate my device, the same text appears in the EditText of the first custom View.

Why is happening this behaviour?

EDIT:

I solved the issue by removing android:id and using android:tag for the EditText in compound_view.xml, then managing the saving of the EditText state in CompoundView class:

@Override
protected Parcelable onSaveInstanceState() {

    Bundle bundle = new Bundle();
    bundle.putParcelable("instanceState", super.onSaveInstanceState());
    bundle.putString("currentEdit", mEditText.getText().toString());
    bundle.putBoolean("isFocused", mEditText.hasFocus());
    return bundle;

}

@Override
protected void onRestoreInstanceState(Parcelable state) {

    if (state instanceof Bundle) {
        Bundle bundle = (Bundle) state;
        mEditText.setText(bundle.getString("currentEdit"));
        if (bundle.getBoolean("isFocused")) {
            mEditText.requestFocus();
        }
        super.onRestoreInstanceState(bundle.getParcelable("instanceState"));
        return;
    }

    super.onRestoreInstanceState(state);
}

解决方案

I'll start off by saying that I haven't confirmed this... but I experienced the same issues when using a compound view, similar to what you were doing.

I think the root of the problem is how Android automatically saves the state of EditText controls, and I think it saves it by "id". So if you have multiple controls in your xml with same "id", then when it saves state, and then restores state, all controls with the same id get the same value. You can try this by adding 2 EditText contols to you normal xml and give them the same android:id value and see if they end up getting the same value.

In your case, you can try to NOT use ids in the compound view and rather find the elements another way, either by tag (View.findViewWithTag), or by name, and see if that makes a difference.

In my case, I solved the problem by doing the latter.