안 드 로 이 드 - 소스 코드 - LayoutInflater (1)
먼저 Layout Inflater 의 설명 을 살 펴 보 겠 습 니 다.
/**
* LayoutInflater xml View
* , :
* Activity.getLayoutInflater / Context.getSystemService
* , LayoutInflater 。
*
* View Factory LayoutInflater,
* cloneInContext LayoutInflater, ,
* setFactory Factory LayoutInflater 。
*
* ,View xml ,
* LayoutInflater xml。
*/
클래스 설명 은 우리 에 게 세 가 지 를 명확 하 게 해 주 었 다.
이 종 류 를 직접 만 들 지 말고 Layout Inflater 대상 을 지정 한 방법 으로 가 져 와 야 합 니 다.
Factory 를 통 해 LayoutInflater 의 충전 과정 을 사용자 정의 할 수 있 습 니 다.LayoutInflater 를 복사 하고 Factory 를 다시 설정 할 수 있 습 니 다.
LayoutInflater 는 컴 파일 된 xml 레이아웃 파일 만 해석 할 수 있 습 니 다.
그 중에서 모든 지 정 된 방법 은 최종 적 으로 Context. getSystemService 를 통 해 이 루어 집 니 다.
/*
* :
* getWindow().getLayoutInflater()
* getWindow() Activity mWindow :
* mWindow = new PhoneWindow(this, window);
* PhoneWindow.getLayoutInflater(), :
* mLayoutInflater = LayoutInflater.from(context);
*/
Activity.getLayoutInflater();
/*
* :
* LayoutInflater factory = LayoutInflater.from(context);
* return factory.inflate(resource, root);
*/
View.inflate(Context context, @LayoutRes int resource, ViewGroup root);
/*
* :
* LayoutInflater LayoutInflater = (LayoutInflater) context
* .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
*/
LayoutInflater.from(context);
그리고 내부 의 몇 개의 인터페이스 와 대상 을 다시 봅 시다.
private boolean mFactorySet; // setFactory
private Factory mFactory; // Factory
private Factory2 mFactory2; // Factory2
private Factory2 mPrivateFactory; //
private Filter mFilter; //
/*
*
* View , InflateException
*/
public interface Filter {
boolean onLoadClass(Class clazz);
}
/*
* Factory
* 3 :
* name : Tag , View ;
* context :View ;
* attrs :View xml ,
* View , View null。
*/
public interface Factory {
public View onCreateView(String name, Context context, AttributeSet attrs);
}
/*
* Factory2
* onCreateView, ViewParent 。
*/
public interface Factory2 extends Factory {
public View onCreateView(View parent, String name,
Context context, AttributeSet attrs);
}
필터 필터: setFilter 방법 을 통 해 LayoutInflater 에 사용자 정의 필 터 를 설정 할 수 있 습 니 다.
/*
* LayoutInflater , View ,
* inflate InflateException,
* filter filter。
*/
public void setFilter(Filter filter) {
mFilter = filter;
if (filter != null)
mFilterMap = new HashMap();
}
Filter 를 새로 설정 하면 오래된 Filter 를 덮어 쓰 고 mFilterMap 을 다시 초기 화 합 니 다.mFilterMap 의 역할: Filter 가 서로 다른 View 에 대한 필터 결 과 를 기록 하고 View 가 필터 에 들 어 갈 때 mFilterMap 을 우선 찾 아 Filter 가 중복 사용 되 지 않도록 합 니 다.
Filter 의 호출 과정 은 뒤의 분석 과정 에서 분 석 될 것 입 니 다.
Factory: Factory 에 대해 서 는 채 워 야 할 View 를 사용자 정의 할 수 있 습 니 다.Factory 인터페이스 에서 방법 매개 변 수 는 name, context, attrs 가 있 고 Factory 2 는 parent 매개 변 수 를 추가 하 는 과부하 가 하나 더 있 습 니 다.관심 을 가 져 야 할 매개 변 수 는: name 과 attrs:
name: xml 의 태그 이름 에 대응 하 는 View 의 클래스 이름 을 채 워 야 합 니 다.예 를 들 어 TextView.이 클래스 이름 에 따라 사용자 정의 View 를 만 들 수 있 습 니 다. 해당 하 는 View 를 만 들 수도 있 고 다른 View 를 만 들 수도 있 습 니 다.예 를 들 어 AppCompatActivity 에서 TextView 를 처리 하면 TextView 가 아 닌 AppCompatTextView 로 돌아 갑 니 다.
attrs: View 속성 은 이 속성 을 수정 할 수 있 습 니 다. 예 를 들 어 새로운 속성 을 추가 하고 기 존 속성 을 수정 하 는 등 입 니 다.attrs 수정 을 통 해 쉽게 스킨 케 어 기능 을 만 들 수 있 습 니 다.
setFactory 방법 을 사용 하여 LayoutInflater 에 사용자 정의 Factory 를 추가 합 니 다.
/*
* LayoutInflater Factory View ,
* Factory null, , ,
* xml , View ,Factory ,
* Factory View, View ,
* , onCreateView View。
*/
public void setFactory(Factory factory) {
// ,
if (mFactorySet)
throw new IllegalStateException("A factory has already "
+ "been set on this LayoutInflater");
if (factory == null)
throw new NullPointerException("Given factory can not be null");
// mFactorySet false, mFactorySet true
// setFactory
mFactorySet = true;
// LayoutInflater mFactory
// mFactory,
if (mFactory == null)
mFactory = factory;
else
mFactory = new FactoryMerger(factory, null, mFactory, mFactory2);
}
setFactory 2 를 사용 하여 Factory 2 대상 을 설정 할 수도 있 습 니 다.setFactory 2 는 setFactory 방법 과 같 지만 Factory 2 를 mFactory 와 mFactory 2 로 설정 합 니 다.
public void setFactory2(Factory2 factory) {
...
if (mFactory == null) {
mFactory = mFactory2 = factory;
} else {
mFactory = mFactory2 = new FactoryMerger(factory, factory, mFactory, mFactory2);
}
}
위 에 Factory Merger 류 가 언급 되 어 있 습 니 다.
private static class FactoryMerger implements Factory2 {
private final Factory mF1, mF2;
private final Factory2 mF12, mF22;
FactoryMerger(Factory f1, Factory2 f12, Factory f2, Factory2 f22) {
mF1 = f1; mF2 = f2; mF12 = f12; mF22 = f22;
}
public View onCreateView(String name, Context context, AttributeSet attrs) {
View v = mF1.onCreateView(name, context, attrs);
if (v != null) return v;
return mF2.onCreateView(name, context, attrs);
}
public View onCreateView(View parent, String name,
Context context, AttributeSet attrs) {
View v = mF12 != null ?
mF12.onCreateView(parent, name, context, attrs) :
mF1.onCreateView(name, context, attrs);
if (v != null) return v;
return mF22 != null ?
mF22.onCreateView(parent, name, context, attrs) :
mF2.onCreateView(name, context, attrs);
}
}
이 종 류 는 Factory 2 인 터 페 이 스 를 실현 했다. 즉, Factory 의 실현 류 이다. 그 역할 은 사실은 이전 Factory 를 기본 View 로 만 드 는 방법 으로 유지 하 는 것 이다.예 를 들 어 현재 Layout Inflater 가 있 습 니 다.
LayoutInflater inflater;
inflater.setFactory((name, context, attrs) -> {
if(TextUtils.equals(name, TextView.class.getSimpleName()))
return new EditText(context,attrs);
return null;
})
이때 EditView 를 처리 하고 원래 Factory 행 위 를 유지 하 는 새로운 Layout Inflater 를 얻 고 싶 습 니 다.
// LayoutInflater
LayoutInflater newInflater = inflater.cloneInContext(context);
newInflater.setFactory((name, context, attrs) -> {
if(TextUtils.equals(name, EditText.class.getSimpleName()))
return new TextView(context,attrs);
return null;
})
new Inflater 에 Factory 가 존재 하기 때문에 setFactory 는 Factory Merger 대상 을 만 들 것 입 니 다.
public void setFactory(Factory factory) {
if (mFactory == null)
mFactory = factory;
else
mFactory = new FactoryMerger(factory, null, mFactory, mFactory2);
}
EditText 를 채 울 때 새 Factory 는 TextView 대상 을 되 돌려 줍 니 다.TextView 를 채 울 때 null 로 돌아 갑 니 다. 이 때 는 기 존의 Factory 를 호출 하여 해석 합 니 다. 즉, EditText 대상 을 되 돌려 줍 니 다.
나머지 분석 은 다음 절 에 놓 여 있다. 안 드 로 이 드 - 소스 코드 분석 - Layout Inflater (2)
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.