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
?
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.)
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.
Id of a resource is uniq identifier , such as name of a variable. It should be uniq or you will have problems with names.
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.
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);
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With