2013-03-02 11 views
6

Szukanie i praca nad tym długo - bez powodzenia. (Musi to być proste Dzięki za pomoc?).Jak zrobić findViewById (R.id. >> StringVarHere <<)?

Próbuje/ustawić ekran pełnego tekstu EditTexts', ale nie ze zwykłym, bardziej zakodowany sposób:

... findViewById (R.id.SomeTextWidgetId) ; 

Zamiast Próbuję wymyślić sposób wielokrotnego użytku za pośrednictwem zmiennej gospodarstwa (String) name_of_widget.

W kodzie psuedo:

findViewById (. R.id >> StringVarHere < <); // jak to zrobić ?

Próbowałem również tej metody findViewById, ale to nie działa (!?)

//// given: 

static final String FIELD_TV_FEE = "TextViewFee" ; 
static final String FIELD_TV_FOO = "TextViewFoo" ; 
static final String FIELD_TV_FUM = "TextViewFum" ; 
//// and some arbitrary number more of similar fields 

static final String [] ALL_FIELDS = { 

    FIELD_TV_FEE , 
    FIELD_TV_FOO , 
    FIELD_TV_FUM // ... 
} ; 

//// ... 

    //// this part works 
    int ResourceID; 
    String stringVarHere = FIELD_TV_FEE; 

    //// outputs a correct id, say '0x7f05000f' as in R.id.xxx below 
    ResourceID = context 
         .getResources() 
         .getIdentifier (stringVarHere, 
             "id", 
             context 
              .getApplicationInfo() 
              .packageName 
            ) ; 
    Log.d ("MyClass" , "RESID = " + Integer.toHexString(ResourceID)) ; 
/* 
* that's where I'm stuck ^^^ ... how do I do: 
*/ 

String field_name ; 

for (field_name : ALL_FIELDS) { 
    (EditText) SomethingLike_a_findViewById(field_name).setText ("Hello Wurld") ; 
} 

Próbowałem .setId ...

//// details 

    <!-- excerpt from working xml layout --> 
    <EditText 
     android:id="@+id/TextViewFee" 
     android:inputType="text" 
     android:layout ... etc ...   
     /> 
    <EditText 
     android:id="@+id/TextViewFoo" 
     android:inputType="text" 
     android:layout ... etc ...   
     /> 
    <EditText 
     android:id="@+id/TextViewFum" 
     android:inputType="text" 
     android:layout ... etc ...   
     /> 

Zgodnie z oczekiwaniami, gen „ed plik R ma coś takiego:

// ... 
public static final class id { 
    public static final int TextViewFee=0x7f05000f; 
    public static final int TextViewFum=0x7f05001c; 
    public static final int TextViewFoo=0x7f05001d; 
    // ... etc 

Tak, dziękuję - to ma sens, aby zrobić to w działaniu. Próbowałem powstrzymać to przed dostawaniem zbyt dużego kodu. Oto, co teraz robię, na podstawie pomocnych sugestii twojego i A-C. Chodzi o to, aby cały tekst pól formularza ponownie znalazł się w jednym ciągu []. (Wiem, że mógłbym brutalnie wymusić wszystkie pola.)

Co o tym wszystkim sądzisz - wydaje się bardzo podobne do twojej sugestii, madlymad? Zastanawiam się, czy to jest kiepskie podejście do projektowania?

public class FoodBar { 

private Activity activity; 
private Context ctx; 

public FoodBar (Activity _activity) {   
    this.activity = _activity; 
    this.ctx = this.activity.getApplicationContext() ; 
} 

public String[] getTextFromAllEditTexts() { // the UI views 

    int res_id = 0; 
    int i = 0; 

    String [] retValues = new String [MyClassName.ALL_FIELDS_LENGTH] ; 

    for (String field : MyClassName.ALL_FIELDS_ALL_VEHICLES) { 

     res_id = this.ctx.getResources() 
         .getIdentifier (field, "id", this.ctx.getPackageName()); 

      ((EditText) this.activity 
          .findViewById (res_id)) 
          .setText("Meat and Potatoes") ; 

       // redundant - get it right back to make sure it really went in ! 
     retVal[i++] = ((EditText) this.activity 
             .findViewById (res_id)) 
             .getText().toString() ; 
    } 

    return retVal; 

} // end func 
} // end class 

Następnie z klasy aktywny, to po prostu:

String [] theFields = null; 
FoodBar = new FoodBar (this); 

try { 

    theFields = FoodBar.getTextFromAllEditTexts(); 

} catch (Exception e) { 
    Log.d ("OOPS", "There's a big mess in the Foodbar: " + e.toString()); 
} 
+0

Patrząc na odpowiedź SO, o której mówisz, że próbowałeś, powinna działać. Po prostu upewnij się, że zrobisz to wszystko po wywołaniu 'setContentView()' –

+0

Przepraszam, "SO"? Co to jest ? ... tak, zapominając ustawićContentView oznacza, że ​​nie ma tam xml, do którego należy się odnieść :) ... –

