0

I've only been doing android programming for a few months, so I could be doing something silly here...

In my activity, I'm using a layout file with a LinearLayout that I'm programmatically adding child views to in the activity's OnCreate(). There is a layout file for the child view, and it contains 3 EditTexts that I'm populating with data I have saved somewhere.

When I navigate to the activity and onCreate() is first called, every child view is populated how I would expect. However, if I rotate the display from portrait -> landscape or vice-versa, when the page refreshes, all child views have the content of the last child view. When I step through the code with breakpoints, everything looks fine to me: the parent LinearLayout has the expected child views, and the child views are populated with the expected data. So, I'm at a loss as to why all child views have the data from the last child, and why this only happens when rotating. I'm using the same layout files here regardless of device size or orientation.

Any thoughts?

edit_profile_activity.xml:

<android.support.design.widget.CoordinatorLayout
    ...>

    <android.support.design.widget.AppBarLayout
        ...>

        <android.support.v7.widget.Toolbar
            .../>

    </android.support.design.widget.AppBarLayout>

    <!-- The main content view -->
    <android.support.v4.widget.NestedScrollView
        ...>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:scrollbarAlwaysDrawVerticalTrack="true"
            android:focusable="true"
            android:focusableInTouchMode="true">

            <!-- Edit Allies -->
            <LinearLayout
                android:id="@+id/profile_edit_ally_layout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:paddingLeft="@dimen/left_margin"
                android:paddingRight="@dimen/right_margin"
                android:orientation="vertical">

                <!-- This content is added programmatically. -->

            </LinearLayout>

        </LinearLayout>
    </android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>

edit_profile_activity_ally_list_item.xml:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
    <EditText
        android:id="@+id/profile_edit_ally_name_edit_text"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:hint="Name"
        android:imeOptions="flagNoExtractUi"
        android:inputType="textNoSuggestions"
        android:maxLines="1"
        android:privateImeOptions="nm"
        android:selectAllOnFocus="true"
        android:textAppearance="@style/FontEditText"/>
    <EditText
        android:id="@+id/profile_edit_ally_init_mod_edit_text"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:layout_marginLeft="@dimen/left_margin"
        android:hint="Init Mod"
        android:imeOptions="flagNoExtractUi"
        android:inputType="numberSigned"
        android:maxLines="1"
        android:privateImeOptions="nm"
        android:selectAllOnFocus="true"
        android:textAppearance="@style/FontEditText"/>
    <EditText
        android:id="@+id/profile_edit_ally_caster_level_edit_text"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:layout_marginLeft="@dimen/left_margin"
        android:hint="Caster Level"
        android:imeOptions="flagNoExtractUi"
        android:inputType="numberSigned"
        android:maxLines="1"
        android:privateImeOptions="nm"
        android:selectAllOnFocus="true"
        android:textAppearance="@style/FontEditText"/>
    <ImageButton
        android:id="@+id/profile_edit_delete_ally_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:background="@drawable/ic_delete"/>
</LinearLayout>

In my activity:

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);

    // Set the content of the activity to use the activity_main.xml layout file
    setContentView(R.layout.edit_profile_activity);

    // ...

    mAllyLayout = (LinearLayout) findViewById(R.id.profile_edit_ally_layout);
    for (TreeMap.Entry<String, AllyDB_Data> entry : mProfileData.mAllies.entrySet())
    {
        addAllyRowToLayout(entry.getKey(),
            Integer.toString(entry.getValue().mCasterLevel),
            Integer.toString(entry.getValue().mInitMod));
    }

    // Make sure there's at least one "empty" ally set.
    if (mAllyLayout.getChildCount() <= 0)
    {
        addAllyRowToLayout(null, null, null);
    }

    // ...
}

// ...

private void addAllyRowToLayout(String name, String casterLevel, String initMod)
{
    // Inflate the Ally Row
    View ally_layout_row = getLayoutInflater().inflate(R.layout.edit_profile_activity_ally_list_item, null, false);

    // EditText Name
    EditText name_edit_text = (EditText) ally_layout_row.findViewById(R.id.profile_edit_ally_name_edit_text);
    name_edit_text.setTextSize(14.0f);
    name_edit_text.setTextColor(Color.DKGRAY);
    if (name != null)
    {
        if (name.isEmpty() == false)
        {
            name_edit_text.setText(name);
        }
    }
    name_edit_text.addTextChangedListener(new TextWatcher()
    {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count)
        {
            invalidateOptionsMenu();
        }

        @Override
        public void afterTextChanged(Editable s) {}
    });

    // EditText Init Mod
    EditText init_mod_edit_text = (EditText) ally_layout_row.findViewById(R.id.profile_edit_ally_init_mod_edit_text);
    init_mod_edit_text.setTextSize(14.0f);
    init_mod_edit_text.setTextColor(Color.DKGRAY);
    if (initMod != null)
    {
        if (initMod.isEmpty() == false)
        {
            init_mod_edit_text.setText(initMod);
        }
    }

    // EditText Caster Level
    EditText caster_level_edit_text = (EditText) ally_layout_row.findViewById(R.id.profile_edit_ally_caster_level_edit_text);
    caster_level_edit_text.setTextSize(14.0f);
    caster_level_edit_text.setTextColor(Color.DKGRAY);
    if (casterLevel != null)
    {
        if (casterLevel.isEmpty() == false)
        {
            caster_level_edit_text.setText(casterLevel);
        }
    }

    // ImageButton Delete Ally Button
    ImageButton delete_button = (ImageButton) ally_layout_row.findViewById(R.id.profile_edit_delete_ally_button);
    delete_button.setOnClickListener(new View.OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            View parent_view = (View) v.getParent();
            if (parent_view != null)
            {
                mAllyLayout.removeView(parent_view);
            }
            if (mAllyLayout.getChildCount() == 0)
            {
                addAllyRowToLayout("", "", "");
            }
        }
    });

    // Add the Ally Row to the Ally Layout.
    mAllyLayout.addView(ally_layout_row);
}

Edit 1 There's an if statement in the activity's onCreate() that I failed to show when I first posted. if (allyLayout.getChildCount() <= 0) ...

Edit 2 Looking at this post gave me the idea to see what was happening in onRestoreInstanceState(Bundle savedInstanceState). Surprisingly to me, overriding it and making it empty, took care of my problem. I'm not sure if that's the most orthodox solution.

1 Answers1

0

After this line :

mAllyLayout = (LinearLayout) findViewById(R.id.profile_edit_ally_layout);

Check if your linear layout has some views.

   if (mAllyLayout.getChildCount()>0){
    //add your views

    }

Update If you don't want to handle data after rotation add this on your manifest:

<activity
            android:name="Your activity"
            android:configChanges="orientation|keyboardHidden|screenSize"/>
diegoveloper
  • 93,875
  • 20
  • 236
  • 194
  • Thanks for the feedback, diegoveloper. First, note that I made an edit to my post above. (There was an if statement in the code that I failed to include.) I tried out your recommendation, and this is what I see: When the page is first navigated to, there is a single empty row. (What I would expect.) If fill in the row and add some more rows with data then rotate the screen, it shows one row with the contents of the last row from before the rotation. This implies to me that some of the data from before the rotation is lingering and overriding the data I set on the second pass. – FreeMarketAnarchist Nov 15 '17 at 18:32
  • This seems to work. Thank you very much for your help! I've spent all day trying to solve this. I also noticed that overriding onRestoreInstanceState() and *not* calling the super class gave me the expected result as well. I still don't know specifically what it is the super class is doing though that causes the issue, but I can at least avoid it. – FreeMarketAnarchist Nov 15 '17 at 19:47