Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Programatically create a resource id for a view

View contains a method setId(int). My question is, how to programatically supply the object an Id that does not overlap any resource id's in R?

like image 295
tyler Avatar asked May 15 '12 18:05

tyler


People also ask

How do I give my ID to a view?

Add an attribute of android:id="@+id/ somename " to your view. When your application is built, the android:id will be assigned a unique int for use in code. Reference your android:id 's int value in code using " R.id. somename" (effectively a constant.)

What is a resource ID in android?

For each type of resource, there is an R subclass (for example, R. drawable for all drawable resources) and for each resource of that type, there is a static integer (for example, R. drawable. icon ). This integer is the resource ID that you can use to retrieve your resource.

What is id value resource Android studio?

Id of a resource is uniq identifier , such as name of a variable. It should be uniq or you will have problems with names.


1 Answers

According to the documentation, View.generateViewId() added in API level 17 will generate a value suitable for use in setId(int). This value will not collide with ID values generated at build time by aapt for R.id.

I experimented with View.generateViewId() to find out how it behaves. Here are my findings.

  • Generated ID will begin from 1 and will be incremented by each time it is called (1, 2 , 3...)
  • generateViewId() will maintain the last ID returned and will continue from there throughout app life cycle. For example if last ID before device rotation was 4, next ID after rotation will 5.

It is important to note that, for instance, if you are setting up views at runtime in your app's onCreate() method by calling generateViewId() every time, after your device rotates, by default onCreate() is called again and your views will receive a different ID than before rotation.

Android has a feature to automatically restore your views state – for instance, text you enter into an EditText view, checked state of a CheckBox – after device rotation, but it only works if the views' have persistent IDs. So in the above example, this state restoration will not work – your EditText view will lose input and you have to type whatever you need to type in again – as views will receive a different ID every time they are generated. To work around this problem, you need to maintain IDs through activity life cycle.

I found out that Android assigns IDs for objects defined in XML in the magnitude of billions. This is a real life ID taken from my app having only a few predefined IDs: 2131427423. So it seems to be pretty safe to use low IDs on your own discretion without ever calling generateViewId(). In my simple app I mimicked it by assigning IDs beginning from 1, increasing by one, and it worked. Here is an example, extracted from my app:

public class MainActivity extends AppCompatActivity {
    // since our lastAllocatedViewId will reset on device rotation
    // regenerated views will receive the same ID
    private int lastAllocatedViewId = 0;

    private ArrayList<QuizQuestions> quizQuestions;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // read quizQuestions from xml at runtime;
        quizQuestions = parseQuizQuestionsXml();

        // we will dynamically add quiz question views to this view
        // depending on how many quizQuestions are in the XML config
        LinearLayout container = (LinearLayout) findViewById(R.id.quiz_questions_container);

        // generate a view for each quiz question
        for (int i = 0; i < quizQuestions.size(); i++) {
            LinearLayout quizQuestionView = (LinearLayout) inflater.inflate(R.layout.quiz_question_template, parent, false);

            quizQuestionView.setId(lastAllocatedViewId++);

            (...) // do some work on our newly generated view

            // then add it to the quiz questions container
            container.addView(quizQuestionView);
        }
    }
}
like image 120
Balázs Lengyák Avatar answered Sep 24 '22 03:09

Balázs Lengyák