Ja, es gibt einen Weg:
Angenommen, Sie haben eine Deklaration von Attributen für Ihr Widget (in attrs.xml
):
<declare-styleable name="CustomImageButton">
<attr name="customAttr" format="string"/>
</declare-styleable>
Deklarieren Sie ein Attribut, das Sie für eine Stilreferenz verwenden (in attrs.xml
):
<declare-styleable name="CustomTheme">
<attr name="customImageButtonStyle" format="reference"/>
</declare-styleable>
Deklarieren Sie eine Reihe von Standardattributwerten für das Widget (in styles.xml
):
<style name="Widget.ImageButton.Custom" parent="android:style/Widget.ImageButton">
<item name="customAttr">some value</item>
</style>
Deklarieren Sie ein benutzerdefiniertes Thema (in themes.xml
):
<style name="Theme.Custom" parent="@android:style/Theme">
<item name="customImageButtonStyle">@style/Widget.ImageButton.Custom</item>
</style>
Verwenden Sie dieses Attribut als drittes Argument im Konstruktor Ihres Widgets (in CustomImageButton.java
):
public class CustomImageButton extends ImageButton {
private String customAttr;
public CustomImageButton( Context context ) {
this( context, null );
}
public CustomImageButton( Context context, AttributeSet attrs ) {
this( context, attrs, R.attr.customImageButtonStyle );
}
public CustomImageButton( Context context, AttributeSet attrs,
int defStyle ) {
super( context, attrs, defStyle );
final TypedArray array = context.obtainStyledAttributes( attrs,
R.styleable.CustomImageButton, defStyle,
R.style.Widget_ImageButton_Custom ); // see below
this.customAttr =
array.getString( R.styleable.CustomImageButton_customAttr, "" );
array.recycle();
}
}
Jetzt müssen Sie sich Theme.Custom
auf alle Aktivitäten anwenden , die CustomImageButton
(in AndroidManifest.xml) verwendet werden:
<activity android:name=".MyActivity" android:theme="@style/Theme.Custom"/>
Das ist alles. Jetzt CustomImageButton
versucht, Standardattributwerte aus zu laden customImageButtonStyle
Attribute des aktuellen Themas. Wenn im Thema kein solches Attribut gefunden wird oder der Wert des Attributs ist, wird @null
das letzte zu verwendende Argument obtainStyledAttributes
verwendet: Widget.ImageButton.Custom
in diesem Fall.
Sie können die Namen aller Instanzen und aller Dateien (außer AndroidManifest.xml
) ändern , es ist jedoch besser, die Android-Namenskonvention zu verwenden.
customImageButtonStyle
in dieser Antwort). So wird die Aktionsleiste auf Android angepasst. Und wenn Sie ein Thema zur Laufzeit ändern möchten, ist dies mit diesem Ansatz nicht möglich.name="CustomTheme"
derdeclare-styleable
Attribut-Wrapper einem Zweck? Ist das nur für die Organisation, weil ich sehe, dass es nirgendwo verwendet wird. Kann ich einfach alle meine Stilattribute für verschiedene Widgets in einem Wrapper zusammenfassen?Ein weiterer Aspekt neben Michaels hervorragender Antwort ist das Überschreiben von benutzerdefinierten Attributen in Themen. Angenommen, Sie haben eine Reihe von benutzerdefinierten Ansichten, die sich alle auf das benutzerdefinierte Attribut "custom_background" beziehen.
In einem Thema definieren Sie den Wert
oder
Sie können in einem Stil auf das Attribut verweisen
Beachten Sie das Fragezeichen, das auch als Referenz für das Android-Attribut verwendet wird, wie in
Wie die meisten von Ihnen bemerkt haben, können und sollten Sie @color-Referenzen anstelle von hartcodierten Farben verwenden.
Warum also nicht einfach tun?
Sie können die Definition von "my_background_color" zur Laufzeit nicht ändern, während Sie die Themen einfach wechseln können.
quelle