View의 setTag () getTag () 메소드의 주요 목적은 무엇입니까?


421

같은 방법의 주요 목적은 무엇인가 setTag()getTag()View형 객체는?

여러 객체를 하나의 View와 연결할 수 있다고 생각하고 있습니까?

답변:


636

비슷한 뷰를 생성한다고 가정 해 보겠습니다. OnClickListener각보기마다 개별적으로를 설정할 수 있습니다.

button1.setOnClickListener(new OnClickListener ... );
button2.setOnClickListener(new OnClickListener ... );
 ...

그런 다음 onClick유사한보기를 수행하더라도 각보기에 대해 고유 한 방법 을 작성 해야합니다.

public void onClick(View v) {
    doAction(1); // 1 for button1, 2 for button2, etc.
}

이는 onClick매개 변수 a가 하나뿐 이기 때문에 View범위 변수의 인스턴스 변수 또는 최종 로컬 변수에서 다른 정보를 가져와야하기 때문입니다. 우리가 정말로 원하는 것은 뷰 자체에서 정보를 얻는 것 입니다.

getTag/ setTag: 입력

button1.setTag(1);
button2.setTag(2);

이제 모든 버튼에 동일한 OnClickListener를 사용할 수 있습니다.

listener = new OnClickListener() {
    @Override
    public void onClick(View v) {
        doAction(v.getTag());
    }
};

기본적으로 뷰가 추억 을 가질 수있는 방법입니다 .


8
@Matthew Willis 그러나 view.getId ()를 사용하여 그렇게 할 수 있습니다. 안 그래 ?
안드로이드 킬러

50
@AndroidKiller를 사용할 수 있지만 setTag ()를 사용하면 원하는 객체, 심지어 커스텀 클래스 등을 넣을 수 있습니다. 따라서 뷰가 표시하는 데이터에 대한 참조를 유지하는 데 사용할 수 있습니다.
Daniel

클릭 한 버튼의 배경색 만 변경하려면 어떻게해야합니까 ??? getTag ()에 의해 위치를 얻고 있습니다.
Sagar Devanga

2
@ Sagar : public void ui_click(View view){ if(20==((int)view.getTag())) view.setBackgroundColor(colorInt); }색상 부분에 대한 트릭을 수행해야합니다. 20은 뷰의 확인 위치를 나타내는 자리 표시 자입니다.
RiA

나는 이것이 오래된 방법이라고 생각합니다. 새로운 방법은 형식 안전성을 제공하는 일반 인수를 사용하는 것입니다. 그럼에도 불구하고 이것은 좋습니다.
M.kazem Akhgary

124

몇 마디 만 더하고 싶습니다.

get/setTag(Object)ViewHolder 패턴의 특정 경우에는 사용 이 매우 유용한 것처럼 보이지만 다른 경우에는 사용하기 전에 두 번 생각하는 것이 좋습니다. 더 나은 디자인을 가진 또 다른 솔루션이 거의 항상 있습니다.

주된 이유는 이와 같은 코드가 꽤 빨리 지원되지 않기 때문입니다.

  • 뷰에서 태그로 저장하도록 디자인 한 다른 개발자에게는 분명하지 않습니다. 방법 setTag/getTag은 전혀 설명하지 않습니다.

  • 단지 Object당신이 원할 때 캐스팅 해야하는을 저장합니다 getTag. 태그에 저장된 객체의 유형을 변경하기로 결정하면 나중에 예기치 않은 충돌이 발생할 수 있습니다.

  • 실제 사례는 다음과 같습니다. 우리는 많은 어댑터와 뷰가있는 비동기 작업 등을 포함하는 꽤 큰 프로젝트를 진행했습니다. 한 개발자는 set/getTag자신의 코드 부분을 결정 했지만 다른 개발자 는 이미 태그를이보기로 설정했습니다. 결국 누군가 자신의 태그를 찾지 못해 매우 혼란 스러웠습니다. 버그를 찾는 데 몇 시간이 걸렸습니다.

setTag(int key, Object tag)모든 리소스에 대해 고유 한 키를 생성 할 수 있지만 ( id resources 사용 ) Android <4.0에는 상당한 제한이 있습니다. 린트 문서에서 :

Android 4.0 이전에는 View.setTag (int, Object)를 구현하면 값이 강력하게 참조되는 정적 맵에 객체가 저장되었습니다. 즉, 객체에 컨텍스트를 가리키는 참조가 포함되어 있으면 컨텍스트 (기타 모든 것을 가리킴)가 누출됩니다. 뷰를 전달하면 뷰는 해당 뷰를 생성 한 컨텍스트에 대한 참조를 제공합니다. 마찬가지로 뷰 홀더에는 일반적으로 뷰가 포함되어 있으며 커서는 때때로 뷰와도 관련되어 있습니다.


2
고마워, 매우 도움이! ... 활동 레크레이션 사이에 태그에있는 내용이 복원되는지 알고 있습니까?
gunar

25

우리는 요구 사항에 따라 사용자 정의 객체를 사용 setTag()하고 getTag()설정할 수 있습니다 . setTag()방법은 유형의 인수를 사용 Object하고 getTag()을 반환합니다 Object.

예를 들어

Person p = new Person();
p.setName("Ramkailash");
p.setId(2000001);
button1.setTag(p);


14

이것은 사용자 정의 ArrayAdapter사용에 매우 유용합니다 . 일종의 최적화입니다. 거기에 setTag객체 참조로 사용되는 레이아웃의 일부에 대한 참조 (에 표시하는 ListView대신) findViewById.

static class ViewHolder {
    TextView tvPost;
    TextView tvDate;
    ImageView thumb;
}

public View getView(int position, View convertView, ViewGroup parent) {

    if (convertView == null) {
        LayoutInflater inflater = myContext.getLayoutInflater();
        convertView = inflater.inflate(R.layout.postitem, null);

        ViewHolder vh = new ViewHolder();
        vh.tvPost = (TextView)convertView.findViewById(R.id.postTitleLabel);
        vh.tvDate = (TextView)convertView.findViewById(R.id.postDateLabel);
        vh.thumb = (ImageView)convertView.findViewById(R.id.postThumb);
        convertView.setTag(vh);
    }
            ....................
}


11

TAG 설정은 ListView가 있고 뷰를 재활용 / 재사용하려는 경우에 매우 유용합니다. 이런 식으로 ListView는 최신 RecyclerView와 매우 유사 해집니다.

@Override
public View getView(int position, View convertView, ViewGroup parent)
  {
ViewHolder holder = null;

if ( convertView == null )
{
    /* There is no view at this position, we create a new one. 
       In this case by inflating an xml layout */
    convertView = mInflater.inflate(R.layout.listview_item, null);  
    holder = new ViewHolder();
    holder.toggleOk = (ToggleButton) convertView.findViewById( R.id.togOk );
    convertView.setTag (holder);
}
else
{
    /* We recycle a View that already exists */
    holder = (ViewHolder) convertView.getTag ();
}

// Once we have a reference to the View we are returning, we set its values.

// Here is where you should set the ToggleButton value for this item!!!

holder.toggleOk.setChecked( mToggles.get( position ) );

return convertView;
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.