ViewStub 소스 코드 분석
ViewStub
소스 코드 를 한 번 보 았 습 니 다. 그 전에 대략적인 원 리 를 알 고 소스 코드 를 자세히 본 적 이 없습니다. 코드 는 조금 있 으 면 다 볼 수 있 고 300 줄 밖 에 없 었 습 니 다. 그리고 반 은 주석 이 었 습 니 다. 읽 고 얻 은 것 이 있 으 면 필 기 를 했 습 니 다.환경.
해석 하 다.
먼저
ViewStub
의 멤버 변 수 를 살 펴 보 자.private int mInflatedId; // xml inflatedId
private int mLayoutResource; // xml layout
private WeakReference mInflatedViewRef; // inflate View
private LayoutInflater mInflater; //
private OnInflateListener mInflateListener; // inflate
그 다음은 구조 법.
public ViewStub(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context);
final TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.ViewStub, defStyleAttr, defStyleRes);
// xml inflatedId , mInflatedId
mInflatedId = a.getResourceId(R.styleable.ViewStub_inflatedId, NO_ID);
// xml layout , layout
mLayoutResource = a.getResourceId(R.styleable.ViewStub_layout, 0);
// xml id
mID = a.getResourceId(R.styleable.ViewStub_id, NO_ID);
a.recycle();
//
setVisibility(GONE);
// ,
setWillNotDraw(true);
}
이 안 에는 세 가지 설명 할 곳 이 있다.
mID
은 ViewStub
에서 정의 되 지 않 았 습 니 다. mID
은 View
에서 정의 되 었 고 mID
방문 장식 부 는 default
입 니 다. 즉, 같은 가방 에서 방문 할 수 있 습 니 다. 이 mID
은 바로 우리 가 자주 사용 하 는 View
의 id
입 니 다. 보통 xml 에서 지정 합 니 다.View
의 setId
과 getId
을 통 해서 도 조작 할 수 있다.그러나 ViewStub
은 setId
방법 으로 설정 하지 않 고 mID
에 게 직접 할당 하 는 것 이 시 끄 러 웠 다. 이것 은 ViewStub
과 View
이 같은 가방 에 있 기 때문에 우리 가 직접 사용자 정의 View
을 쓰 면 이 일 을 할 수 없 기 때문에 당연히 반 사 를 통 해 할 수 있다.setVisibility()
방법 은 ViewStub
에서 재 작성 되 었 는데 이 방법 은 비교적 관건 적 이 고 뒤에 말한다.setWillNotDraw()
이 방법 은 View
에서 기본 값 은 false
이 고 ViewGroup
에서 기본 값 은 true
이 며 true
이 라면 View
의 onDraw()
은 호출 되 지 않 아 성능 을 향상 시 킬 수 있다.ViewStub
을 다시 써 서 View
을 그 리 는 방법 을 보 겠 습 니 다.@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// xml , 0
setMeasuredDimension(0, 0);
}
@Override
public void draw(Canvas canvas) {
}
@Override
protected void dispatchDraw(Canvas canvas) {
}
우 리 는
onMeasure
에서 너비 와 높이 를 모두 0 으로 설정 하 는 것 을 보 았 고 draw
관련 방법 은 모두 공 으로 이 루어 진 것 을 보 았 다. 이것 은 ViewStub
의 성능 이 좋 은 원인 으로 그 자신 이 존재 하지 않 는 것 과 같다 는 것 을 설명 했다.OK,
ViewStub
의 진실 한 View
을 보 여 주 려 면 두 가지 방법 이 있다 는 것 을 알 고 있 습 니 다.setVisibility()
을 VISIBLE
또는 INVISIBLE
inflate()
방법 @Override
public void setVisibility(int visibility) {
if (mInflatedViewRef != null) {
// inflate , mInflatedViewRef null
View view = mInflatedViewRef.get();
if (view != null) {
view.setVisibility(visibility);
} else {
// View , View
throw new IllegalStateException("setVisibility called on un-referenced view");
}
} else {
super.setVisibility(visibility);
if (visibility == VISIBLE || visibility == INVISIBLE) {
// inflate , , inflate()
inflate();
}
}
}
우 리 는
setVisibility()
도 최종 적 으로 inflate()
방법 을 사용 한 것 을 발견 했다. 첫 번 째 mInflatedViewRef
이 null
이 라 고 생각 했다. 그러면 inflate()
방법의 현실 을 계속 보 자.public View inflate() {
// ViewStub parent,ViewStub , inflate View parent
final ViewParent viewParent = getParent();
if (viewParent != null && viewParent instanceof ViewGroup) {
// mLayoutResource xml layout
if (mLayoutResource != 0) {
final ViewGroup parent = (ViewGroup) viewParent;
final LayoutInflater factory;
if (mInflater != null) {
factory = mInflater;
} else {
factory = LayoutInflater.from(mContext);
}
// LayoutInflater xml layout
final View view = factory.inflate(mLayoutResource, parent,
false);
if (mInflatedId != NO_ID) {
// View id, xml inflatedId
view.setId(mInflatedId);
}
// ViewStub parent
final int index = parent.indexOfChild(this);
// ViewStub parent ,ViewStub
parent.removeViewInLayout(this);
final ViewGroup.LayoutParams layoutParams = getLayoutParams();
// View parent
if (layoutParams != null) {
// ViewStub layout View
parent.addView(view, index, layoutParams);
} else {
parent.addView(view, index);
}
// View
mInflatedViewRef = new WeakReference(view);
// infalte ,listener set
if (mInflateListener != null) {
mInflateListener.onInflate(this, view);
}
// View
return view;
} else {
throw new IllegalArgumentException("ViewStub must have a valid layoutResource");
}
} else {
throw new IllegalStateException("ViewStub must have a non-null ViewGroup viewParent");
}
}
코드 논 리 는 비교적 간단 하 다. 여기 서 우 리 는
ViewStub
이 제거 되 는 과정 을 주의해 보 자. parent.removeViewInLayout(View)
방법 을 호출 하 는데 우 리 는 평소에 removeView(View)
을 많이 사용 할 수 있다. 그러면 이 두 가지 방법 이 어떤 차이 가 있 는 지 직접 소스 코드 를 보면 알 수 있다.public void removeView(View view) {
if (removeViewInternal(view)) {
requestLayout();
invalidate(true);
}
}
public void removeViewInLayout(View view) {
removeViewInternal(view);
}
removeView(View)
은 layout
을 다시 시작 하 는 과정 을 일 으 킬 수 있 음 이 분명 하 다. 즉, View
이 화면 에 표시 되 어 있 으 면 우리 가 제거 하려 면 removeView(View)
을 호출 하여 페이지 를 새로 고침 하 는 것 이다. View
이 화면 에 표시 되 지 않 으 면 removeViewInLayout(View)
의 성능 을 호출 하여 불필요 한 재 그림 을 피 할 수 있다.ViewStub
은 좋 은 예 다.여기 서
ViewStub
의 소스 코드 를 분석 하 였 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.