Wie lege ich die ID des dynamisch erstellten Layouts fest?


77

Ich möchte einigen Ansichten (Textansicht, Bildansicht usw.) in einem programmgesteuert erstellten Layout eine ID geben. Was ist der beste Weg, um die ID festzulegen?

Antworten:


128

Sie erstellen eine ids.xml-Datei und platzieren alle erforderlichen IDs wie folgt darin

<?xml version="1.0" encoding="utf-8"?>
<resources>
        <item type="id" name="layout1" />
        <item type="id" name="layout2" />
        <item type="id" name="layout3" />
</resources>

Für Ihre dynamisch erstellten Layouts oder Ansichten können Sie diese IDs wie folgt verwenden

new_layout1.setId(R.id.layout1);
new_view2.setId(R.id.layout2);
new_layout3.setId(R.id.layout3);

Ich hoffe es kann dir helfen.


Mein schlechtes, es funktioniert. Trotzdem ist es nie gut, Codierungs- und XML-Versionsdeklarationen nicht wegzulassen.
Arnthor

19
@Nordvind Ich gab eine Idee zu Abhishek Ameta nicht vollständige Lösung. Er erwähnte keine Anforderungen an die Android-Version. <? xml ...> Deklaration ist eine grundlegende Sache, daher schreibt jeder Android-Entwickler in die * .xml-Datei. Wurde mir gesagt, dass es in allen Versionen von Android funktionieren wird? Was ist los mit meinem Code? Wenn Sie die gleiche Anforderung haben, verwenden Sie meine Antwort und haben Probleme, fragen Sie mich, kommentieren Sie nicht so.
Yugandhar Babu

1
@Nordvind mit einem weiteren Beispiel dafür, wie nutzlos das Abstimmungssystem von SO ist. Schade, dass es keine Möglichkeit gibt, Kommentare abzustimmen.
Glenn Maynard

8
Dies erklärt immer noch nicht, wie man eine dynamisch erstellte ID setzt
Ghosh

1
Wenn Sie dynamisch erstellte Ansichten haben, wissen Sie möglicherweise nicht, wie viele / viele davon Sie benötigen oder wann Sie sie benötigen. Das Voreinstellen der IDs in Ressourcen würde nicht viel helfen.
Landrykapela

62

Google erkannte schließlich die Notwendigkeit, eindeutige IDs für programmgesteuert erstellte Ansichten zu generieren ...

Ab API-Level 17 und höher kann View.generateViewId () wie folgt verwendet werden :

view.setId(View.generateViewId());

4
Sie können auch verwenden, ViewCompat.generateViewId()wenn Sie auf eine niedrigere API-Ebene
abzielen

1
Dies ist die richtige Antwort und die einzige dynamische Methode zum Erstellen einer ID.
Phani Rithvij

18

Ordner erstellen res/values/ids.xmlund

<?xml version="1.0" encoding="utf-8"?>

<resources>   
   <item name="refresh" type="id"/>   
   <item name="settings" type="id"/>        
</resources>

in der Aktivitätsklasse so aufrufen

ImageView refreshImg = new ImageView(activity);
ImageView settingsImg = new ImageView(activity); 

     refreshImg.setId(R.id.refresh);
     settingsImg .setId(R.id.settings);

4
Es wurde nach dynamisch erstellten Layouts gefragt .
Arnthor

1
So ---> Ordner erstellenres/values/ids.xml
Bugs Happen

15

Das wird nicht funktionieren:

layout.setId(100);

Aber das wird:

int id=100;
layout.setId(id);

auch dieser (Kredit: Aaron Dougherty):

layout.setId(100+1);

Wie hier erwähnt , generiert diese Lösung einen Editor-Validierungsfehler (erwartete Ressource vom Typ id), der jedoch problemlos kompiliert werden kann.
Adamdport

4
Eigentlich nicht. Wenn Sie int id = 100 tun, funktioniert es anscheinend gut, wenn Sie Zahlen addieren. Verstehe das nicht xD
Mateusz Winnicki

3
/ danke @MateuszWinnicki, seltsamerweise machte das Hinzufügen den Unterschied. setId (100) funktioniert nicht, aber setId (99 + 1) funktioniert
Aaron Dougherty

