Der herkömmliche Ansatz ist voll von unausgegorenem Code und ungeschicktem Umgang mit Ressourcen. Deshalb habe ich die Spyglass Rahmen . Zur Veranschaulichung der Funktionsweise finden Sie hier ein Beispiel für die Erstellung einer benutzerdefinierten Ansicht, die einen String-Titel anzeigt.
Schritt 1: Erstellen Sie eine benutzerdefinierte Ansichtsklasse.
public class CustomView extends FrameLayout {
private TextView titleView;
public CustomView(Context context) {
super(context);
init(null, 0, 0);
}
public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs, 0, 0);
}
public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(attrs, defStyleAttr, 0);
}
@RequiresApi(21)
public CustomView(
Context context,
AttributeSet attrs,
int defStyleAttr,
int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(attrs, defStyleAttr, defStyleRes);
}
public void setTitle(String title) {
titleView.setText(title);
}
private void init(AttributeSet attrs, int defStyleAttr, int defStyleRes) {
inflate(getContext(), R.layout.custom_view, this);
titleView = findViewById(R.id.title_view);
}
}
Schritt 2: Definieren Sie ein String-Attribut in der values/attrs.xml
Ressourcendatei:
<resources>
<declare-styleable name="CustomView">
<attr name="title" format="string"/>
</declare-styleable>
</resources>
Schritt 3: Wenden Sie die @StringHandler
Anmerkung zu der setTitle
Methode, um dem Spyglass-Framework mitzuteilen, dass der Attributwert an diese Methode weitergeleitet werden soll, wenn die Ansicht aufgeblasen wird.
@HandlesString(attributeId = R.styleable.CustomView_title)
public void setTitle(String title) {
titleView.setText(title);
}
Da Ihre Klasse nun eine Spyglass-Annotation hat, wird das Spyglass-Framework sie zur Kompilierzeit erkennen und automatisch die CustomView_SpyglassCompanion
Klasse.
Schritt 4: Verwenden Sie die generierte Klasse in der benutzerdefinierten Ansicht der init
Methode:
private void init(AttributeSet attrs, int defStyleAttr, int defStyleRes) {
inflate(getContext(), R.layout.custom_view, this);
titleView = findViewById(R.id.title_view);
CustomView_SpyglassCompanion
.builder()
.withTarget(this)
.withContext(getContext())
.withAttributeSet(attrs)
.withDefaultStyleAttribute(defStyleAttr)
.withDefaultStyleResource(defStyleRes)
.build()
.callTargetMethodsNow();
}
Das war's. Wenn Sie nun die Klasse aus XML instanziieren, interpretiert der Spyglass-Begleiter die Attribute und führt den erforderlichen Methodenaufruf durch. Wenn wir zum Beispiel das folgende Layout aufblasen, dann setTitle
wird aufgerufen mit "Hello, World!"
als Argument.
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:width="match_parent"
android:height="match_parent">
<com.example.CustomView
android:width="match_parent"
android:height="match_parent"
app:title="Hello, World!"/>
</FrameLayout>
Das Framework ist nicht auf String-Ressourcen beschränkt, sondern verfügt über viele verschiedene Annotationen für andere Ressourcentypen. Es hat auch Annotationen für die Definition von Standardwerten und für die Übergabe von Platzhalterwerten, wenn Ihre Methoden mehrere Parameter haben.
Weitere Informationen und Beispiele finden Sie im Github-Repositorium.