5

View包含一个方法setId(int)。我的问题是,如何以编程方式为对象提供一个不与任何资源 ID 重叠的 ID R

4

1 回答 1

5

根据文档View.generateViewId()在 API 级别 17 中添加会生成一个适合在setId(int). 此值不会与 aapt for 在构建时生成的 ID 值冲突R.id

我进行了实验View.generateViewId()以了解它的行为方式。这是我的发现。

  • 生成的 ID 将从 1 开始,每次调用时都会递增 (1, 2 , 3...)
  • 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);
        }
    }
}
于 2017-02-25T14:03:27.587 回答