EditText setText() 在多个EditText视图上设置文本

5
我遇到了奇怪的行为,我怀疑是bug,但也许我忽略了什么。代码片段在帖子末尾。我可以发布.xml文件,但我认为不需要理解问题。
我有一个水平线性布局,根据玩家数量添加TableLayouts。
表格布局包含几个字段,TextView、EditText、Buttons等等。
当我初始化每个TableLayout时,我将其添加到LinearLayout中(通过xml膨胀),然后初始化字段。
问题是,EditText字段总是更新为最后一个玩家的信息。从我所知道的来看,我的setText调用被传递给每个EditText。
我使用findViewById在父TableLayout上查找EditText。实际上是祖父级别,因为有一个TableRow。
EditText的id在整个树中不是唯一的,但从表格布局的角度来看是唯一的。
可能的原因: 1)我在findById时获取了错误的EditText视图:虽然如此,但这不可能。我改变了我的代码以发布我得到的EditTextView的objectID IN A TEXTVIEW,并且我得到了唯一的objectID。将完全相同的myEditText.toString()发布到EditText中,我会得到一个重复使用的最后一个object ID的值。再次强调,使用完全相同的findView逻辑,每当字段是TextView时都有效,并且每当它是EditText时显示“多”setText行为。
2)当我将字段从EditText更改为TextView时,并且简单地将我的转换从EditText更改为TextView时,一切都表现得像预期的那样。
3)在我的onClickListeners中进行的类似查找尝试表现正常。
4)我尝试在初始化之前和之后将视图添加到线性布局中-相同的行为。我想知道是否它是基础对象的操作顺序问题,因为它在侦听器上工作了,但我仍然缺少一些东西。
问题: 1)这对其他人来说看起来像一个bug吗? 2)建议的解决方法? 3)为什么当我在搜索我的顶级对象时,它在我的侦听器中工作,但在我的初始化代码中不工作,其中我明确有我的顶级对象(顶级对象是我膨胀的TableLayout)。
代码片段:
onCreate Intialization Code:
TableLayout tl = (TableLayout)inflater.inflate(R.layout.playerpanel, llayout, false);
InitializePlayer(player1,tl);
llayout.addView(tl);

初始化播放器代码片段 - 出现问题的地方:

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() ));

点击事件代码示例:

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());


    }
};
2个回答

9
我遇到了类似的问题,当设备改变方向时,值会复制。我发现EditText会根据id保存和恢复其状态。这个过程会在我已经在小部件上设置正确值之后填充相同的值。
我找到的解决方案是在XML中对小部件条目设置android:saveEnabled="false"

你救了我的一天!非常感谢你。 - Dr TJ

1

正如Victor所说:EditText的文本属性是基于ID进行恢复的。这发生在onRestoreInstanceState中。如果有多个具有相同ID的EditText,则会全部设置。

因此,另一种解决方案是在Android设置完后设置或覆盖值。这要么在onResume中,要么在super.onRestoreInstanceState被调用后的onRestoreInstanceState中。(对于Activity而言。我没有检查Fragments)

在onCreate中设置值太早了。在这种情况下,它们将被覆盖。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接