프로그래밍 방식으로 뷰에 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:id의 int값을 참조하십시오 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와 같은 LinearLayout과 android:id="@+id/placeholder".
  • 자리 표시 자 채우기 위해 코드를 사용하여 ViewGroup에 View들.
  • 필요하거나 원하는 경우 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.