Tworzenie zajęć w widoku danych

Wypróbuj metodę Compose
Jetpack Compose to zalecany zestaw narzędzi interfejsu na Androida. Dowiedz się, jak pracować z układami w Compose.

Dobrze zaprojektowany widok niestandardowy jest podobny do każdej innej dobrze zaprojektowanej klasy. Zawiera on określony zestaw funkcji z prostym interfejsem, wydajnie wykorzystuje procesor i pamięć itp. Oprócz tego, że klasa musi być dobrze zaprojektowana, widok niestandardowy musi spełniać te wymagania:

  • spełniać standardy Androida,
  • Udostępniaj niestandardowe atrybuty, które można dostosowywać i które działają z układami XML na Androidzie.
  • wysyłać zdarzenia ułatwień dostępu;
  • być zgodna z wieloma platformami Androida;

Platforma Androida udostępnia zestaw klas bazowych i tagów XML, które pomagają tworzyć widoki spełniające wszystkie te wymagania. Z tej lekcji dowiesz się, jak używać platformy Androida do tworzenia podstawowych funkcji klasy widoku.

Dodatkowe informacje znajdziesz w sekcji Komponenty widoku niestandardowego.

Tworzenie podklasy widoku

Wszystkie klasy widoków zdefiniowane w platformie Android rozszerzają klasę View. Widok niestandardowy może też bezpośrednio rozszerzać klasę View. Możesz też zaoszczędzić czas, rozszerzając jedną z istniejących podklas widoku, np. Button.

Aby umożliwić Android Studio interakcję z widokiem, musisz podać co najmniej konstruktor, który przyjmuje jako parametry obiekt Context i obiekt AttributeSet. Ten konstruktor umożliwia edytorowi układu tworzenie i edytowanie instancji widoku.

Kotlin

class PieChart(context: Context, attrs: AttributeSet) : View(context, attrs)

Java

class PieChart extends View {
    public PieChart(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
}

Definiowanie atrybutów niestandardowych

Aby dodać wbudowany element View do interfejsu, określ go w elemencie XML i kontroluj jego wygląd oraz działanie za pomocą atrybutów elementu. Możesz też dodawać i stylować widoki niestandardowe za pomocą XML. Aby włączyć to działanie w widoku niestandardowym, wykonaj te czynności:

  • Zdefiniuj atrybuty niestandardowe widoku w elemencie zasobu <declare-styleable> .
  • Określ wartości atrybutów w układzie XML.
  • Pobieranie wartości atrybutów w czasie działania.
  • Zastosuj pobrane wartości atrybutów do widoku.

W tej sekcji dowiesz się, jak zdefiniować atrybuty niestandardowe i określić ich wartości. W następnej sekcji znajdziesz informacje o pobieraniu i stosowaniu wartości w czasie działania.

Aby zdefiniować atrybuty niestandardowe, dodaj do projektu <declare-styleable>  zasobów. Zwykle umieszcza się je w pliku res/values/attrs.xml. Oto przykład pliku attrs.xml:

<resources>
   <declare-styleable name="PieChart">
       <attr name="showText" format="boolean" />
       <attr name="labelPosition" format="enum">
           <enum name="left" value="0"/>
           <enum name="right" value="1"/>
       </attr>
   </declare-styleable>
</resources>

Ten kod deklaruje 2 atrybuty niestandardowe, showTextlabelPosition, które należą do podlegającej stylowi encji o nazwie PieChart. Nazwa elementu, któremu można przypisać styl, jest zwykle taka sama jak nazwa klasy, która definiuje widok niestandardowy. Chociaż nie jest konieczne stosowanie tej konwencji, wiele popularnych edytorów kodu polega na niej w zakresie uzupełniania instrukcji.

Po zdefiniowaniu atrybutów niestandardowych możesz ich używać w plikach XML układu tak samo jak wbudowanych atrybutów. Jedyna różnica polega na tym, że atrybuty niestandardowe należą do innej przestrzeni nazw. Zamiast należeć do przestrzeni nazw http://schemas.android.com/apk/res/android, należą do http://schemas.android.com/apk/res/[your package name]. Oto przykład użycia atrybutów zdefiniowanych dla elementu PieChart:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:custom="http://schemas.android.com/apk/res-auto">
 <com.example.customviews.charting.PieChart
     custom:showText="true"
     custom:labelPosition="left" />
</LinearLayout>

Aby uniknąć powtarzania długiego identyfikatora URI przestrzeni nazw, w przykładzie użyto dyrektywy xmlns. Ta dyrektywa przypisuje alias custom do przestrzeni nazw http://schemas.android.com/apk/res/com.example.customviews. Możesz wybrać dowolny alias dla swojej przestrzeni nazw.

Zwróć uwagę na nazwę tagu XML, który dodaje widok niestandardowy do układu. Jest to pełna nazwa klasy widoku niestandardowego. Jeśli klasa widoku jest klasą wewnętrzną, dodatkowo określ ją za pomocą nazwy klasy zewnętrznej widoku. Na przykład klasa PieChart ma klasę wewnętrzną o nazwie PieView. Aby używać atrybutów niestandardowych z tej klasy, użyj tagu com.example.customviews.charting.PieChart$PieView.

Stosowanie atrybutów niestandardowych

Gdy widok jest tworzony na podstawie układu XML, wszystkie atrybuty w tagu XML są odczytywane z pakietu zasobów i przekazywane do konstruktora widoku jako AttributeSet. Chociaż można odczytywać wartości bezpośrednio z AttributeSet, ma to pewne wady:

