Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EditText setText() sets text on multiple EditText views

I am encountering odd behavior, I suspect bug, but perhaps I am overlooking something. Code Snippets at end of post. I can post the .xml as well, but I don't think it's necessary to understand the issue.

I have a horizontal linear layout, that I add TableLayouts to based upon number of players.

The table layouts contain several fields, TextView,EditText,Buttons etc.

When I initialize each TableLayout, I add it to the LinearLayout (via xml inflation) and then intialize the fields.

The thing is, the EditText fields always get updated with the last players info. From what I can tell, my call to setText is being passed to every EditText.

I am finding the EditText using findViewById on the parent TableLayout (actually the grandparent since there is a TableRow.

The EditText id's are not unique in the whole tree, but are unique from the table layout perspective.

Possible Reasons: 1) I am getting the wrong EditText View when I findById : This can't be it though. I changed my code to post the objectID for the EditTextView I get IN A TEXTVIEW and I get unique object IDs. Posting the exact same myEditText.toString() to an EditText and I get a repeating value of the last object ID used. To Reiterate, using the exact same findView logic works whenever the field is a TextView, and displays the "multiple" setText behavior whenever it is an EditText.

2) When I change the field from an EditText to a TextView in the xml, and then simply change my casts from EditText to TextView, everything behaves as expected.

3) Similar lookup attempts done in my onClickListeners behave as expected.

4) I've tried adding the view to the linear layout before initialization and after - same behavior. I was wondering if it were an order of operations thing for the underlying objects since it worked on the listeners, but I'm still missing something.

QUESTIONS: 1) Does this look like a bug to anyone else? 2) Suggested workarounds?
3) Any idea why it works in my listeners when I'm searching for my top level object, but not in my initialization code, where I explicitly have my top level object (top level object being the TableLayout that I inflated.

CODE SNIPPETS:

onCreate Intialization Code:

TableLayout tl = (TableLayout)inflater.inflate(R.layout.playerpanel, llayout, false);
InitializePlayer(player1,tl);
llayout.addView(tl);

InitializePlayer Snippet - where things break:

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 that does work:

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


    }
};
like image 937
akameswaran Avatar asked Dec 31 '11 14:12

akameswaran


2 Answers

I had a similar problem, the values were replicating when the device changed orientation. I found out that the EditText is saving it's state and restoring it based on the id. This process was filling the same values after I had already set the correct values on the widgets.

The solution I found was to set android:saveEnabled="false" on the widget entry on the XML.

like image 93
Victor Bogado Avatar answered Oct 14 '22 18:10

Victor Bogado


It's as Victor said: The text-property of the EditText is restored based on the ID. This happens in onRestoreInstanceState. If there are multiple EditTexts with the same ID, all of them are set.

So another solution is to set or overwrite the values after Android has set them. This is either in onResume or in onRestoreInstanceState, after super.onRestoreInstanceState was called. (In case of an Activity. I did not check for Fragments)

Setting the values in onCreate is too early. They will be overwritten in this case.

like image 40
user2808624 Avatar answered Oct 14 '22 18:10

user2808624