+0

SO = "StackOverflow". Myślę, że powinieneś opublikować wersję próbną, w której używałeś albo mojej, albo tej implementacji odpowiedzi. Próbowałem mojej implementacji i działało, więc nie jestem pewien, dlaczego to nie działa. –

Odpowiedz

3

Sposób można zrobić to (jak rozumiem sposób próbujesz):

To może być w nie-aktywność (YourClassname.Java):

public static int getMyId(Context context, String field) { 
    return context.getResources().getIdentifier (field, "id", context.getPackageName()); 
} 

aktywności klasy:

for (String field_name : YourClassname.ALL_FIELDS) { 
    int resid = YourClassname.getMyId(context, field_name); 
    if(resid != 0) { // 0 = not found 
     EditText et = (EditText) findViewById(resid); 
     if (et != null) { 
      et .setText ("Hello Wurld") ; 
     } 
    } 
} 

Ale myślę, że lepiej jest kod w klasie aktywności jak:

String packageName = getPackageName(); 
Resources res = getResources(); 
for (String field_name : YourClassname.ALL_FIELDS) { 
    int resid = res.getIdentifier (field_name, "id", packageName); 
    if(resid != 0) {// 0 = not found 
     EditText et = (EditText) findViewById(resid); 
     if (et != null) { 
      et .setText ("Hello Wurld") ; 
     } 
    } 
} 
+0

jeszcze raz dziękuję madlymad - ty, Code-Guru i A-C pomógł mi przemyśleć to - bardzo doceniane! –

2

AC zasugerował coś wzdłuż linii:

res_id = getResources().getIdentifier (field, "id", getPackageName()); 
((EditText)findViewById (res_id)).setText("NoLongerFubar"); 

to działa - kiedy próbowałem go samodzielnie w teście takielunek. Dzięki ! Nadal nie jestem pewien, co wysadziło w powietrze, ale podejrzewam, że nie były dostępne elementy Kontekstu lub Zasoby.

+0

Jeśli nie w klasie Activity, użyj 'context.getResources(). GetIdentifier (pole," id ", getPackageName());' – madlymad

+0

Dzięki madlymad - to jest dokładnie to, co miałem w moim OP! a kontekst był dobry (AFAICT?) przeszedł kontekst do konstruktora klas niezwiązanych z działaniem - i context.getResources(). getIdentifier ... zwracał poprawny identyfikator, ale gdy próbowałem go użyć, otrzymałem wyjątek null pntr . ... –

+0

Zobacz odpowiedź powyżej - (Poza Kev - dzięki za naprawienie niewłaściwego wpisu!) –

1

Należy pamiętać, że nazwy zmiennych (takie jak R.id.some_id) są dostępne tylko w czasie kompilacji i nie można uzyskać do nich dostępu z wartości String w czasie wykonywania. Ponieważ te identyfikatory są zadeklarowane jako int s, możesz rozważyć użycie int[] lub List<Integer> do przechowywania identyfikatorów. W zależności od tego, jak dynamiczny jest twój układ i co robisz z widokami w nim zawartymi, możesz nawet po prostu utworzyć Widoki w czasie wykonywania i przechowywać tablicę lub Listę bez użycia jakichkolwiek identyfikatorów.

+1

dzięki za sugestię List - dobry pomysł ... problem polegał nie tyle na uzyskiwaniu/zapisywaniu identyfikatorów, ile na ich używaniu z powodu braku kontekstu. - Kev przeniósł moją odpowiedź również na właściwe miejsce. –

+0

@HowardPautz Cieszę się, że to wymyśliłeś. Powodzenia w programowaniu Androida! Witamy w SO. –

+0

Code-Guru, dziękuję bardzo za szczęście i powitanie! Bardzo doceniane jako SO jest niczym innym niż * niesamowite * ... praktycznie każde wyszukiwanie Google na temat błędu, bez względu na to, jak niejasne, znajduje SO na szczycie hity! –

Powiązane problemy