  • Odwołania do zasobów w wartościach atrybutów nie są rozpoznawane.
  • Style nie są stosowane.

Zamiast tego przekaż AttributeSet do obtainStyledAttributes(). Ta metoda zwraca tablicę wartości, które zostały już wyłuskane i są ostylowane.TypedArray

Kompilator zasobów Androida wykonuje wiele czynności, aby ułatwić wywoływanie obtainStyledAttributes(). W przypadku każdego zasobu <declare-styleable> w katalogu res/ wygenerowany plik R.java definiuje zarówno tablicę identyfikatorów atrybutów, jak i zestaw stałych, które określają indeks każdego atrybutu w tablicy. Do odczytywania atrybutów z obiektu TypedArray używasz predefiniowanych stałych. Oto jak klasa PieChart odczytuje swoje atrybuty:

Kotlin

init {
    context.theme.obtainStyledAttributes(
            attrs,
            R.styleable.PieChart,
            0, 0).apply {

        try {
            mShowText = getBoolean(R.styleable.PieChart_showText, false)
            textPos = getInteger(R.styleable.PieChart_labelPosition, 0)
        } finally {
            recycle()
        }
    }
}

Java

public PieChart(Context context, AttributeSet attrs) {
   super(context, attrs);
   TypedArray a = context.getTheme().obtainStyledAttributes(
        attrs,
        R.styleable.PieChart,
        0, 0);

   try {
       mShowText = a.getBoolean(R.styleable.PieChart_showText, false);
       textPos = a.getInteger(R.styleable.PieChart_labelPosition, 0);
   } finally {
       a.recycle();
   }
}

Pamiętaj, że obiekty TypedArray są zasobem współdzielonym i po użyciu należy je poddać recyklingowi.

Dodawanie usług i wydarzeń

Atrybuty to skuteczny sposób kontrolowania zachowania i wyglądu widoków, ale można je odczytać tylko wtedy, gdy widok jest zainicjowany. Aby zapewnić dynamiczne działanie, udostępnij parę funkcji pobierającej i ustawiającej wartość właściwości dla każdego atrybutu niestandardowego. Poniższy fragment kodu pokazuje, jak PieChart udostępnia właściwość o nazwie showText:

Kotlin

fun isShowText(): Boolean {
    return mShowText
}

fun setShowText(showText: Boolean) {
    mShowText = showText
    invalidate()
    requestLayout()
}

Java

public boolean isShowText() {
   return mShowText;
}

public void setShowText(boolean showText) {
   mShowText = showText;
   invalidate();
   requestLayout();
}

Zwróć uwagę, że funkcja setShowText wywołuje funkcje invalidate()requestLayout(). Te wywołania są kluczowe, aby widok działał niezawodnie. Po każdej zmianie właściwości widoku, która może wpłynąć na jego wygląd, musisz unieważnić widok, aby system wiedział, że trzeba go ponownie narysować. Podobnie musisz poprosić o nowy układ, jeśli właściwość zmieni się w sposób, który może wpłynąć na rozmiar lub kształt widoku. Zapomnienie o wywołaniu tych metod może spowodować trudne do wykrycia błędy.

Widoki niestandardowe muszą też obsługiwać odbiorniki zdarzeń, aby przekazywać ważne zdarzenia. Na przykład PieChart udostępnia zdarzenie niestandardowe o nazwie OnCurrentItemChanged, aby powiadomić detektory, że użytkownik obrócił wykres kołowy, aby skupić się na nowym wycinku.

Łatwo zapomnieć o udostępnieniu właściwości i zdarzeń, zwłaszcza gdy jesteś jedynym użytkownikiem niestandardowego widoku. Dokładne zdefiniowanie interfejsu widoku zmniejsza przyszłe koszty konserwacji. Dobrze jest zawsze udostępniać każdą właściwość, która wpływa na widoczny wygląd lub zachowanie widoku niestandardowego.

Projektowanie z myślą o dostępności

Widok niestandardowy musi obsługiwać szerokie grono użytkowników. Dotyczy to użytkowników z niepełnosprawnościami, które uniemożliwiają im korzystanie z ekranu dotykowego. Aby pomóc użytkownikom z niepełnosprawnością, wykonaj te czynności:

  • Oznacz pola wejściowe za pomocą atrybutu android:contentDescription.
  • Wysyłaj zdarzenia ułatwień dostępu, wywołując w odpowiednich sytuacjach funkcję sendAccessibilityEvent().
  • obsługiwać alternatywne kontrolery, takie jak pad kierunkowy lub trackball;

Więcej informacji o tworzeniu widoków z ułatwieniami dostępu znajdziesz w artykule Zwiększanie dostępności aplikacji.