How to set Id of dynamic created layout?

AndroidAndroid View

Android Problem Overview


I want to give ID to some views (textview ,imageview etc) in a layout that is programmetically created. So what is the best way to set ID.

Android Solutions


Solution 1 - Android

You create an ids.xml file and place all your required ids in it as below

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

Now for your dynamically created layouts or views you can use these ids as below

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

I hope it may help you.

Solution 2 - Android

Google finally realized the need of generating unique IDs for programmatically created views...

From API level 17 and above, one can use View.generateViewId() like this:

view.setId(View.generateViewId());

For apps targeting API level 16 or lower, use ViewCompat.generateViewId() instead:

view.setId(ViewCompat.generateViewId());

Solution 3 - Android

create folder res/values/ids.xmland

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

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

in Activity class call like this

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

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

Solution 4 - Android

This wont work:

layout.setId(100);

But, this will:

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

also, this one too (credit: Aaron Dougherty):

layout.setId(100+1);

Solution 5 - Android

For compatibility purposes use: ViewCompat.generateViewId()

Solution 6 - Android

If you are putting a group of components repeatedly into a layout programmatically like below:

<LinearLayout>
      
      <ImageView>
      <TextView>
      <Button>
      
      <ImageView>
      <TextView>
      <Button>
    
      <ImageView>
      <TextView>
      <Button>
        
      ...
</LinearLayout>

then,you can use for loop and give ids accordingly:

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
}

Or if just one group of component you want to add,you can use any integer number which is large and don't conflict with other component's ids in Resources.It won't be much conflicting.

Solution 7 - Android

Try this code! This should help give an idea.

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>

here's the rest of code

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

}

As you can see ids were created in res -> values -> ids file.

when creating views dynamically id is the same for the views.

Each TextView share same id. Each Button share same id. each layout share same id.

Ids are only important to access the contents of views.

However the Tag is what makes each view unique to each other.

Hope this helps you out!

Solution 8 - Android

I went about it in a different way.
Created my own R.id HashMap.
Than used the value for the view.setID() part.
String is the id, Integer its value

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

and to set:

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

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

Now, at any point you can just:

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

and to test it -

    test.setImageResource(R.drawable.differentPic);

P.S. I've written it like this for ease of explain.
Obviously it can be written better andmore compact.

Solution 9 - Android

All you need to do is call ViewCompat.generateViewId()

For Example:

val textView = TextView(this)
textView.text = "Hello World"
textView.setLayoutParams(ViewGroup.LayoutParams(MATCH_PARENT, WRAP_CONTENT))
textView.id = ViewCompat.generateViewId()

Solution 10 - Android

You can define your Ids as resources and then use setId() of the view to set it. In a xml file, define the ID's like:

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

then, use in the java file as..

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionabhishek ametaView Question on Stackoverflow
Solution 1 - AndroidYugandhar BabuView Answer on Stackoverflow
Solution 2 - AndroidVarun BhatiaView Answer on Stackoverflow
Solution 3 - AndroidNagarjunaReddyView Answer on Stackoverflow
Solution 4 - AndroidjeetView Answer on Stackoverflow
Solution 5 - AndroidSanf0rdView Answer on Stackoverflow
Solution 6 - AndroidHiral VadodariaView Answer on Stackoverflow
Solution 7 - AndroidBernardo TrevinoView Answer on Stackoverflow
Solution 8 - AndroidRazVanView Answer on Stackoverflow
Solution 9 - AndroidLekeOpeView Answer on Stackoverflow
Solution 10 - AndroidKhawarView Answer on Stackoverflow