Reputation: 3852
The Context
My application architecture is very similar to the default called "Swipe Views" when you create a new android project. One activity, 3 Fragments, you can swipe through them. It uses the support library. everything is up to date. The device I'm testing on is a galaxy nexus running android 4.1.2 Support library r11, and SDK versions min=14 target=16
The Problem
The second Fragment holds a bunch of EditText which contain various numerical values read from sharedPreferences. When the Activity is first created, everything is fine the EditViews all have their correct value, but if I modify one of the values to, for instance 555, and then I rotate the device, all the EditText are now displaying 555 !
There is only one setText in the whole program and it is displayed later in this post, I tried to remove it, as expected when starting the activity all the EditTexts display the default value (666), I modify one and rotate the device, they all display the new value!
The details
One activity with a SectionsPagerAdapter, a ViewPager and several fragments for each page.
In one of the fragments (ConfigurationFragment) in the onViewCreated
method I dynamically create lines with and EditText
and an ImageButton
.
those lines are actually in a layout (xml file) which I inflate for each line to add, then I get the editText and call setText to set it's value to what it should be.
onViewCreated method:
public void onViewCreated(View view, Bundle savedInstanceState)
{
// populate ports list on view creation
ArrayList<String> listenPorts = mServerManagerThread.getListenPorts();
for (String port : listenPorts)
{
EditText v = ((EditText) addListenPortItem().getChildAt(0));
v.setText(port);
}
super.onViewCreated(view, savedInstanceState);
}
naturally the method getListenPorts
returns the same list each time it is called (on startup and when the device is rotated)
what addListenPortItem basically does:
// Instantiate a new "row" view.
final ViewGroup newView = (ViewGroup) LayoutInflater.from(viewGroup.getContext()).inflate(itemResource,
viewGroup, false);
// Set a click listener for the "X" button in the row that will remove
// the row.
newView.findViewById(R.id.delete_button).setOnClickListener(
new OnRemoveClickListener(mContainer, viewGroup, newView, emptyListTextResource));
viewGroup.addView(newView);
viewGroup is a linearLayout which will hold the newly created views itemResource is the following layout
layout of one line:
<?xml version="1.0" encoding="utf-8"?>
<!--
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="?android:listPreferredItemHeightSmall"
android:layout_marginTop="8dp"
android:divider="?android:dividerVertical"
android:dividerPadding="8dp"
android:gravity="right"
android:orientation="horizontal"
android:showDividers="middle" >
<EditText
android:id="@+id/editPort"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="number"
android:text="666" >
</EditText>
<ImageButton
android:id="@+id/delete_button"
style="?android:attr/borderlessButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/action_remove_item"
android:src="@drawable/content_remove" />
</LinearLayout>
any idea?
I've been staring at this bug for a couple hours now and I really have no clue what's going on ... I'm starting to suspect a bug in the SDK or the support library, but I know from experience the bug is most often in my brain :)
Upvotes: 2
Views: 2913
Reputation: 3852
I found the solution: I moved the code from onViewCreated to onViewStateRestored(..) so that filling the EditTexts with their value is done after the state has been restored.
The problem was that all the EditTexts have the same id so when restoring the state it was messing it up.
Upvotes: 4
Reputation: 72553
That's not a bug, so don't be worried. The problem is that if you rotate the screen the Activity and the Fragments will be recreated. onCreateView()
will be called again and this mixes things up and therefore you have such a weird behaviour. You can fix this by overriding these thwo methods:
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
// Read values from the "savedInstanceState"-object and put them in your textview
}
@Override
protected void onSaveInstanceState(Bundle outState) {
// Save the values you need from your textview into "outState"-object
super.onSaveInstanceState(outState);
}
Upvotes: 0