매직

2014-07-09 3 views
1

코드 :매직

public class CustomLayoutWithText extends LinearLayout { 

    private Context context; 
    private AttributeSet attrs; 

    public CustomLayoutWithText(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     this.context = context; 
     this.attrs = attrs; 
     fooAttrs(); 
    } 

    @Override 
    protected void onFinishInflate() { 
     super.onFinishInflate(); 
     fooAttrs(); 
    } 

    private void fooAttrs() { 
     int[] set = { 
      android.R.attr.text  // idx 0 
     }; 
     TypedArray a = context.obtainStyledAttributes(attrs, set); 
     Log.d(null, a.getString(0)); 
    } 
} 

와 XML :

기대하는 합리적인
<com.korovyansk.android.views.CustomLayoutWithText 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:text="Some text"/> 

가 출력 될 것입니다 :
일부 텍스트
일부 텍스트

그러나 그것 :
일부 텍스트
null

두 번째로 null로 표시되는 이유는 무엇입니까? 어떻게 피하는가?

+0

attrs를 덤프하여 변경되는지 확인 – pskink

+0

@pskink attrs는 거대한 개체이므로 hashCode는 같은 값을 반환하지만 무시되지 않을 수 있습니다. 덤프, toString 또는 다른 어떤 메소드에 사용할 메소드는 무엇입니까? – AlexKorovyansky

+0

getAttributeName/getAttributeValue를 사용 하시겠습니까? – pskink

답변

1

나는 attrs의 모든 데이터가 재활용된다고 생각합니다. 사실 모든 예제에서보기의 생성자에있는 AttributeSet에서 가져온 모든 유형화 된 배열을 명시 적으로 재활용하는 것이 좋습니다. 나는 당신도 최고의 연습을 따라야한다고 생각합니다.

TypedArray a = context.obtainStyledAttributes(attrs, set); 
    try { 
     // read attributes from a 
     // ... 
    } finally { 
     attributes.recycle(); 
    } 

내 생각 엔 onFinishInflate()가 호출 될 때, attrs 이미 비어 있거나 사용할 수없는 것입니다.

사실 LayoutInflater 코드에 따르면 레이아웃 인플레이션 중에 View 생성자에 전달되는 AttributeSet은 실제로 XmlPullParser을 기반으로합니다. onFinishInflate()은 모든 하위 항목을 부 풀린 다음 상위보기에서 호출됩니다.

'onFinishInflate()'의이 시점에서 attrs에서 속성 값을 가져올 수 없습니다. 특히 레이아웃 내에 아이들이있는 경우 attrs은 동일한 파서를 참조하지만 파서의 위치는 마지막으로 파싱 된 하위의 속성을 가리 킵니다.