Почему EditText в пользовательском составном представлении повторно использует текст, введенный в другой составной экземпляр вида?

Я пытаюсь написать настраиваемый составной вид, составленный TextView и 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> 

И это класс, расширяющий 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); } } 

Теперь, если я использую 2 из этих View в своем _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> 

И в коде действия я только раздуваю RelativeLayout, не управляя onSaveInstanceState:

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

Затем, когда я пишу что-то во втором EditText и вращаю свое устройство, тот же text появляется в EditText первого пользовательского View .

Почему такое поведение происходит?

РЕДАКТИРОВАТЬ:

Я решил проблему, удалив android: id и используя android: tag для EditText в составном_view.xml, а затем управляя сохранением состояния EditText в классе CompoundView:

 @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); } 

Я начну, сказав, что я не подтвердил это … но я столкнулся с теми же проблемами при использовании сложного представления, похожего на то, что вы делали.

Я думаю, что корень проблемы в том, как Android автоматически сохраняет состояние элементов управления EditText , и я думаю, что он сохраняет его с помощью «id». Поэтому, если у вас есть несколько элементов управления в вашем xml с одинаковым «id», тогда, когда он сохраняет состояние, а затем восстанавливает состояние, все элементы управления с одинаковым идентификатором получают одинаковое значение. Вы можете попробовать это, добавив 2 EditText contols к нормальному xml и дадите им одинаковое значение android:id и посмотрите, получают ли они одинаковое значение.

В вашем случае вы можете попытаться НЕ использовать идентификаторы в составном виде и скорее найти элементы по-другому, либо по тегу ( View.findViewWithTag ), либо по имени, и посмотреть, не View.findViewWithTag ли это.

В моем случае я решил проблему, выполнив последнее.

Взгляните на мой комментарий в своем вопросе, а также убедитесь, что вы правильно ссылаетесь на свои взгляды.

Я использую ваш код следующим образом:

 CompoundView cv1 = (CompoundView) findViewById(R.id.compoundview1); TextView tv1 = (TextView) cv1.findViewById(R.id.textEdit); CompoundView cv2 = (CompoundView) findViewById(R.id.compoundview2); TextView tv2 = (TextView) cv2.findViewById(R.id.textEdit); 

У меня такая же раздражающая проблема, и я решил ее другим решением, чем предлагалось. Когда пользовательский вид завышен, я не нахожу их с идентификаторами или тегами, я получаю их с помощью метода getChildAt . Мне не нужно было сохранять состояние экземпляра.

Вот пример:

Пользовательский XML для раздувания (custom_view.xml):

 <?xml version="1.0" encoding="utf-8"?> <merge xmlns:android="http://schemas.android.com/apk/res/android" > <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center" android:textAppearance="?android:attr/textAppearanceMedium"/> <EditText android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center"/> </merge> 

Затем вы просто получаете представления таким образом во время инициализации представления:

 private void initView(Context context) { LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); inflater.inflate(R.layout.custom_view, this, true); setOrientation(LinearLayout.HORIZONTAL); setGravity(Gravity.CENTER); TextView mTitleTV = (TextView) getChildAt(0); EditText mContentET = (EditText) getChildAt(1); } 

ВАЖНО : вы должны удалить все идентификаторы из XML