2011-12-31 18 views
5

Zdaję sobie dziwne zachowanie, podejrzewam błąd, ale być może coś przeoczam. Fragmenty kodu na końcu postu. Mogę również opublikować plik .xml, ale nie sądzę, że konieczne jest zrozumienie problemu.EditText setText() ustawia tekst na wielu widokach EditText

Mam poziomy układ liniowy, który dodaję TableLayouts do liczby graczy.

Układy tabela zawiera kilka pól, TextView, EditText, guziki itp

Kiedy zainicjować każdy TableLayout, dodaję go do LinearLayout (poprzez inflację xml), a następnie intialize pola.

Chodzi o to, że pola EditText zawsze otrzymują aktualne informacje o graczach. Z tego co wiem, moje wezwanie do setText jest przekazywane do każdego EditText.

jestem znalezienie EditText korzystając findViewById na rodzica TableLayout (właściwie dziadków ponieważ istnieje TableRow.

EditText id nie są unikalne w całym drzewie, ale są wyjątkowe z punktu widzenia układu tabeli.

Możliwe przyczyny: 1) Otrzymuję nieprawidłowy widok EditText, gdy znajdęBibl: Nie może to być jednak. Zmieniłem swój kod, aby opublikować objectID dla EditTextView otrzymuję IN A TEXTVIEW i otrzymuję unikalne identyfikatory obiektów. Przesłanie dokładnie tego samego myEditText.toString() do EditText i otrzymuję powtarzającą się wartość ostatniego używanego ID obiektu. Aby powtórzyć, użycie tej samej logiki findView działa zawsze, gdy pole jest TextView i wyświetla "wielokrotne" zachowanie setText za każdym razem, gdy jest to EditText.

2) Gdy zmienię pole z EditText na TextView w xml, a następnie po prostu zmieni moje rzutowanie z EditText na TextView, wszystko zachowuje się zgodnie z oczekiwaniami.

3) Podobne próby wyszukiwania wykonane w moich skryptach onClickListeners zachowują się zgodnie z oczekiwaniami.

4) Próbowałem dodać widok do układu liniowego przed inicjalizacji i po - takie samo zachowanie. Zastanawiałem się, czy to była kolejność operacji dla obiektów leżących u jej podstaw, ponieważ zadziałało to na słuchaczy, ale wciąż czegoś mi brakuje.

PYTANIA: 1) Czy to wygląda na błąd dla kogokolwiek innego? 2) Sugerowane sposoby obejścia problemu?
3) Dowolny pomysł, dlaczego działa on w moich słuchaczach, gdy szukam obiektu najwyższego poziomu, ale nie w kodzie inicjującym, w którym wyraźnie mam obiekt najwyższego poziomu (najwyższym obiektem jest TableLayout, który zawyżam)

fragmenty kodu:

onCreate Code intialization:

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

InitializePlayer krótkiego opisu - gdzie rzeczy złamać:

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 że działa:

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


    } 
}; 

Odpowiedz

9

miałem podobny problem, wartości były replikacji gdy urządzenie zmieniło orientację. Odkryłem, że EditText zapisuje stan i przywraca go na podstawie identyfikatora.Ten proces wypełniał te same wartości po tym, jak już ustawiłem poprawne wartości na widżetach.

Rozwiązaniem, które znalazłem, było ustawienie android:saveEnabled="false" na pozycji widżetu w pliku XML.

+0

Uratowałeś mój dzień! Dziękuję bardzo –

1

To tak jak powiedział Victor: Właściwość tekstowa EditText jest przywracana na podstawie identyfikatora. To dzieje się w onRestoreInstanceState. Jeśli istnieje wiele EditText o tym samym ID, wszystkie są ustawione.

Kolejnym rozwiązaniem jest ustawienie lub zastąpienie wartości po ustawieniu ich przez system Android. To jest w onResume lub w onRestoreInstanceState, po wywołaniu super.onRestoreInstanceState. (W przypadku aktywności, nie sprawdziłem fragmentów)

Ustawienie wartości w onCreate jest zbyt wcześnie. Zostaną one nadpisane w tym przypadku.