View
包含方法setId(int)
。我的问题是,如何以编程方式为对象提供一个不与R
中任何资源ID重叠的Id?
答案 0 :(得分:2)
根据documentation,API级别17中添加的View.generateViewId()
将生成适合setId(int)
使用的值。此值不会与构建时为a R.id
生成的ID值冲突。
我尝试使用View.generateViewId()
来了解它的行为方式。以下是我的发现。
generateViewId()
将保留最后返回的ID ,并将在整个应用生命周期内从那里继续。例如,如果设备旋转前的最后一个ID为4,则旋转后的下一个ID将为5。重要的是要注意,例如,如果您在应用的onCreate()
方法中通过每次在设备旋转后调用generateViewId()
来在运行时设置视图,请执行以下操作:再次调用默认onCreate()
,您的视图将获得与轮换前不同的ID 。
Android具有自动恢复视图状态的功能 - 例如,您输入EditText视图的文本,检查CheckBox的状态 - 设备轮换后,但只有在视图'拥有持久性ID 。因此,在上面的示例中,此状态恢复将不起作用 - 您的EditText视图将丢失输入,您必须键入您需要再次键入的内容 - 因为视图每次生成时都会收到不同的ID。 要解决此问题,您需要通过活动生命周期维护ID。
我发现Android为数十亿的XML中定义的对象分配ID。这是从我的应用程序中获取的具有几个预定义ID的真实身份ID:2131427423。因此似乎可以非常安全地自行判断使用低ID而无需调用generateViewId()
。在我的简单应用程序中,我通过分配从1开始的ID,增加1来模仿它,并且它起作用。这是一个从我的应用程序中提取的示例:
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);
}
}
}
答案 1 :(得分:-1)