Як встановити ідентифікатор динамічно створеного макета?


77

Я хочу надати ідентифікатор деяким представленням (текстовому, графічному та ін.) У макеті, який створений програмно. Тож який найкращий спосіб встановити ідентифікатор.

Відповіді:


128

Ви створюєте файл ids.xml і розміщуєте в ньому всі потрібні ідентифікатори, як показано нижче

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

Тепер для ваших динамічно створених макетів або подань ви можете використовувати ці ідентифікатори, як показано нижче

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

Сподіваюся, це може вам допомогти.


Шкода, це працює. Але все-таки ніколи не добре не пропускати декларації про кодування та версії xml.
Arnthor

19
@ Nordvind Я дав ідею abhishek ameta не повним рішенням. Він не згадав жодних вимог до версії Android. Декларація <? xml ...> - це основна річ, тому будь-який розробник Android буде писати у файлі * .xml. Мені сказали, що це буде працювати у всіх версіях android ?? Що не так з моїм кодом? Якщо у вас є однакові вимоги, ви використовуєте мою відповідь і у вас виникли проблеми, запитайте мене, не коментуйте так.
Югандхар Бабу,

1
@ Nordvind з іншим прикладом того, наскільки марною є система голосування SO. Шкода, що немає можливості відхилити коментарі.
Гленн Мейнард,

8
це все ще не пояснює, як встановити динамічно встановлений ідентифікатор
ghosh,

1
Сенс динамічно створюваних поглядів полягає в тому, що ви можете не знати, скільки / скільки з них вам знадобляться або коли вони вам знадобляться. Попереднє встановлення ідентифікаторів у ресурсах не допоможе.
ландрикапела

65

Google нарешті усвідомив необхідність створення унікальних ідентифікаторів для програмно створених подань ...

Починаючи з рівня 17 API і вище, можна використовувати View.generateViewId () таким чином:

view.setId(View.generateViewId());

Для програм, націлених на рівень API 16 або нижче, використовуйте ViewCompat.generateViewId()замість цього:

view.setId(ViewCompat.generateViewId());

6
Також ви можете використовувати, ViewCompat.generateViewId()якщо ви націлюєтесь на нижчий рівень API
Гірбод Бехнам

1
Це правильна відповідь і єдиний динамічний спосіб створення ідентифікатора.
Phani Rithvij

1
Як отримати доступ до того самого ідентифікатора, який я щойно створив?
Джевон

18

створити папку res/values/ids.xmlі

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

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

в класі активності дзвоніть так

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

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

4
Його запитали про динамічно створений макет.
Arnthor

1
ось як ---> створити папкуres/values/ids.xml
Помилки трапляються

15

Це не працює:

layout.setId(100);

Але це:

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

також і цей (кредит: Аарон Догерті):

layout.setId(100+1);

Як зазначалося тут , це рішення генерує помилку перевірки редактора (очікуваний ресурс ідентифікатора типу), але компілюється просто чудово.
adamdport

4
насправді це не так. Якщо ви робите int id = 100., мабуть, якщо ви складаєте цифри, це працює нормально. Не розумійте цього xD
Матеуш Вінницький

3
/ дякую @MateuszWinnicki, як не дивно додавання зробило різницю. setId (100) не працює, але setId (99 + 1) працює
Aaron Dougherty

@jeet чи можливо ідентифікатор 100 зіткнеться з іншим, який система автоматично встановить на 100?
YoussefDir

8

Для сумісності використовуйте: ViewCompat.generateViewId()


2

Якщо ви повторно вкладаєте групу компонентів у макет програмно, як показано нижче:

<LinearLayout>

      <ImageView>
      <TextView>
      <Button>

      <ImageView>
      <TextView>
      <Button>

      <ImageView>
      <TextView>
      <Button>

      ...
</LinearLayout>

тоді ви можете використовувати цикл for і відповідно надати ідентифікатори:

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
}

Або якщо ви хочете додати лише одну групу компонентів, ви можете використовувати будь-яке ціле число, яке є великим і не суперечить ідентифікаторам інших компонентів у ресурсах. Це не буде суперечливо.


3
як отримати значення textview та всіх інших компонентів? Будь ласка, детальніше розробіть.
Ананд Савяні

0

Спробуйте цей код! Це повинно допомогти дати уявлення.

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>

ось решта коду

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

}

Як бачите, ідентифікатори були створені у файлі res -> values ​​-> ids.

при динамічному створенні ідентифікаторів ідентичний ідентичний для переглядів.

Кожен TextView має однаковий ідентифікатор. Кожна кнопка має однаковий ідентифікатор. кожен макет має однаковий ідентифікатор.

Ідентифікатори важливі лише для доступу до вмісту подань.

Однак тег - це те, що робить кожен вигляд унікальним один для одного.

Сподіваюся, це вам допоможе!


0

Ви можете визначити свої ідентифікатори як ресурси, а потім використовувати setId()представлення для його встановлення. У файлі xml визначте ідентифікатор, наприклад:

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

потім, використовуйте у файлі Java як ..

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

0

Я пішов про це по-іншому.
Створив власну R.id HashMap.
Потім використано значення для частини view.setID ().
Рядок - це ідентифікатор, ціле його значення

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

і встановити:

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

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

Тепер у будь-який момент ви можете просто:

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

і перевірити -

    test.setImageResource(R.drawable.differentPic);

PS Я написав це так для зручності пояснення.
Очевидно, що це можна написати краще і більш компактно.


0

Все, що вам потрібно зробити - це зателефонувати ViewCompat.generateViewId()

Наприклад:

val textView = TextView(this)
textView.text = "Hello World"
textView.setLayoutParams(ViewGroup.LayoutParams(MATCH_PARENT, WRAP_CONTENT))
textView.id = ViewCompat.generateViewId()
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.