Frage

Ich habe eine benutzerdefinierte Ansicht, die ich erstelle, um die Schriftgröße des untergeordneten Elements zu skalieren TextViews um alle in eine festgelegte Breite zu passen, befindet sich jede auf einer eigenen Linie.Offensichtlich wird es die Breite brauchen, um das herauszufinden.

Ich hatte überschrieben onMeasure() wie so:

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  int widthSize = MeasureSpec.getSize(widthMeasureSpec);
  int lineWidth = widthSize - getPaddingLeft() - getPaddingRight();

  // Change the text size until the largest line of text fits.
  while (lineWidth < calculateTextWidth()) {
    for (TextView textView : this.childViews) {
      float newSize = textView.getTextSize() - 1;
      textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, newSize);
    }
  }

  super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

calculateTextWidth() berechnet die Breite der größten Textzeile und damit funktioniert alles.Dieser Code funktioniert gut für FILL_PARENT und WRAP_CONTENT breiten, aber vermasselt, wenn ich versuche, der Komponente ein Gewicht zu geben und sie ihr Gewicht automatisch so einstellen zu lassen.

MeasureSpec.getSize(widthMeasureSpec) zurückgeben 0, als getMinimumSuggestedWidth() tut es auch.Dies ergibt einen wunderbaren Aktivitätsfehler, der nicht reagiert, da die Linienbreite immer kleiner ist als calculateTextWidth() würde jemals wiederkommen, also die while schleife läuft für immer.Der XML-Code, den ich verwendet habe, war im Wesentlichen folgender:

<com.my.widgets.ScalingTextViewGroup
  android:layout_width="0dp"
  android:layout_height="wrap_content"
  android:layout_weight="1"
  android:orientation="vertical"
  android:gravity="center_horizontal"
  >
    <TextView
        android:id="@+id/text_1"
        android:text="Text 1"
        android:textSize="20sp" />
    <TextView
        android:id="@+id/text_2"
        android:text="Text 2"
        android:textSize="18sp" />
    <TextView
        android:id="@+id/text_3"
        android:text="Text 3"
        android:textSize="18sp" />
    <TextView
        android:id="@+id/text_4"
        android:text="Text 4"
        android:textSize="18sp" />
</com.my.widgets.ScalingTextViewGroup>

Ich verstehe, warum es 0 zurückgibt - offensichtlich wird es auf 0 gesetzt - aber wie bringe ich es dazu, das zu verwenden layout_weight?Ich habe das Gefühl, dass es etwas ist, das eine einfache Antwort haben sollte, aber ich weiß nicht, was es ist.

War es hilfreich?

Lösung

Am Ende habe ich es durch ein bedeutendes Googeln herausgefunden.Auf diese Seite Das habe ich herausgefunden onMeasure wird tatsächlich zweimal aufgerufen wenn android:layout_weight eingestellt ist.Ich habe später herausgefunden, dass es in erwähnt wird Wie Android Ansichten zeichnet dass measure() kann beliebig oft aufgerufen werden, es saß einfach nicht sofort in meinem Gehirn.Der erste Durchgang kann offensichtlich keinen Wert für die Größe jedes Kindes angeben, da er nicht weiß, wie hoch die Gewichte aller Geschwister der Ansicht sind.Es geht es einmal durch und gibt mit einer MeasureSpec eine Breite von 0 an.NICHT SPEZIFIZIERT, um zu sehen, ob das Kind bestimmte Einschränkungen hat, dann geht es durch wieder um die tatsächlichen Gewichte einer MeasureSpec zuzuordnen.GENAU.Meine Aktivität wurde beim ersten Durchgang durcheinander gebracht, so dass es nie zum Layoutschritt kam.Das Ändern von onMeasure () in den folgenden Code hat das Problem behoben.

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  int widthMode = MeasureSpec.getMode(widthMeasureSpec);
  if (widthMode != MeasureSpec.UNSPECIFIED) {
    int widthSize = MeasureSpec.getSize(widthMeasureSpec);
    int lineWidth = widthSize - getPaddingLeft() - getPaddingRight();

    // Change the text size until the largest line of text fits.
    while (lineWidth < calculateTextWidth()) {
      for (TextView textView : this.childViews) {
        float newSize = textView.getTextSize() - 1;
        textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, newSize);
      }
    }
  }

  super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top