Wie man Text so anordnet, dass er um ein Bild herum fließt
Lesezeit: 9 Minuten
Silberburg
Können Sie mir bitte sagen, ob es eine Möglichkeit gibt, Text um ein Bild herum anzuordnen? So was:
------ text text text
| | text text text
----- text text text
text text text text
text text text text
Ich habe eine Antwort von einem Android-Entwickler zu dieser Frage erhalten. Aber ich bin mir nicht sicher, was er damit meint, meine eigene Version von TextView zu machen? Danke für jeden Tipp.
Am Montag, 8. Februar 2010 um 23:05 Uhr schrieb Romain Guy:
Hallo,
Mit den mitgelieferten Widgets und Layouts ist dies nicht möglich. Sie könnten Ihre eigene Version von TextView schreiben, um dies zu tun, es sollte nicht schwer sein.
silverburgh: hast du dafür eine lösung gefunden, die du teilen könntest?
– znq
5. März 2010 um 11:05 Uhr
stackoverflow.com/questions/13526949/… ist wahrscheinlich die Lösung
– Viktor
28. November 2012 um 5:02 Uhr
Das geht ganz einfach im Web. Ich werde diese Funktion vorerst überspringen.
– danny117
29. September 2014 um 3:40 Uhr
Sie können verwenden ImageSpan. Schauen Sie sich diesen Link an
– Treffen Sie Vora
13. Dezember 2016 um 13:35 Uhr
Wirbelwolf
Jetzt ist es möglich, aber nur für Telefone mit Version höher oder gleich 2.2, indem Sie die verwenden android.text.style.LeadingMarginSpan.LeadingMarginSpan2 Schnittstelle, die in API 8 verfügbar ist.
Hier ist das Artikelallerdings nicht in Englisch, aber Sie können den Quellcode des Beispiels direkt von herunterladen Hier.
Wenn Sie Ihre Anwendung mit älteren Geräten kompatibel machen möchten, können Sie ein anderes Layout ohne Fließtext anzeigen. Hier ist ein Beispiel:
Layout (Standard für ältere Versionen, wird programmgesteuert für neuere Versionen geändert)
class FlowTextHelper {
private static boolean mNewClassAvailable;
static {
if (Integer.parseInt(Build.VERSION.SDK) >= 8) { // Froyo 2.2, API level 8
mNewClassAvailable = true;
}
}
public static void tryFlowText(String text, View thumbnailView, TextView messageView, Display display){
// There is nothing I can do for older versions, so just return
if(!mNewClassAvailable) return;
// Get height and width of the image and height of the text line
thumbnailView.measure(display.getWidth(), display.getHeight());
int height = thumbnailView.getMeasuredHeight();
int width = thumbnailView.getMeasuredWidth();
float textLineHeight = messageView.getPaint().getTextSize();
// Set the span according to the number of lines and width of the image
int lines = (int)FloatMath.ceil(height / textLineHeight);
//For an html text you can use this line: SpannableStringBuilder ss = (SpannableStringBuilder)Html.fromHtml(text);
SpannableString ss = new SpannableString(text);
ss.setSpan(new MyLeadingMarginSpan2(lines, width), 0, ss.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
messageView.setText(ss);
// Align the text with the image by removing the rule that the text is to the right of the image
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams)messageView.getLayoutParams();
int[]rules = params.getRules();
rules[RelativeLayout.RIGHT_OF] = 0;
}
}
Die MyLeadingMarginSpan2-Klasse (aktualisiert, um API 21 zu unterstützen)
public class MyLeadingMarginSpan2 implements LeadingMarginSpan2 {
private int margin;
private int lines;
private boolean wasDrawCalled = false;
private int drawLineCount = 0;
public MyLeadingMarginSpan2(int lines, int margin) {
this.margin = margin;
this.lines = lines;
}
@Override
public int getLeadingMargin(boolean first) {
boolean isFirstMargin = first;
// a different algorithm for api 21+
if (Build.VERSION.SDK_INT >= 21) {
this.drawLineCount = this.wasDrawCalled ? this.drawLineCount + 1 : 0;
this.wasDrawCalled = false;
isFirstMargin = this.drawLineCount <= this.lines;
}
return isFirstMargin ? this.margin : 0;
}
@Override
public void drawLeadingMargin(Canvas c, Paint p, int x, int dir, int top, int baseline, int bottom, CharSequence text, int start, int end, boolean first, Layout layout) {
this.wasDrawCalled = true;
}
@Override
public int getLeadingMarginLineCount() {
return this.lines;
}
}
So sieht die Anwendung auf dem Android 2.2-Gerät aus:
Und das ist für das Android 2.1-Gerät:
Anstelle des Class.forName-Tricks könnten Sie eine einfache Bedingung verwenden: if (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO) {...
– Wojciech Gorski
30. August 2012 um 15:29 Uhr
Ich verwende dies auch. Aber wenn Daten mit HTML-Tags nicht für Html.fromHtml (HTML-Inhalt) unterstützt werden, helfen Sie mir bitte, ich muss eine Liste mit WrapText-Adapter wie oben anzeigen
– Harscha
27. November 2014 um 11:13 Uhr
@Harsha Die Methode Html.fromHtml funktioniert nicht mit HTML, es unterstützt nur einfaches HTML mit wenigen Tags.
– Wirbelwolf
14. Dezember 2014 um 7:39 Uhr
Großartige Arbeit, ich habe fast meinen Tag verschwendet … Tausend Dank!!
– Palak Darji
12. März 2015 um 10:13 Uhr
Dies fügt jedoch auch einen rechten Rand für die Zeilen nach dem Bild hinzu (so dass der Text nie ganz quer verläuft). Irgendeine Idee, wie man diesen Fehler beheben kann?
Hier ist eine Verbesserung für den FlowTextHelper (aus der Antwort von vorrtex). Ich habe die Möglichkeit hinzugefügt, zusätzliche Auffüllung zwischen dem Text und dem Bild hinzuzufügen, und die Zeilenberechnung verbessert, um auch die Auffüllung zu berücksichtigen. Genießen!
public class FlowTextHelper {
private static boolean mNewClassAvailable;
/* class initialization fails when this throws an exception */
static {
try {
Class.forName("android.text.style.LeadingMarginSpan$LeadingMarginSpan2");
mNewClassAvailable = true;
} catch (Exception ex) {
mNewClassAvailable = false;
}
}
public static void tryFlowText(String text, View thumbnailView, TextView messageView, Display display, int addPadding){
// There is nothing I can do for older versions, so just return
if(!mNewClassAvailable) return;
// Get height and width of the image and height of the text line
thumbnailView.measure(display.getWidth(), display.getHeight());
int height = thumbnailView.getMeasuredHeight();
int width = thumbnailView.getMeasuredWidth() + addPadding;
messageView.measure(width, height); //to allow getTotalPaddingTop
int padding = messageView.getTotalPaddingTop();
float textLineHeight = messageView.getPaint().getTextSize();
// Set the span according to the number of lines and width of the image
int lines = (int)Math.round((height - padding) / textLineHeight);
SpannableString ss = new SpannableString(text);
//For an html text you can use this line: SpannableStringBuilder ss = (SpannableStringBuilder)Html.fromHtml(text);
ss.setSpan(new MyLeadingMarginSpan2(lines, width), 0, ss.length(), 0);
messageView.setText(ss);
// Align the text with the image by removing the rule that the text is to the right of the image
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams)messageView.getLayoutParams();
int[]rules = params.getRules();
rules[RelativeLayout.RIGHT_OF] = 0;
}
}
Hallo Ronen. Ich habe große Probleme, die ganze Idee des Problems “Textumbruch um Bild” zu verstehen. Können Sie mir bitte sagen, wo ich Informationen zum Schreiben eines solchen Codes erhalten kann? Ich würde gerne lernen, wie man den Code selbst schreibt, anstatt ihn nur zu kopieren.
Hallo, vielen Dank für Infos. Wissen Sie, wie Sie dies mit dem Bild auf der rechten Seite des Bildschirms erreichen können?
– Ramona
14. Oktober 2017 um 9:18 Uhr
@Ramona sieht aus, als suche ich auch nach der gleichen Lösung. In unserem Fall haben wir ein Bild auf der rechten Seite des Bildschirms. Sind Sie auf eine Lösung oder Hinweise gestoßen, die hilfreich sein könnten?
– Chethan Shetty
6. Oktober 2021 um 5:41 Uhr
Die Antworten von Vorrtex und Ronen funktionieren für mich bis auf ein Detail: Nachdem ich Text um das Bild gewickelt hatte, gab es einen seltsamen “negativen” Rand unter dem Bild und auf der gegenüberliegenden Seite. Ich habe herausgefunden, dass ich beim Festlegen der Spanne auf dem SpannableString geändert habe
Ich brauchte den globalen Layout-Listener, um die richtigen Werte für zu bekommen getWidth() und getHeight().
Hier ist das Ergebnis:
Peter vdl
“Aber ich bin mir nicht sicher, was er damit meint, meine eigene Version von TextView zu erstellen?”
Er meint, dass Sie die Klasse android.widget.TextView (oder Canvas oder eine andere darstellbare Oberfläche) erweitern und Ihre eigene überschreibende Version implementieren können, die eingebettete Bilder mit umfließendem Text zulässt.
Dies kann eine Menge Arbeit sein, je nachdem, wie allgemein Sie es machen.
10015600cookie-checkWie man Text so anordnet, dass er um ein Bild herum fließtyes
silverburgh: hast du dafür eine lösung gefunden, die du teilen könntest?
– znq
5. März 2010 um 11:05 Uhr
stackoverflow.com/questions/13526949/… ist wahrscheinlich die Lösung
– Viktor
28. November 2012 um 5:02 Uhr
Das geht ganz einfach im Web. Ich werde diese Funktion vorerst überspringen.
– danny117
29. September 2014 um 3:40 Uhr
Sie können verwenden ImageSpan. Schauen Sie sich diesen Link an
– Treffen Sie Vora
13. Dezember 2016 um 13:35 Uhr