@jeet ist es möglich, dass die ID 100 mit einer anderen kollidiert, die vom System automatisch auf 100 gesetzt wird?
YoussefDir

8

Verwenden Sie aus Kompatibilitätsgründen: ViewCompat.generateViewId()


2

Wenn Sie eine Gruppe von Komponenten wiederholt programmgesteuert wie folgt in ein Layout einfügen:

<LinearLayout>

      <ImageView>
      <TextView>
      <Button>

      <ImageView>
      <TextView>
      <Button>

      <ImageView>
      <TextView>
      <Button>

      ...
</LinearLayout>

Dann können Sie for-Schleife verwenden und IDs entsprechend angeben:

for(int i=0;i<totalGroups;i++)
{
    ImageView img;
    TextView tv;
    Button b;

    ... // set other properties of above components

    img.setId(i);
    tv.setId(i);
    b.setId(i);

    ... //handle all events on these components here only

    ... //add all components to your main layout
}

Oder wenn Sie nur eine Gruppe von Komponenten hinzufügen möchten, können Sie eine beliebige Ganzzahl verwenden, die groß ist und nicht mit den IDs anderer Komponenten in Resources in Konflikt steht. Es wird keine großen Konflikte geben.


3
Wie rufe ich Werte der Textansicht und aller anderen Komponenten ab? Bitte erläutern Sie mehr.
Anand Savjani

0

Versuchen Sie diesen Code! Dies sollte helfen, eine Idee zu geben.

activity_prac_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:orientation="vertical">

<TextView
    android:text="@string/edit_message"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/display_txt"
    android:textStyle="bold"
    android:textSize="18sp"
    android:textAlignment="center"
    android:layout_gravity="center_horizontal"/>

<GridLayout
    android:id="@+id/my_grid"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:rowCount="4">


<LinearLayout
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/linear_view">

    <Button
        android:text="@string/button_send"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/my_btn"
        android:layout_gravity="center_horizontal"/>

    <TextView
        android:text="@string/edit_message"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/my_txt"
        android:textSize="18sp"
        />

</LinearLayout>
</GridLayout>
</LinearLayout>

Hier ist der Rest des Codes

 public class AnotherActivity extends AppCompatActivity {

private int count = 1;

List<Integer> gridArray;
private TextView myDisplayText;
@Override
protected void onCreate( Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    gridArray = new ArrayList<>();
    gridArray.add(Integer.valueOf(1));
    setContentView(R.layout.activity_prac_main);



    findViews();


}
private void findViews(){

    GridLayout gridLayout = (GridLayout)findViewById(R.id.my_grid);
    gridLayout.setColumnCount(4);
    LinearLayout linearLayout = (LinearLayout) gridLayout.findViewById(R.id.linear_view);
    linearLayout.setTag("1");
    Button myButton = (Button) linearLayout.findViewById(R.id.my_btn);
    myButton.setTag("1");
    TextView myText = (TextView) linearLayout.findViewById(R.id.my_txt);
    myText.setText("1");

    myDisplayText = (TextView) findViewById(R.id.display_txt);


    myButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            TextView txt = (TextView) view;
            myDisplayText.setText("PRESS " + txt.getTag().toString());
            if(count < 24) {

                createView();
            }
            else{
                dialogBox();
            }
        }
    });
}

private void createView(){

    LinearLayout ll = new LinearLayout(this);
    ll.setId(Integer.valueOf(R.id.new_view_id));
    ll.setTag(String.valueOf(count+1));

    Button newBtn = createButton();
    newBtn.setId(Integer.valueOf(R.id.new_btn_id));
    newBtn.setTag(String.valueOf(count+1));

    TextView txtView = createText();
    txtView.setId(Integer.valueOf(R.id.new_txt_id));
    txtView.setTag(String.valueOf(count+1));
    txtView.setText(String.valueOf(count+1));

    GridLayout gridLayout = (GridLayout)findViewById(R.id.my_grid);


   ll.addView(newBtn);
    ll.addView(txtView);
    ll.setOrientation(LinearLayout.VERTICAL);

    gridLayout.addView(ll);



        count++;

}

