2016-05-24 11 views
0

Wie erstellt man eine sekundäre Zeile (Unterstrich) in TextView?textview unterstreichen (sekundärer Text)

Zum Beispiel

line1:

|word1  word2  word3 word4| //size17 

|  word2 description   | //size 6 

line2:

|word4 word5 word6  word7  | //size17 

|    word7 description | //size6 

EDIT 27.05:

Preview-Version. Irgendwelche Ideen, wie man sich verbessert?

public class DescriptionSpan extends ReplacementSpan { 


String description; 
Paint descriptionPaint; 

public DescriptionSpan(Paint paint, String description) { 
    descriptionPaint = paint; 
    this.description = description; 
} 


@Override 
public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) { 

    float delta = getShift(paint, text.subSequence(start, end).toString(), description); 

    if (delta >= 0) { 
     canvas.drawText(text, start, end, x, y, paint); 
     canvas.drawText(description, 0, description.length(), x + delta, y + descriptionPaint.getTextSize(), descriptionPaint); 
    } else { 
     canvas.drawText(text, start, end, x - delta, y, paint); 
     canvas.drawText(description, 0, description.length(), x, y + descriptionPaint.getTextSize(), descriptionPaint); 
    } 
} 

@Override 
public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) { 
    return (int) Math.max(paint.measureText(text, start, end), descriptionPaint.measureText(description)); 
} 


private float getShift(Paint paint, String text, String description) { 
    return (paint.measureText(text) - descriptionPaint.measureText(description))/2; 
} 

Es sieht aus wie Ihr Beitrag ist meist Code; Bitte fügen Sie weitere Details hinzu ....

+0

Ich denke, du meinst nicht, dass dies ein Raster von Texten ist, du meinst, dass dies Wörter innerhalb von Zeilen eines Absatzes sind, und an einem bestimmten Wort, willst du einen sekundären Text unter diesem Wort. Ist das genau? Vielleicht könntest du mehr darüber sagen, was du mit dieser Textanzeige machst. –

+0

ja. Grundsätzlich brauchen Beschreibung um (oben oder unten) Wort –

+1

Dies würde mindestens eine benutzerdefinierte Span-Unterklasse erfordern. Ich werde es mir ansehen. Wenn mir jemand das zum Codieren gab, würde ich überlegen, eine benutzerdefinierte Ansicht zu schreiben und alle Textmessungen/Berechnungen/Rendering direkt durchzuführen. –

Antwort

0

Sie können dafür einen SpannableStringBuilder verwenden. Etwas wie unten:

SpannableStringBuilder span = new SpannableStringBuilder(); 
    span.append("First Line"); 
    span.setSpan(new RelativeSizeSpan(.8f),0,firstLineLength); 
    span.append("Second Line"); 
    span.setSpan(new RelativeSizeSpan(1f),firstLineLength,firstLineLength+secondLineLength); 
textView.setText(span); 
+0

Zur Zeit erstellte Lösung Text wie cCcCcCc. Die Position für die Beschreibung wird berechnet, um nach mehrzeiligem Text zu suchen. –

1

Ich mag es nicht, Antworten ohne Code zu schreiben; Allerdings habe ich viel zu lange damit verbracht (ich kann der Herausforderung beim Codieren nicht widerstehen) und ich denke, ich habe genügend Informationen, um Sie ohne ein funktionierendes Codebeispiel in die richtige Richtung zu bringen.

So wie es ist angeblich ist zu arbeiten, dass in getSize() Sie würden die FontMetricsInt gesetzt, die in der richtigen Höhe für die Spanne übergeben werden, sowie Rückkehr der Spannweiten.

Aber hier ist das Ding: Die einzige konkrete Umsetzung von ReplacementSpanImageSpan die DynamicDrawableSpan erstreckt ist (das ist ein ReplacementSpan). Wenn Sie betrachten, werden der Abstieg und der Boden auf Null und der Aufstieg und der Anfang auf die Größe des Zeichens gesetzt. Mehr dazu in einer Sekunde.

Als ich Ihren Code nahm und versuchte, die Schriftart Metrik-Logik zu getSize() hinzuzufügen, stieß ich auf ein paar Probleme.

  1. Änderungen im Aufstieg/top sind geehrt, aber jede Änderung auf den Boden - die auf die eingestellte brauchen würde Raum für die Beschreibung zu ermöglichen - ist nicht geehrt. Es scheint, dass die Logik zugeschnitten ist, um ImageSpan/DynamicDrawableSpan aufzunehmen, und alles andere wird als ein ungetesteter Eckfall behandelt.

  2. ReplacementSpan scheint für einzeilige Texte ausgerichtet zu sein. Der Aufstieg & oben ist in der ersten Absatzzeile korrekt eingerichtet, aber nach dem Zeilenumbruch wird der normale Aufstieg/Top wiederhergestellt.

  3. Die Spanne wird im Allgemeinen als ein nicht brechendes Wort behandelt, aber ich stieß auf einen zeitweiligen Fehler, bei dem die Spanne selbst in eine zweite Zeile eingeschlossen wurde. Offensichtlich wäre dies ein Problem bei der Berechnung, wo alle Ihre Texte zu platzieren sind.

Also, wenn Sie wirklich diese mit Spannweiten tun wollte, ich glaube, was würden Sie tun müssen, ist eine andere benutzerdefinierte Absatz-Stil Spanne, die LineHeightSpan implementiert. Dazu würden Sie chooseHeight() implementieren.Wie das funktioniert ist, dass chooseHeight() für jede Zeile im Absatz aufgerufen werden soll. Ihre Implementierung würde in dieser Zeile nach einem DescriptionSpan suchen und die Schriftmetrik so einstellen, dass sie dem Beschreibungstext entspricht. So würden Sie jeden Absatz, der DescriptionSpan s hatte, mit diesem Absatzstil umspannen. Mit dieser Zeitspanne würde Ihre DescriptionSpan die Schriftmetrik in getSize() nicht ändern, und Sie würden nur annehmen, dass Sie Platz für den Beschreibungstext in draw() haben. (Ich hoffe, dass die Leinwand nicht an die Spannenbegrenzungen geklammert wird. Diese benutzerdefinierte Ansichtsidee sieht einfach immer besser aus.)

Ich würde gerne den Code arbeiten und posten, aber ich verbringe zu viel Zeit mit meinem Kopf auf ReplacementSpan Schriftmetrik.

+0

Ja, ich weiß. In der Freizeit werde ich versuchen, diese Lösung zu erweitern. Für die aktuelle Aufgabe ist es genug (Wort/Übersetzung braucht nicht viel Platz, zusätzlichen Platz durch lineSpacingMultiplier). Ich möchte nicht custome view verwenden. Ich denke, es wird genügen, etwas wie [numberLine = measure/lineLenght +1; FontMetricsInt.bottom * numberLine; foreach Zeichnungslinie] –