프로그래밍 방식으로 뷰에 ID를 할당하려면 어떻게해야합니까?


202

XML 파일에서 뷰에 ID를 할당 한 android:id="@+id/something"다음을 호출 findViewById()할 수 있지만 프로그래밍 방식으로 뷰를 생성 할 때 ID를 어떻게 할당합니까?

setId()기본 과제와 같지 않다고 생각 합니다. setId()여분입니다.

아무도 나를 고칠 수 있습니까?


답변:


521

안드로이드 id개요

Android id는 일반적으로 뷰를 식별하는 데 사용되는 정수입니다. 이것은 idXML (수) 및 코드를 통해 통해 할당 될 수있다 (프로그래밍). (가) idXML 정의 참조 얻기에 가장 유용 ViewS 의해 생성을 Inflater(예로서 사용하여 setContentView).

id통해 할당XML

  • 뷰 에 android:id="@+id/somename 속성을 추가하십시오 ".
  • 응용 프로그램이 빌드되면 코드에 사용할 android:id수 있도록 고유 하게 할당됩니다 int.
  • " somename"(실제로 상수)을 사용하여 코드에서 android:idint값을 참조하십시오 R.id..
  • 이것은 int빌드마다 변경 될 수 있으므로 package.name/ 에서 ID복사하지 마십시오 . " somename" 만 사용하십시오 .gen/R.javaR.id.
  • (또한 XML을 생성 할 때는 in XML에 id할당 된 Preference것이 사용되지 않습니다 .)PreferenceView

id프로그래밍 방식으로 코드를 통해 할당

  • int를 id사용하여 수동으로 설정someView.setId();
  • int양수 여야하지만, 그렇지 않으면 당신이 원하는 무엇이든 할 수있다 arbitrary- (이이 무서운 경우 계속 읽어.)
  • 예를 들어, 항목을 나타내는 여러보기를 작성하고 번호를 매기면 항목 번호를 사용할 수 있습니다.

고유성 id

  • XML-지정된 ids는 고유합니다.
  • 코드 할당 id들 할 수 없습니다 고유해야
  • 코드 할당 id과의 캔 (이론적으로) 충돌 XML-assigned id의.
  • 이러한 id쿼리는 올바르게 쿼리 된 경우 중요하지 않습니다 (계속 읽으십시오) .

언제 (그리고 왜) 충돌 id하는 것이 중요하지 않습니다

  • findViewById(int)지정한 View 의 뷰 계층 구조 통해 깊이 우선 재귀를 반복 View하고 일치하는 첫 번째를 반환합니다 id.
  • 계층 구조에서 idXML로 정의되기 전에 코드가 할당되지 않은 한 항상 XML 정의 뷰를 반환합니다 .idfindViewById(R.id.somename)id

동적 뷰 및 할당 만들기 ID

  • 레이아웃 XML에서로 빈 ViewGroup을 정의하십시오 id.
  • A와 같은 LinearLayoutandroid:id="@+id/placeholder".
  • 자리 표시 자 채우기 위해 코드를 사용하여 ViewGroupView들.
  • 필요하거나 원하는 경우 id각보기에 편리한을 지정하십시오 .
  • placeholder.findViewById (convenientInt);를 사용하여 이러한 자식 뷰를 쿼리하십시오.

  • View.generateViewId()고유 ID를 생성 할 수있는 API 17이 도입되었습니다 .

뷰에 대한 참조를 유지하기로 선택한 경우 뷰 를 인스턴스화하고 getApplicationContext()각 참조를 null로 설정해야합니다 onDestroy. 분명히 새는Activity(파손 된 후 그 위에 매달려있는 것)은 낭비입니다 .. :)

android:id코드에서 사용하기 위해 XML 예약

View.generateViewId() 고유 ID를 생성하는 API 17이 도입되었습니다 . (이 점을 지적한 변경 기회를 가져 주셔서 감사합니다.) *

ViewGroupXML을 통해 정의 할 수없는 경우 (또는 원하지 않는 경우) XML을 통해 ID를 예약하여 고유 한 상태로 유지할 수 있습니다.

여기에서 values ​​/ ids.xml 은 사용자 정의를 정의합니다 id.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <item name="reservedNamedId" type="id"/>
</resources>

그런 다음 ViewGroup 또는 View가 생성되면 맞춤 ID를 첨부 할 수 있습니다.

myViewGroup.setId(R.id.reservedNamedId);

충돌하는 id

모호한 예를 통해 명확성을 기하기 위해 id장면 뒤에서 충돌 이 발생했을 때 어떤 일이 발생하는지 살펴 보겠습니다 .

