上下文
当您创建新的Android项目时,我的应用程序体系结构与默认名为“Swipe Views”的默认设置非常相似。 一个活动,3个碎片,你可以刷过它们。它使用支持库。 一切都是最新的。 我正在测试的设备是运行android 4.1.2的galaxy nexus 支持库r11和SDK版本min = 14 target = 16
问题
第二个片段包含一堆EditText,其中包含从sharedPreferences读取的各种数值。首次创建Activity时,一切都很好,EditViews都有正确的值,但如果我修改其中一个值,例如555,然后我旋转设备,所有EditText现在都显示555!
整个程序中只有一个 setText,它会在本文后面显示,我试图将其删除,正如预期的那样,在启动活动时,所有EditTexts都会显示默认值(666) ,我修改一个并旋转设备,它们都显示新值!
详情
一个活动包含SectionsPagerAdapter,一个ViewPager和每个页面的几个片段。
在onViewCreated
方法的一个片段(ConfigurationFragment)中,我使用EditText
和ImageButton
动态创建行。
这些行实际上是一个布局(xml文件),我为每一行添加膨胀,然后我得到editText并调用setText将它的值设置为它应该是什么。
onViewCreated方法:
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);
}
自然方法getListenPorts
每次调用时都会返回相同的列表(在启动时和旋转设备时)
addListenPortItem基本上做什么:
// 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是一个linearLayout,它将保存新创建的视图 itemResource是以下布局
一行布局:
<?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>
任何想法?
我一直盯着这个bug几个小时了,我真的不知道发生了什么......我开始怀疑SDK或支持库中的一个错误,但我从经验中知道虫子最常出现在我的大脑中:))
答案 0 :(得分:4)
我找到了解决方案:我将代码从onViewCreated移动到onViewStateRestored(..),以便在状态恢复后填充EditTexts及其值。
问题是所有的EditTexts都有相同的id,因此在恢复状态时它会弄乱它。
答案 1 :(得分:0)
这不是一个错误,所以不要担心。问题是如果旋转屏幕,将重新创建活动和碎片。 onCreateView()
将再次被调用,这会混淆,因此你会有这样一种奇怪的行为。你可以通过覆盖这两种方法来解决这个问题:
@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);
}