LayoutInflater 날치기, 사용자 정의 속성 교묘 한 해석
8155 단어 안 드 로 이 드 개발android
이 수 요 는 제한 되 어 있 습 니 다. 1. 일반적인 구조 이 기 를 원 하기 때문에 ImageView, 각종 Layout, 사용자 정의 View 등 다양한 View 를 사용 할 수 있 습 니 다. 따라서 하나의 단독 View 를 계승 할 수 없습니다. 2. 기 존 코드 를 최대한 수정 하지 않 고 사용자 에 게 투명 합 니 다.
문제 의 가장 어 려 운 점 은 적절 한 착안점 이 없어 서 속성 을 읽 고 응용 하 는 것 입 니 다. 나중에 비교적 tricky 방식 으로 이 문 제 를 해결 하 였 습 니 다.
1. Layout Inflater 에 onCreateView 방법 이 있 음 을 알 고 있 습 니 다. 이 방법 은 Public 에서 복사 할 수 있 고 xml 를 읽 고 얻 은 여러 속성 값 을 얻 을 수 있 습 니 다. 따라서 이상 적 인 접근 점 입 니 다.
한 마디 로 Layout Inflater 는
setFactory
와 같은 방식 으로 View 의 생산 을 맞 출 수 있 지만 여기 서 는 적합 하지 않다. 왜냐하면 우 리 는 View 가 어떻게 구축 되 었 는 지 주목 하고 싶 지 않 고 View 가 구 축 된 후에 추가 작업 을 하고 싶 을 뿐이다.따라서 시스템 의 Layout Infalter 를 교체 할 수 있 기 를 바 랍 니 다.
2. Layout Inflater 의 일상 사용 방식 은 주로
LayoutInfater.from(context)
또는 Activit#getLayoutInflater
등 이 고 마지막 호출 까지 context.getSystemService(LAYOUT_INFLATER)
올 라 옵 니 다.// LayoutInflater.java
public static LayoutInflater from(Context context) {
LayoutInflater LayoutInflater =
(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (LayoutInflater == null) {
throw new AssertionError("LayoutInflater not found.");
}
return LayoutInflater;
}
시스템 의 '정품' Layout Inflate 는 Phone Layout Inflater 를 사용 합 니 다.
//ContextImpl.java
@Override
public Object getSystemService(String name) {
return SystemServiceRegistry.getSystemService(this, name);
}
//SystemServiceRegistry
registerService(Context.LAYOUT_INFLATER_SERVICE, LayoutInflater.class,
new CachedServiceFetcher() {
@Override
public LayoutInflater createService(ContextImpl ctx) {
return new PhoneLayoutInflater(ctx.getOuterContext());
}});
저 희 는 Activity 에서 getSystemService 를 다시 쓰 면 Layout Inflater 로 바 꿀 수 있 습 니 다.
public class MainActivity extends Activity {
LayoutInflater layoutInflater;
@Override
public Object getSystemService(String name) {
if (name.equals(LAYOUT_INFLATER_SERVICE)) {
if (layoutInflater == null) {
LayoutInflater origin = (LayoutInflater) super.getSystemService(name);
// ni
layoutInflater = new PPLayoutInflater(origin, this);
}
return layoutInflater;
}
return super.getSystemService(name);
}
@Override
public LayoutInflater getLayoutInflater() {
return layoutInflater;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
@Override protected View onCreateView(String name, AttributeSet attrs) throws ClassNotFoundException {
Log.e("shitshit", "【" + this.getClass().getSimpleName() + "】 onCreateView() called with: " + "name = [" + name + "], attrs = [" + attrs + "]");
for (String prefix : sClassPrefixList) {
try {
//
View view = createView(name, prefix, attrs);
if (view != null) {
//do custom here... ImageView
if(view instanceof ImageView) {
if (attrs != null) {
for (int i = 0; i < attrs.getAttributeCount(); i++) {
String attributeName = attrs.getAttributeName(i);
String attributeValue = attrs.getAttributeValue(i);
// View xml
processAttrs(attributeName, attributeValue, view);
}
}
}
return view;
}
} catch (ClassNotFoundException e) {
// In this case we want to let the base class take a crack
// at it.
}
}
return super.onCreateView(name, attrs);
}
간단 한 processAtts 의 밤:
public void processAttrs(String attrName, String attrValue, View view){
if(attrName.equals("tag")){
view.setBackgroundColor(Color.parseColor(attrValue));
}
}
본문 전체 코드 가 git 에 업로드 되 었 습 니 다.https://github.com/BFridge/CustomLayoutInflater
사실 SystemService 를 교체 하 는 유사 한 작은 tricky 에 대해 서도 높 은 사람들 이 전문 적 으로 연구 한 적 이 있다.https://github.com/square/mortar
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Android 개발 에 사용 되 는 MT 난수 생 성기이전의 AS3 이식 판 을 약간 고 쳐 서 현재 jkanji 에 사용 하고 있 습 니 다.테스트 를 좀 해 봤 는데 버그 가 별로 없 는 것 같 아 요.가장 간단 한 동전 테스트 를 해 봤 는데 같은 씨앗 의 경우 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.