Automatische Anpassung von TextView für Android

Hintergrund

Oft müssen wir die Schriftart der Textansicht automatisch an die ihm zugewiesenen Grenzen anpassen.

Das Problem

Leider, obwohl es viele Themen und Beiträge (und Lösungsvorschläge) gibt, die sich mit diesem Problem befassen (Beispiel)Hier, Hier undHier), keiner von ihnen funktioniert wirklich gut.

Aus diesem Grund habe ich mich entschlossen, jeden einzelnen zu testen, bis ich den richtigen Deal gefunden habe.

Ich denke, dass die Anforderungen von einer solchen Textansicht sein sollten:

Sollte die Verwendung von Schriftarten, Schriftarten, Stilen und Zeichensätzen erlauben.

Sollte sowohl mit der Breite als auch mit der Höhe umgehen

Keine Kürzung, es sei denn, der Text passt aufgrund der Einschränkung nicht (Beispiel: zu langer Text, zu kleine verfügbare Größe). Wir können jedoch für diese Fälle eine horizontale / vertikale Bildlaufleiste anfordern, wenn wir dies wünschen.

Sollte mehrzeilig oder einzeilig zulassen. Bei mehrzeiligen Verbindungen sind max. Und min. Zeilen zulässig.

Sollte nicht langsam in der Berechnung sein. Verwenden Sie eine Schleife, um die beste Größe zu finden? Optimieren Sie es zumindest und erhöhen Sie Ihre Abtastung nicht jedes Mal um 1.

Bei mehrzeiligen Zeilen sollte es möglich sein, die Größe zu ändern oder mehr Zeilen zu verwenden, und / oder die Zeilen selbst mit dem Zeichen "\ n" auszuwählen.

Was ich versucht habe

Ich habe so viele Beispiele ausprobiert (einschließlich derjenigen der Links, über die ich geschrieben habe), und ich habe auch versucht, sie zu modifizieren, um die Fälle zu behandeln, von denen ich gesprochen habe, aber keine funktioniert wirklich.

Ich habe ein Beispielprojekt erstellt, mit dem ich visuell feststellen kann, ob TextView automatisch richtig passt.

Derzeit werden in meinem Beispielprojekt nur der Text (das englische Alphabet plus Ziffern) und die Größe der Textansicht zufällig ausgewählt und es bleibt in einer einzelnen Zeile, aber auch dies funktioniert in keinem der von mir getesteten Beispiele.

Hier ist der Code (auch verfügbarHier):

Dateires/layout/activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
  android:layout_height="match_parent" tools:context=".MainActivity">
  <Button android:id="@+id/button1" android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_centerHorizontal="true" android:text="Button" />
  <FrameLayout android:layout_width="match_parent"
    android:layout_height="wrap_content" android:layout_above="@+id/button1"
    android:layout_alignParentLeft="true" android:background="#ffff0000"
    android:layout_alignParentRight="true" android:id="@+id/container"
    android:layout_alignParentTop="true" />

</RelativeLayout>
Dateisrc/.../MainActivity.java
public class MainActivity extends Activity
  {
  private final Random        _random            =new Random();
  private static final String ALLOWED_CHARACTERS ="qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890";

  @Override
  protected void onCreate(final Bundle savedInstanceState)
    {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    final ViewGroup container=(ViewGroup)findViewById(R.id.container);
    findViewById(R.id.button1).setOnClickListener(new OnClickListener()
      {
        @Override
        public void onClick(final View v)
          {
          container.removeAllViews();
          final int maxWidth=container.getWidth();
          final int maxHeight=container.getHeight();
          final FontFitTextView fontFitTextView=new FontFitTextView(MainActivity.this);
          final int width=_random.nextInt(maxWidth)+1;
          final int height=_random.nextInt(maxHeight)+1;
          fontFitTextView.setLayoutParams(new LayoutParams(width,height));
          fontFitTextView.setSingleLine();
          fontFitTextView.setBackgroundColor(0xff00ff00);
          final String text=getRandomText();
          fontFitTextView.setText(text);
          container.addView(fontFitTextView);
          Log.d("DEBUG","width:"+width+" height:"+height+" text:"+text);
          }
      });
    }

  private String getRandomText()
    {
    final int textLength=_random.nextInt(20)+1;
    final StringBuilder builder=new StringBuilder();
    for(int i=0;i<textLength;++i)
      builder.append(ALLOWED_CHARACTERS.charAt(_random.nextInt(ALLOWED_CHARACTERS.length())));
    return builder.toString();
    }
  }
Die Frage

Kennt jemand eine Lösung für dieses häufige Problem, die tatsächlich funktioniert?

Sogar eine Lösung, die viel weniger Funktionen hat als das, worüber ich geschrieben habe, zum Beispiel eine, die nur eine konstante Anzahl von Textzeilen hat und ihre Schriftart an ihre Größe anpasst, aber niemals seltsame Pannen aufweist und den Text auch bekommt groß / klein im Vergleich zu seinem verfügbaren Platz.

GitHub-Projekt

Da dies ein so wichtiges TextView ist, habe ich beschlossen, eine Bibliothek zu veröffentlichen, damit jeder es leicht benutzen und dazu beitragen kann.Hier.

Antworten auf die Frage(15)

Ihre Antwort auf die Frage