엄선 된 API를 사용하는 맞춤 코드를 사용하면 Android에서 레이아웃 XML 파일을 확장하는 방식을 모방 할 수 있으며 Android에서 컴파일 된 XML 파일 및 사용자 정의 XML 파일 내의 임의 리소스에 대한 참조와 같은 XML 최적화 및 이점을 계속 활용할 수 있습니다. 해당 클래스는 View
을 팽창시킬 수 있기 때문에 기존 LayoutInflater
에 직접 연결할 수 없습니다. 아래 코드가 작동하려면 XML 파일을 응용 프로그램의 'res/xml'에 넣으십시오.
먼저 (컴파일 된) XML 파일을 구문 분석하고 Model
생성자를 호출하는 코드는 다음과 같습니다. 등록 메커니즘을 추가하여 모든 태그에 대해 클래스를 쉽게 등록하거나 ClassLoader.loadClass()
을 사용하여 클래스 이름을 기반으로 클래스를로드 할 수 있습니다. 이와
public class CustomInflator {
public static ArrayList<Model> inflate(Context context, int xmlFileResId) throws Exception {
ArrayList<Model> models = new ArrayList<Model>();
XmlResourceParser parser = context.getResources().getXml(R.xml.models);
Model currentModel = null;
int token;
while ((token = parser.next()) != XmlPullParser.END_DOCUMENT) {
if (token == XmlPullParser.START_TAG) {
if ("model".equals(parser.getName())) {
// You can retrieve the class in other ways if you wish
Class<?> clazz = Model.class;
Class<?>[] params = new Class[] { Context.class, AttributeSet.class };
Constructor<?> constructor = clazz.getConstructor(params);
currentModel = (Model)constructor.newInstance(context, parser);
models.add(currentModel);
}
} else if (token == XmlPullParser.TEXT) {
if (currentModel != null) {
currentModel.setText(parser.getText());
}
} else if (token == XmlPullParser.END_TAG) {
// FIXME: Handle when "model" is a child of "model"
if ("model".equals(parser.getName())) {
currentModel = null;
}
}
}
return models;
}
}
장소에, 당신은
View
그것을하지 많은처럼
Model
클래스 내부 속성의 "분석"넣을 수 있습니다 :
public class Model {
private String mName;
private String mType;
private int mStatAttack;
private String mText;
public Model(Context context, AttributeSet attrs) {
for (int i = 0; i < attrs.getAttributeCount(); i++) {
String attr = attrs.getAttributeName(i);
if ("name".equals(attr)) {
mName = attrs.getAttributeValue(i);
} else if ("type".equals(attr)) {
// This will load the value of the string resource you
// referenced in your XML
int stringResource = attrs.getAttributeResourceValue(i, 0);
mType = context.getString(stringResource);
} else if ("stat_attack".equals(attr)) {
mStatAttack = attrs.getAttributeIntValue(i, -1);
} else {
// TODO: Parse more attributes
}
}
}
public void setText(String text) {
mText = text;
}
@Override
public String toString() {
return "model name=" + mName + " type=" + mType + " stat_attack=" + mStatAttack + " text=" + mText;
}
}
을 내가 문자열 표현을 통해 특성을 참조한 위. 추가로 이동하려는 경우 응용 프로그램 특정 속성 자원을 정의하여 대신 사용할 수 있지만 그 작업은 상당히 복잡합니다 (Declaring a custom android UI element using XML 참조). 어쨌든, 모든 리소스 설정이의 더미 활동 :이 출력을 얻을 것이다
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
for (Model m : CustomInflator.inflate(this, R.xml.models)) {
Log.i("Example", "Parsed: " + m.toString());
}
} catch (Exception e) {
Log.e("Example", "Got " + e);
}
}
:
I/Example (1567): Parsed: model name=tall_model type=Example3 stat_attack=5 text=Tall Gunner
I/Example (1567): Parsed: model name=short_model type=Example3 stat_attack=3 text=Short Gunner
I/Example (1567): Parsed: model name=big_tank type=Example2 stat_attack=7 text=Big Tank
주 당신이 당신의 XML 파일에 @resource/scout
을 가질 수 없습니다 resource
이 아니므로 올바른 리소스 유형이지만 @string/foo
이 정상적으로 작동합니다. 예를 들어 @drawable/foo
을 사용하여 코드를 약간 수정하면됩니다.
매우 상세한 답변을 주셔서 감사합니다. 너는 나의 영웅이야. – AedonEtLIRA