6

これを長い間検索して取り組んでいました-運が悪い. (簡単でしょう?助けてくれてありがとう。)

EditTexts のテキストでいっぱいの画面を取得/設定しようとしていますが、通常のよりハードコードされた方法ではありません:

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

代わりに、(String) name_of_widget を保持する変数を介して再利用可能な方法を見つけようとしています。

擬似コード:

findViewById (R.id.>> StringVarHere << ); // どうやってするか ?

このfindViewByIdメソッドも試してみましたが、うまくいきませんでした(!?)

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

私は.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 ...         
        />

予想どおり、生成された R ファイルには次のようなものがあります。

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

はい、ありがとうございます。アクティビティでそれを行うのは理にかなっています。コードがかさばりすぎないようにしていました。あなたとACの有益な提案に基づいて、私が今していることは次のとおりです。その意図は、フォームのフィールドのすべてのテキストを 1 つの String[] に戻すことです。(すべてのフィールドをブルートフォースできることも知っています。)

以下のこれについてどう思いますか - あなたの提案に非常に似ているように思えますか? これが悪い設計アプローチであるかどうか疑問に思っていますか?

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

次に、Activity クラスからは、次のようになります。

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

3 に答える 3

3

あなたがそれをすることができる方法は(私があなたが試みている方法を理解しているように):

これは非アクティビティ(YourClassname.java)にある可能性があります。

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

アクティビティクラス:

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

しかし、次のようなアクティビティクラスでコーディングする方が良いと思います。

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") ;
       }
    }
}
于 2013-03-02T23:57:59.460 に答える
2

AC は、次の行に沿って何かを提案しました。

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

これは機能します-テストリグでスタンドアロンで試したとき。ありがとう !何が爆発したのかはまだわかりませんが、Context または Resource アイテムにアクセスできなかったのではないかと思います。

于 2013-03-02T23:05:57.533 に答える
1

変数名 ( などR.id.some_id) はコンパイル時にのみ使用可能であり、実行時に String 値からアクセスできないことに注意してください。これらの ID は として宣言されているため、 orを使用して ID を格納するintことを検討してください。レイアウトがどの程度動的で、その中のビューで何をしているかによっては、実行時に単純にビューを作成し、id をまったく使用せずにそれらの配列またはリストを保存することもできます。int[]List<Integer>

于 2013-03-03T00:45:48.037 に答える