layout / mylayout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <LinearLayout
        android:id="@+id/placeholder"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >
</LinearLayout>

충돌을 시뮬레이션하기 위해 최신 빌드가 할당 말할 수 R.id.placeholder( @+id/placeholder)는 int값을 12 ..

다음으로 MyActivity.java 는 프로그래밍 방식으로 코드를 통해 뷰를 추가합니다.

int placeholderId = R.id.placeholder; // placeholderId==12
// returns *placeholder* which has id==12:
ViewGroup placeholder = (ViewGroup)this.findViewById(placeholderId);
for (int i=0; i<20; i++){
    TextView tv = new TextView(this.getApplicationContext());
    // One new TextView will also be assigned an id==12:
    tv.setId(i);
    placeholder.addView(tv);
}

그래서 placeholder우리의 새로운 하나 TextView의 둘 모두가 id12을! 그러나 자리 표시 자의 자식 뷰를 쿼리하는 경우 실제로 문제가되지 않습니다.

// Will return a generated TextView:
 placeholder.findViewById(12);

// Whereas this will return the ViewGroup *placeholder*;
// as long as its R.id remains 12: 
Activity.this.findViewById(12);

*나쁘지 않았어


9
이 외에도, 그것은 충돌하지 않는 ID에 대한 View.generateViewId () API에서> (17)을 알고 있어야 비슷한 솔루션을 코딩에 누군가를 위해 유용 할 수 있습니다
AllDayAmazing

참고 findViewById"로 긴 계층 구조의 XML 정의 ID 위의 할당 된 코드 할당 된 식별자가없는 한"그래서, 깊이 우선 탐색을 수행 기술적으로 정확하지 않습니다; "위"가 아니라 "이전"입니다.
Karu

최신 버전의 Android 개발자 도구에서 프로그래밍 방식으로 ID를 임의의 값으로 설정하면 컴파일러 오류로 표시됩니다. 값은 실제 자원 ID 일 것으로 예상됩니다.
ThomasW

나는 이것이 5 년 전에 대답했을 때조차도 그렇다고 믿습니다. 그러므로 맞춤 ID가에 정의되어 있어야합니다 ids.xml. 진정한 임의의 ID의 경우 View.generateViewId()(API 17)을 사용하십시오. (내가 요점을 놓쳤다면 당신의 요점을 명확히하십시오.)
CodeShane

> (또한 Preference가 뷰를 생성 할 때 XML의 Preference에 할당 된 ID는 사용되지 않습니다.) 매우 관심이 있습니다. 내 코드는 PreferenceDialogFragmentCompatid가 R.id뷰 계층과 일치하지 않는 것처럼 보입니다 . 이렇게하면 ID 로보기를 찾을 수 없습니다.
UrK

6

당신은 View.setId(integer)이것을 위해 사용할 수 있습니다 . XML에서는 문자열 ID를 설정하더라도 정수로 변환됩니다. 이로 인해 Views 프로그래밍 방식으로 추가 하는 모든 (정수) 정수를 사용할 수 있습니다 .

View설명서 에 따르면

이 뷰의 계층에서 식별자가 고유하지 않아도됩니다. 식별자는 양수 여야합니다.

따라서 원하는 양의 정수를 사용할 수 있지만이 경우 동등한 id를 가진 일부 뷰가있을 수 있습니다. 일부 주요 객체를 사용하여 setTag를 호출하는 계층 구조에서 일부보기를 검색하려면 편리 할 수 ​​있습니다.

이 답변에 대한 크레딧 .


5

예, setId(value)원하는 (양의) 정수 값을 사용하여 모든 뷰에서 호출 한 다음을 사용하여 상위 컨테이너에서 찾을 수 있습니다 findViewById(value). setId()다른 형제 뷰에 대해 동일한 값 으로 호출하는 것이 유효 하지만 findViewById()첫 번째 뷰만 반환합니다.


1
0보다 큰 정수를 사용해야합니다.
Peter Ajtai

하지만 findViewById를 (INT)이보기에서보기 계층 구조를 통해 재귀 적으로 반복됩니다 당신은 지정하고이 일치하는 ID로 찾은 첫 번째보기 반환 가장 정확한 1 대답에 지정합니다.
Aniket Thakur

예, findViewById알려진 조상에게 전화 하는 것은 성능상의 이유로 좋은 생각이지만 올바른 ID를 가진 아이가 있다면 바로 아이를 찾을 것이라고 보장하지는 않습니다.
Karu
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.