private Button createButton(){
    Button myBtn = new Button(this);
    myBtn.setText(R.string.button_send);
    myBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            TextView txt = (TextView) view;
            myDisplayText.setText("PRESS " + txt.getTag().toString());
            if(count < 24) {

                createView();
            }
            else{
                dialogBox();
            }
        }
    });


    return myBtn;
}
public void dialogBox() {
    AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
    alertDialogBuilder.setMessage("GRID IS FULL!");
    alertDialogBuilder.setPositiveButton("DELETE",
            new DialogInterface.OnClickListener() {

                @Override
                public void onClick(DialogInterface arg0, int arg1) {
                    GridLayout gridLayout = (GridLayout)findViewById(R.id.my_grid);
                    gridLayout.removeAllViews();
                    count = 0;
                    createView();

                }
            });

    alertDialogBuilder.setNegativeButton("CANCEL",
            new DialogInterface.OnClickListener() {

                @Override
                public void onClick(DialogInterface arg0, int arg1) {

                }
            });

    AlertDialog alertDialog = alertDialogBuilder.create();
    alertDialog.show();
}
private TextView createText(){
    TextView myTxt = new TextView(this);
    myTxt.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);

    return myTxt;
}

}

Wie Sie sehen können, wurden IDs in der Datei res -> values ​​-> ids erstellt.

Beim dynamischen Erstellen von Ansichten ist die ID für die Ansichten identisch.

Jede TextView hat dieselbe ID. Jeder Button hat dieselbe ID. Jedes Layout hat dieselbe ID.

IDs sind nur wichtig, um auf den Inhalt von Ansichten zuzugreifen.

Das Tag macht jedoch jede Ansicht für sich einzigartig.

Hoffe das hilft dir weiter!


0

Sie können Ihre IDs als Ressourcen definieren und dann mithilfe setId()der Ansicht festlegen. Definieren Sie in einer XML-Datei die IDs wie folgt:

<resources>
  <item type="id">your id name</item>
</resources>

Verwenden Sie dann in der Java-Datei als ..

layout.setId(R.id.<your id name>)

0

Ich habe es anders gemacht.
Erstellt meine eigene R.id HashMap.
Dann wurde der Wert für den Teil view.setID () verwendet.
String ist die ID, Integer sein Wert

Private HashMap<String, Integer> idMap= new HashMap<String, Integer>();
private int getRandomId(){

    boolean notInGeneralResourses = false;
    boolean foundInIdMap = false;

    String packageName = mainActivity.getPackageName();
    Random rnd = new Random();
    String name ="";

    //Repaet loop in case random number already exists
    while(true) {

        // Step 1 - generate a random id
        int generated_id = rnd.nextInt(999999);

        // Step 2 - Check R.id
        try{
            name = mainActivity.getResources().getResourceName(generated_id);
        }catch(Exception e){
            name = null;
        }

        notInGeneralResourses = false;
        if (name == null || !name.startsWith(packageName)) {
            notInGeneralResourses = true;
        }else{
            notInGeneralResourses = false;
            localLog("Found in R.id list.");
        }

        // Step 3 - Check in id HashMap
        if(notInGeneralResourses){
            List<Integer> valueList = new ArrayList<Integer>(idMap.values());

            foundInIdMap = false;
            for (Integer value : valueList) {
                if (generated_id == value) {
                    foundInIdMap = true;
                    localLog("Found in idMAp.");
                }
            }
        }

        // Step 4 - Return ID, or loop again.
        if (!foundInIdMap) {
            localLog("ID clear for use. "+generated_id);
            return generated_id;
        }
    }
}

und zu setzen:

 String idName = "someName";
 int generated_R_id = getRandomId();
 idMap.put(idName,generated_R_id);

 someView.setId(idMap.get(idName));

Jetzt können Sie jederzeit einfach:

ImageView test = (ImageView) 
mainActivity.findViewById(idMap.get("somName"));

und um es zu testen -

    test.setImageResource(R.drawable.differentPic);

PS Ich habe es so geschrieben, um es einfacher zu erklären.
Offensichtlich kann es besser und kompakter geschrieben werden.


0

Alles was Sie tun müssen, ist anzurufen ViewCompat.generateViewId()

Zum Beispiel:

val textView = TextView(this)
textView.text = "Hello World"
textView.setLayoutParams(ViewGroup.LayoutParams(MATCH_PARENT, WRAP_CONTENT))
textView.id = ViewCompat.generateViewId()
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.