sty*_*972 5 android view android-resources
View包含一个方法setId(int)。我的问题是,如何以编程方式为对象提供一个不与任何资源 ID 重叠的 ID R?
根据文档,View.generateViewId()在 API 级别 17 中添加将生成适合在setId(int). 此值不会与 aapt 在构建时生成的 ID 值冲突R.id。
我进行了试验以View.generateViewId()了解它的行为方式。这是我的发现。
generateViewId() 将保留返回的最后一个 ID,并将在整个应用程序生命周期中从那里继续。例如,如果设备旋转前的最后一个 ID 为 4,则旋转后的下一个 ID 为 5。重要的是要注意,例如,如果您在应用程序的onCreate()方法中通过generateViewId()每次调用在运行时设置视图,则在您的设备旋转后,默认情况下onCreate()会再次调用并且您的视图将收到与旋转前不同的 ID。
Android 有一项功能可以在设备旋转后自动恢复您的视图状态 - 例如,您输入到 EditText 视图中的文本,CheckBox 的选中状态 - 但它仅在视图具有持久 ID 时才有效。所以在上面的例子中,这种状态恢复是行不通的——你的 EditText 视图将丢失输入,你必须再次输入你需要输入的任何内容——因为视图每次生成时都会收到不同的 ID。要解决此问题,您需要在活动生命周期中维护 ID。
我发现 Android 为 XML 中定义的对象分配了数十亿的 ID。这是只有我的应用程序的几个预定义的标识采取了现实生活中的ID:2131427423.所以它看起来是相当安全的,以你自己的自由裁量权使用低标识而没有调用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);
}
}
}
Run Code Online (Sandbox Code Playgroud)