2

I created a deletable EditText. Here is the layout

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal" >

<EditText
    android:id="@+id/cacEditText"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:inputType="text"
    android:paddingRight="35dp" />

<Button
    android:id="@+id/cacClearButton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:layout_marginLeft="20dp"
    android:layout_marginTop="5dp"
    android:layout_marginRight="5dp"
    android:background="@android:drawable/ic_input_delete"
    android:visibility="invisible" />

</RelativeLayout>

The problem is that when I put more of these into one layout and rotate to landscape, they all suddenly have the same value. I suppose it is because the system restores the values by ID and each component consists of elements of the same IDs. How can I solve this problem?

More info:

deletable EditText (cz.kns.uome.component.CleanAndClearEditText) in a layout

<?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/cz.kns.uome"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <ScrollView
        android:id="@+id/scrollView1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" >

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:padding="5dp" >

            <RelativeLayout
                android:layout_width="fill_parent"
                android:layout_height="wrap_content" >

                <cz.kns.uome.component.CleanAndClearEditText
                    android:id="@+id/nameEditText"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentLeft="true"
                    android:layout_toLeftOf="@+id/contactPickerButton"
                    app:hint="@string/person_name"
                    app:type="textPersonName" />

                <ImageButton
                    android:id="@+id/contactPickerButton"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentRight="true"
                    android:contentDescription="@string/select_contact"
                    android:src="@drawable/ic_action_dropdown" />
            </RelativeLayout>

            <cz.kns.uome.component.CleanAndClearEditText
                android:id="@+id/emailEditText"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                app:hint="@string/person_email_opt"
                app:type="textEmailAddress" />

            <cz.kns.uome.component.CleanAndClearEditText
                android:id="@+id/descriptionEditText"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                app:hint="@string/description_opt"
                app:type="text" />

            <LinearLayout
                android:layout_width="fill_parent"
                android:layout_height="wrap_content" >

                <Button
                    android:id="@+id/saveButton"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_weight="5"
                    android:text="@string/save" />

                <Button
                    android:id="@+id/cancelButton"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_weight="2"
                    android:text="@string/cancel" />
            </LinearLayout>
        </LinearLayout>
    </ScrollView>

</LinearLayout>

java class

public class CleanAndClearEditText extends RelativeLayout {

    private final EditText editText;
    private final Button clearButton;

    public CleanAndClearEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
        LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(R.layout.clean_and_clear_edit_text, this);

        TypedArray typedArray = getContext().obtainStyledAttributes(attrs,
                R.styleable.ClearAndCleanEditText);

        // ?????
        // I have to somehow access that edittext here but static id does not work
        editText = (EditText) findViewById(R.id.cacEditText);
        editText.addTextChangedListener(textWatcher);
        editText.setHint(typedArray.getString(R.styleable.ClearAndCleanEditText_hint));

        String type = typedArray.getString(R.styleable.ClearAndCleanEditText_type);
        if (type != null) {
            editText.setInputType(InputTypes.get(type));
        }

        clearButton = (Button) findViewById(R.id.cacClearButton);
        clearButton.setOnClickListener(clearButtonListener);
    }
    // rest ommited
}

Normal state Rotated

user219882
  • 15,274
  • 23
  • 93
  • 138
  • I didn't understand your question. If you put more of these into one layout, you should have different id's. – Sebastian Breit May 19 '12 at 11:12
  • Please look at the updated question – user219882 May 19 '12 at 11:19
  • You'll have to save the state for your custom `View`. Here is a link with a detailed answer http://stackoverflow.com/questions/3542333/how-to-prevent-custom-views-from-losing-state-across-screen-orientation-changes . – user May 19 '12 at 12:27
  • @Luksprog That is not the problem. If I used this I wouldn't have to create my own component because it wouldn't help me at all – user219882 May 19 '12 at 13:26
  • Oddly, I've just experienced this same phenomenon. Can you please explain further why this is happening, @Tomas? Is it simply because of the ID's in the xml layout you inflate? – user1923613 Jan 08 '14 at 18:06
  • @Luksprog If you could explain it too, I would be very thankful. – user1923613 Jan 08 '14 at 18:19

3 Answers3

2

I'm running on this issue, and I was able to "solve" this, by removing all views in the layout that contains the custom views, implement this:

public void onSaveInstanceState(Bundle outState) {
    // TODO Auto-generated method stub
    super.onSaveInstanceState(outState);
    // retain your data in the bundle then remove views
    layout.removeAllViewsInLayout();
}

So you can get your data back from the bundle in the onCreate method.

Akino
  • 41
  • 3
1

See if this helps:

public class CleanAndClearEditText extends RelativeLayout {

    private final EditText editText;
    private final Button clearButton;

    public CleanAndClearEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
        LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(R.layout.clean_and_clear_edit_text, this);
        RelativeLayout rl = (RelativeLayout) getChildAt(0); // consider using a merge tag in R.layout.clean_and_clear_edit_text instead of the parent RelativeLayout
        //clearButton = (Button) findViewById(R.id.cacClearButton);
        clearButton = (Button) rl.getChildAt(1);
        clearButton.setOnClickListener(null);
        //editText = (EditText) findViewById(R.id.cacEditText);
        editText = (EditText) rl.getChildAt(0);
    }

    @Override
    protected Parcelable onSaveInstanceState() {
        Parcelable superState = super.onSaveInstanceState();
        SavedState ss = new SavedState(superState);
        ss.stateToSave = editText.getText().toString();
        return ss;

    }

    @Override
    protected void onRestoreInstanceState(Parcelable state) {
        if (!(state instanceof SavedState)) {
            super.onRestoreInstanceState(state);
            return;
        }
        SavedState ss = (SavedState) state;
        super.onRestoreInstanceState(ss.getSuperState());
        editText.setText(ss.stateToSave);
    }

    static class SavedState extends BaseSavedState {
        String stateToSave;

        SavedState(Parcelable superState) {
            super(superState);
        }

        private SavedState(Parcel in) {
            super(in);
            stateToSave = in.readString();
        }

        @Override
        public void writeToParcel(Parcel out, int flags) {
            super.writeToParcel(out, flags);
            out.writeString(stateToSave);
        }

        // required field that makes Parcelables from a Parcel
        public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() {
            public SavedState createFromParcel(Parcel in) {
                return new SavedState(in);
            }

            public SavedState[] newArray(int size) {
                return new SavedState[size];
            }
        };
    }
}

and the modified R.layout.clean_and_clear_edit_text file:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal" >

    <EditText
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:inputType="text"
        android:paddingRight="35dp" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="5dp"
        android:layout_marginTop="5dp"
        android:background="@android:drawable/ic_input_delete"
        android:visibility="invisible" />

</RelativeLayout>

Edit: The main part of the code is from the question I posted as a comment.

user
  • 86,916
  • 18
  • 197
  • 190
  • I tried to manually set IDs which worked fine but it was a little bit hack. This one is longer but better and safer. Thank you – user219882 May 19 '12 at 14:39
0

OK, I see you are inflating custom code and inserting it into a linearlayout. You should use a ListView and implement your ListAdapter. You can customize your ListItem to fit your needs. That's the way I would do it.

Sebastian Breit
  • 6,137
  • 1
  • 35
  • 53