我遇到奇怪的行为,我怀疑是虫子,但也许我忽视了一些事情。帖子末尾的代码片段。我也可以发布.xml,但我认为没有必要理解这个问题。
我有一个水平线性布局,我根据玩家数量添加TableLayouts。
表格布局包含几个字段,TextView,EditText,Buttons等。
当我初始化每个TableLayout时,我将它添加到LinearLayout(通过xml膨胀),然后初始化字段。
问题是,EditText字段总是使用最后的玩家信息进行更新。据我所知,我对setText的调用正在传递给每个EditText。
我在父TableLayout上使用findViewById找到了EditText(实际上是祖父母,因为有一个TableRow。
EditText id在整个树中不是唯一的,但从表格布局的角度来看是唯一的。
可能的原因: 1)当我findById时,我得到了错误的EditText视图:但这不可能。我更改了我的代码以发布EditTextView的objectID我得到了一个TEXTVIEW我获得了唯一的对象ID。将完全相同的myEditText.toString()发布到EditText,我得到最后使用的对象ID的重复值。重申一下,只要字段是TextView,使用完全相同的findView逻辑就可以工作,只要它是EditText就会显示“多个”setText行为。
2)当我将字段从EditText更改为xml中的TextView,然后只需将我的强制转换从EditText更改为TextView时,一切都按预期运行。
3)在onClickListeners中进行的类似查找尝试的行为符合预期。
4)我尝试在初始化之前和之后将视图添加到线性布局 - 相同的行为。我想知道它是否是底层对象的操作顺序,因为它对听众起作用,但我仍然遗漏了一些东西。
问题:
1)这看起来像其他人的错误吗?
2)建议的解决方法?
3)当我在搜索我的顶级对象时,我知道为什么它在我的听众中工作,而不是在我的初始化代码中,我明确地拥有我的顶级对象(顶层对象是我膨胀的TableLayout。
代码链接:
onCreate初始化代码:
TableLayout tl = (TableLayout)inflater.inflate(R.layout.playerpanel, llayout, false);
InitializePlayer(player1,tl);
llayout.addView(tl);
InitializePlayer Snippet - 事情中断:
public void InitializePlayer(Player p, TableLayout tl)
{
players.add(p);
tl.setTag(p);
//INITIALIZE LISTENERS HERE - SNIPPED FOR READABILITY
TextView scoreLabel = (TextView)tl.findViewById(R.id.currentScore);
EditText curPoints = (EditText)tl.findViewById(R.id.scoreEntry);
curPoints.setText(p.getScore());
EditText playerEntry = (EditText)tl.findViewById(R.id.playerName);
playerEntry.setText(tl.toString());
//CONFIRMING UNIQUE OBJECTS HERE should actually be p.getScore()
scoreLabel.setText(playerEntry.toString());
ListView lv = (ListView)tl.findViewById(R.id.listView);
lv.setAdapter(new ArrayAdapter<String>(this,R.layout.list_item, p.getTurns() ));
运行的OnClickCode:
private OnClickListener addButtonListener = new OnClickListener() {
public void onClick(View v) {
// get all the objects I care about
TableRow tr = (TableRow)v.getParent();
TableLayout tl = (TableLayout)tr.getParent();
EditText ev = (EditText)tl.findViewById(R.id.scoreEntry);
Player pl = (Player)tl.getTag();
TextView scoreLabel = (TextView)tl.findViewById(R.id.currentScore);
pl.addScore(ev.getText().toString());
scoreLabel.setText(pl.getScore());
ListView lv = (ListView)tl.findViewById(R.id.listView);
ArrayAdapter aa = (ArrayAdapter)lv.getAdapter();
aa.notifyDataSetChanged();
InputMethodManager imm = (InputMethodManager)v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
EditText playerEntry = (EditText)tl.findViewById(R.id.playerName);
playerEntry.setText(playerEntry.toString());
}
};
答案 0 :(得分:9)
我遇到了类似的问题,当设备改变方向时,值会复制。我发现EditText正在保存它的状态并根据id恢复它。在我已经在小部件上设置了正确的值之后,此过程填充了相同的值。
我找到的解决方案是在XML上的小部件条目上设置android:saveEnabled="false"
。
答案 1 :(得分:1)
就像Victor说的那样:EditText的text-property根据ID进行恢复。 这发生在onRestoreInstanceState中。如果有多个具有相同ID的EditTexts,则会设置所有这些。
另一种解决方案是在Android设置后设置或覆盖这些值。 在调用super.onRestoreInstanceState之后,它位于onResume或onRestoreInstanceState中。 (如果是活动。我没有检查碎片)
在onCreate中设置值太早了。在这种情况下,它们将被覆盖。