Android - UI personalizada com atributos personalizados

113

Eu sei que é possível criar um elemento de interface do usuário personalizado (por meio de modo de exibição ou extensão de elemento de interface de usuário específico). Mas é possível definir novas propriedades ou atributos para elementos de interface do usuário recém-criados (quero dizer, não herdados, mas totalmente novos para definir algum comportamento específico que não sou capaz de lidar com propriedades ou atributos padrão)

por exemplo, elemento meu elemento personalizado:

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

Então, é possível definir MyCustomValue ?

THX

Parada
fonte
Olá, aqui você tem um bom artigo sobre os atributos personalizados no android - amcmobileware.org/android/blog/2016/09/11/custom-attributes
Arkadiusz Cieśliński
Dê uma olhada na minha resposta a esta questão relacionada.
Helios de

Respostas:

258

Sim. Guia resumido:

1. Crie um atributo XML

Crie um novo arquivo XML dentro /res/values/attrs.xml, com o atributo e seu tipo

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

Basicamente, você deve configurar um <declare-styleable />para sua visualização que contenha todos os seus atributos personalizados (aqui apenas um). Nunca encontrei uma lista completa dos tipos possíveis, então você precisa procurar na fonte, eu acho. Tipos que eu conheço são referência (para outro recurso), cor, booleano, dimensão, flutuante, inteiro e string . Eles são bastante autoexplicativos

2. Use os atributos em seu layout

Isso funciona da mesma maneira que você fez acima, com uma exceção. Seu atributo personalizado precisa de seu próprio namespace 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"
   />

Bem direto.

3. Faça uso dos valores que você passar

Modifique o construtor de sua visualização personalizada para analisar os valores.

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();
    }
    // ...
}

distanceExampleé uma variável de membro privado neste exemplo. TypedArraytem muitas outras coisas para analisar outros tipos de valores.

E é isso. Use o valor analisado em seu Viewpara modificá-lo, por exemplo, use-o em onDraw()para alterar a aparência de acordo.

uthark
fonte
7
Apenas observe sobre TypedArray. Certifique-se de chamar recycle () quando terminar de usá-los.
zskalnik
Aqui você pode encontrar uma boa lista github.com/android/platform_frameworks_base/blob/master/core/…
yahya
O IDE (eclipse, por exemplo) preenche automaticamente as chaves / valores de atributos personalizados?
AlikElzin-kilaka de
23
para compilações do Gradle, você deve usar http://schemas.android.com/apk/res-autoao declarar o namespace personalizado
Dori
2
Na etapa 3, você pode simplesmente usar String initialText = attrs.getAttributeValue("http://schemas.android.com/apk/res-auto", "initialText");onde attr é o AttributeSet que é passado no construtor e 'initialText' é o nome do seu atributo personalizado
kosiara - Bartosz Kosarzycki
21

Em sua pasta res / valores, crie attr.xml. Lá você pode definir seus atributos:

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

Quando você quiser usá-lo em seu arquivo de layout, você deve adicionar

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

e então você pode usar o valor com customname:myCustomValue=""

Maria Neumayer
fonte
esta não é a resposta, a questão é como mudar programaticamente de java
Fazal
-11

Sim, você pode <resource>. Basta usar a tag.
como isso:

<?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 do site oficial

Frank Cheng
fonte
Obrigado pela resposta. Mas no recurso, vejo o uso de valores padrão "android:". Meu ponto é, posso ter, por exemplo, android: phoneNameSelected = "true" como um parâmetro do meu elemento de IU personalizado?
Ponto de referência