2013-03-02 29 views
6

Abbiamo cercato e lavorato su questo a lungo - senza fortuna. (Deve essere semplice Grazie per l'assist?.)Come eseguire findViewById (R.id. >> StringVarHere <<)?

Cercando di ottenere/impostare una schermata di testo EditTexts', ma non con il solito, molto più hard-coded:

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

Invece, Sto cercando di capire un modo riutilizzabile tramite una variabile che contiene il nome_stringa (String).

Nel codice pseudo:

findViewById (. R.id >> StringVarHere < <); // come farlo ?

ho provato anche questo metodo findViewById, ma non ha funzionato (!?)

//// 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") ; 
} 

Ho provato .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 ...   
     /> 

Come previsto, il gen 'file di R DE ha qualcosa di simile:

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

Sì, grazie - ha senso farlo nell'attività. Stavo cercando di evitare che diventasse troppo voluminoso. Ecco cosa sto facendo ora, basato sui suggerimenti utili di A e C. L'intenzione è di riportare tutto il testo dei campi di un modulo in una stringa []. (So ​​che potrei forza bruta anche tutti i campi.)

Cosa ne pensi di questo qui sotto - sembra molto simile al tuo suggerimento, madlymad? Mi chiedo se questo è un approccio di progettazione scadente?

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 

Poi dalla classe di attività, è solo:

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

Guardando la risposta SO che dici di aver provato, dovrebbe funzionare. Assicurati di fare tutto ciò dopo aver chiamato 'setContentView()' –

+0

Spiacente, "SO"? Cos'è quello ? ... sì, dimenticando di setContentView significa che non esiste un xml a cui fare riferimento :) ... –

+0

SO = "StackOverflow". Penso che dovresti pubblicare il processo che hai usato sia per il mio che per l'implementazione di quella risposta. Ho provato la mia implementazione e ha funzionato, quindi non sono sicuro del motivo per cui non funziona per te. –

risposta

3

Il modo in cui si possa fare è (mi pare di capire il modo in cui si sta cercando):

Questo può essere in non-attività (YourClassname.java):

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

in attività di classe:

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") ; 
     } 
    } 
} 

Ma penso che sia meglio codice nella classe di attività come:

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

grazie ancora madlymad - tu, Code-Guru e A-C mi hai aiutato a pensare che fosse --- molto apprezzato! –

2

AC ha suggerito qualcosa sulla falsariga di:

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

questo funziona - quando l'ho provato standalone in un test rig. Grazie ! Ancora non sono sicuro di cosa stesse facendo esplodere, ma ho il sospetto che gli oggetti Context o Resource non siano accessibili.

+0

Se non è attivo nella classe Attività, usare 'context.getResources(). GetIdentifier (field," id ", getPackageName());' – madlymad

+0

Grazie a madlymad: è esattamente quello che avevo nel mio OP! e il contesto era buono (AFAICT?) aveva passato il contesto nel costruttore delle classi di non attività - e context.getResources(). getIdentifier ... stava restituendo un id valido, ma quando ho provato a usarlo, ho ottenuto un'eccezione pntr nulla . ... –

+0

Vedi risposta sopra - (A parte Kev - grazie per aver sistemato il mis-post!) –

1

Si noti che i nomi delle variabili (come R.id.some_id) sono disponibili solo in fase di compilazione e non è possibile accedere da un valore di stringa in fase di esecuzione. Poiché questi ID sono dichiarati come int s, è possibile considerare l'utilizzo di un valore int[] o List<Integer> per memorizzare gli ID. A seconda di quanto sia dinamico il tuo layout e di cosa stai facendo con le Views in esso, potresti anche voler semplicemente creare le Views in fase di esecuzione e memorizzare un array o un elenco di esse senza utilizzare alcun id.

+1

grazie per il suggerimento Elenco - una buona idea ... il problema non era tanto di ottenere/salvare gli Id tanto quanto li stava usando a causa del fatto che il contesto non era a posto. - Kev spostò la mia risposta nel punto corretto anche sopra. –

+0

@HowardPautz Sono contento che tu l'abbia capito. Buona fortuna con la tua programmazione Android! E benvenuto in SO. –

+0

Code-Guru, grazie mille per la fortuna e l'accoglienza! Molto apprezzato come SO non è niente di meno che * sorprendente * ... praticamente ogni ricerca su Google su un bug, non importa quanto oscuro, trova COSI sulla cima dei successi! –

Problemi correlati