Android - niestandardowy interfejs użytkownika z niestandardowymi atrybutami

113

Wiem, że można stworzyć niestandardowy element UI (za pomocą View lub określonego rozszerzenia elementu UI). Ale czy można zdefiniować nowe właściwości lub atrybuty dla nowo utworzonych elementów interfejsu użytkownika (mam na myśli nie dziedziczone, ale zupełnie nowe, aby zdefiniować określone zachowanie, którego nie jestem w stanie obsłużyć z domyślnymi właściwościami lub atrybutami)

np. element mój element niestandardowy:

<com.tryout.myCustomElement
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:text="Element..."
   android:myCustomValue=<someValue>
/>

Czy można więc zdefiniować MyCustomValue ?

Dzięki

Punkt orientacyjny
źródło
Hej, masz jakiś fajny artykuł o niestandardowych atrybutach w Androidzie
Arkadiusz Cieśliński
Spójrz na moją odpowiedź na to powiązane pytanie.
Helios

Odpowiedzi:

258

Tak. Krótki przewodnik:

1. Utwórz atrybut XML

Utwórz w środku nowy plik XML /res/values/attrs.xmlz atrybutem i jego typem

<?xml version="1.0" encoding="UTF-8"?>
<resources>
    <declare-styleable name="MyCustomElement">
        <attr name="distanceExample" format="dimension"/>
    </declare-styleable>
</resources>

Zasadniczo musisz skonfigurować jeden <declare-styleable />dla swojego widoku, który zawiera wszystkie atrybuty niestandardowe (tutaj tylko jeden). Nigdy nie znalazłem pełnej listy możliwych typów, więc myślę, że musisz poszukać źródła. Typy, które znam, to odwołania (do innego zasobu), kolor, wartość logiczna, wymiar, liczba zmiennoprzecinkowa, liczba całkowita i łańcuch . Są dość oczywiste

2. Użyj atrybutów w swoim układzie

Działa to tak samo, jak powyżej, z jednym wyjątkiem. Twój atrybut niestandardowy wymaga własnej przestrzeni nazw XML.

<com.example.yourpackage.MyCustomElement
   xmlns:customNS="http://schemas.android.com/apk/res/com.example.yourpackage"
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:text="Element..."
   customNS:distanceExample="12dp"
   />

Całkiem proste.

3. Skorzystaj z przekazanych wartości

Zmodyfikuj konstruktora widoku niestandardowego, aby przeanalizować wartości.

public MyCustomElement(Context context, AttributeSet attrs) {
    super(context, attrs);

    TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.MyCustomElement, 0, 0);
    try {
        distanceExample = ta.getDimension(R.styleable.MyCustomElement_distanceExample, 100.0f);
    } finally {
        ta.recycle();
    }
    // ...
}

distanceExamplew tym przykładzie jest prywatną zmienną składową. TypedArrayma wiele innych rzeczy do analizowania innych typów wartości.

I to wszystko. Użyj przeanalizowanej wartości w swoim, Viewaby ją zmodyfikować, np. Użyj jej, onDraw()aby odpowiednio zmienić wygląd.

uthark
źródło
7
Zwróć uwagę na TypedArray. Po zakończeniu należy wywołać funkcję recycle ().
zskalnik
Tutaj możesz znaleźć dobrą listę github.com/android/platform_frameworks_base/blob/master/core/…
yahya
Czy IDE (na przykład zaćmienie) automatycznie uzupełnia klucze / wartości atrybutów niestandardowych?
AlikElzin-kilaka,
23
w przypadku kompilacji gradle należy użyć http://schemas.android.com/apk/res-autopodczas deklarowania niestandardowej przestrzeni nazw
Dori
2
W kroku 3 możesz po prostu użyć, String initialText = attrs.getAttributeValue("http://schemas.android.com/apk/res-auto", "initialText");gdzie attr to zestaw atrybutów przekazywany w konstruktorze, a „initialText” to nazwa atrybutu niestandardowego
kosiara - Bartosz Kosarzycki
21

W folderze res / values ​​utwórz attr.xml. Tam możesz zdefiniować swoje atrybuty:

<declare-styleable name="">
    <attr name="myCustomValue" format="integer/boolean/whatever" />
</declare-styleable>

Jeśli chcesz użyć go w pliku układu, musisz dodać

xmlns:customname="http://schemas.android.com/apk/res/your.package.name"

a następnie możesz użyć wartości z customname:myCustomValue=""

Maria Neumayer
źródło
to nie jest odpowiedź, pytanie brzmi jak programowo zmienić z java
Fazal
-11

Tak, po prostu użyj <resource>tagu.
lubię to:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="CodeFont" parent="@android:style/TextAppearance.Medium">
        <item name="android:layout_width">fill_parent</item>
        <item name="android:layout_height">wrap_content</item>
        <item name="android:textColor">#00FF00</item>
        <item name="android:typeface">monospace</item>
    </style>
</resources>

link z oficjalnej strony internetowej

Frank Cheng
źródło
Dziękuję za odpowiedź. Ale w zasobach widzę użycie domyślnych wartości „android:”. Chodzi mi o to, czy mogę mieć np. Android: phoneNameSelected = "true" jako parametr mojego niestandardowego elementu UI?
Waypoint