Frage

Ich habe eine benutzerdefinierte Komponente mit zwei Textviews mit einer maßgeschneiderten Methode zur Größeneinstellung (die beiden Textansichten sind proportional um ein Verhältnis von 1: 2). Da dies eine Unterklasse von RelATivalout ist, gibt es kein Textzu -Attribut, aber ich frage mich, ob es möglich ist, das noch festzustellen android:textSize Attribut in der XML -Instanziierung für diese Komponente und greifen Sie dann die textSize Attribut aus dem Attributensatz, das mit meinem Brauch verwendet werden soll setSize() Methode im Konstruktor.

Ich habe die Technik gesehen, um dies mit benutzerdefinierten Attributen zu tun, aber was ist, wenn ich ein Attribut holen möchte, das bereits im Android -Lexikon liegt?

War es hilfreich?

Lösung

Ja, es ist möglich;

Nehmen wir an, Ihre RelATivalout -Deklaration (in XML) hat Texsize mit 14SP definiert:

android:textSize="14sp"

Im Konstruktor Ihrer benutzerdefinierten Ansicht (der in den Attributensatz) können Sie die Attribute aus Androids Namespace als solcher abrufen:

String xmlProvidedSize = attrs.getAttributeValue("http://schemas.android.com/apk/res/android", "textSize");

Der Wert des XMLProvidedSize ist so etwas wie dieser "14.0sp" und vielleicht können Sie mit wenig String -Bearbeitung die Zahlen extrahieren.


Eine weitere Option, Ihr eigenes Attributsatz zu deklarieren, wäre wenig lang, aber es ist auch möglich.

Sie haben also Ihre benutzerdefinierte Ansicht und Ihre Textviews haben so etwas richtig erklärt:

public class MyCustomView extends RelativeLayout{

    private TextView myTextView1;
    private TextView myTextView2;

// rest of your class here

Großartig...

Jetzt müssen Sie auch sicherstellen, dass Ihre benutzerdefinierte Ansicht den Konstruktor überschreibt, der den AttributeSet wie folgt aufnimmt:

public MyCustomView(Context context, AttributeSet attrs){   
    super(context, attrs);
    init(attrs, context);  //nice, clean method to instantiate your TextViews// 
}

OK, sehen wir uns jetzt diese init () -Methode an:

private void init(AttributeSet attrs, Context context){
    // do your other View related stuff here //


    TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.MyCustomView);
    int xmlProvidedText1Size = a.int(R.styleable.MyCustomView_text1Size);
    int xmlProvidedText2Size = a.int(R.styleable.MyCustomView_text2Size);

    myTextView1.setTextSize(xmlProvidedText1Size);
    myTextView2.setTextSize(xmlProvidedText2Size);

    // and other stuff here //
}

Sie fragen sich wahrscheinlich, wo r.Stylable.mycustomview, r.Stylable.MyCustomView_Text1size und R.Stylable.MyCustomView_Text2Size stammen; Erlauben Sie mir, diese zu näher eingehen.

Sie müssen die Attributnamen (n) in Ihrer Attr.xml -Datei (im Valuer -Verzeichnis) deklarieren, sodass Sie Ihre benutzerdefinierte Ansicht verwenden, die aus diesen Attributen gesammelten Werte in Ihrem Konstruktor übergeben werden.

Mal sehen, wie Sie diese benutzerdefinierten Attribute so deklarieren, wie Sie es gefragt haben: Hier sind meine ganzen Attr.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="MyCustomView">
        <attr name="text1Size" format="integer"/>
        <attr name="text2Size" format="integer"/>
    </declare-styleable>
</resources>

Jetzt können Sie die Größe Ihrer Textviews in Ihrem XML festlegen, ohne den Namespace in Ihrem Layout nicht zu erklären. Hier ist, wie:

<com.my.app.package.MyCustomView
    xmlns:josh="http://schemas.android.com/apk/res-auto"
    android:id="@+id/my_custom_view_id"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    josh:text1Size="15"
    josh:text2Size="30"     
    />

Bitte beachten Sie, wie ich den Namespace als "Josh" als erste Zeile im Attribut -Set Ihres CustomView deklariert habe.

Ich hoffe das hilft Josh,

Andere Tipps

Die akzeptierte Antwort ist etwas lang. Hier ist eine komprimierte Version, von der ich hoffe, dass sie leicht zu folgen ist. Um a hinzuzufügen textSize Attribut (oder irgendetwas, das verwendet dp/sp) Machen Sie die folgenden Schritte aus.

1. Erstellen Sie ein benutzerdefiniertes Attribut

Erstellen (oder fügen Sie den folgenden Abschnitt hinzu) zu attr.xml. Beachten Sie das dimension Format.

<resources>
    <declare-styleable name="CustomView">
        <attr name="textSize" format="dimension" />
    </declare-styleable>
</resources>

2. Stellen Sie das Attribut in Ihrem XML -Layout ein.

Beachten Sie den Brauch app Namespace.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:app="http://schemas.android.com/apk/res-auto"
                android:layout_width="match_parent"
                android:layout_height="match_parent">

    <com.example.myproject.CustomView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:textSize="20sp" /> 

</RelativeLayout>

3. Holen Sie sich den Attributwert in Ihrer benutzerdefinierten Ansicht

Beachten Sie die Verwendung von getDimensionPixelSize. Arbeiten Sie in Ihrer benutzerdefinierten Ansicht einfach mit Pixel. Sehen Diese Antwort Wenn Sie in eine andere Dimension konvertieren müssen.

public class CustomView extends View {

    private float mTextSize; // pixels

    public CustomView(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray a = context.getTheme().obtainStyledAttributes(
                attrs, R.styleable.CustomView, 0, 0);
        try {
            mTextSize = a.getDimensionPixelSize(R.styleable.CustomView_textSize, 0);
        } finally {
            a.recycle();
        }
    }

    /**
     * @param size in SP units
     */
    public void setTextSize(int size) {
        mTextSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
                size, getResources().getDisplayMetrics());
        mTextPaint.setTextSize(mTextSize);
        invalidate();
        requestLayout();
    }

    // ...
}

Anmerkungen

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top