Jak uzyskać TextView
uzasadnienie tekstu a (z wyrównaniem tekstu po lewej i prawej stronie)?
Znalazłem możliwe rozwiązanie tutaj , ale to nie działa (nawet jeśli zmienisz pionowe centrum do center_vertical, etc).
Jak uzyskać TextView
uzasadnienie tekstu a (z wyrównaniem tekstu po lewej i prawej stronie)?
Znalazłem możliwe rozwiązanie tutaj , ale to nie działa (nawet jeśli zmienisz pionowe centrum do center_vertical, etc).
Odpowiedzi:
Nie wierzę, że Android obsługuje pełne uzasadnienie.
AKTUALIZACJA 01.01.2018 : Android 8.0+ obsługuje tryby justowania zTextView
.
Odpowiedź @CommonsWare jest poprawna. Android 8.0+ obsługuje „pełne uzasadnienie” (lub po prostu „usprawiedliwienie”, jak to niekiedy określa się niejednoznacznie).
System Android obsługuje także „Wyrównanie tekstu do lewej / prawej strony”. Zobacz artykuł w Wikipedii na temat uzasadnienia tego rozróżnienia. Wiele osób uważa, że pojęcie „justowania” obejmuje pełne justowanie, a także wyrównanie tekstu do lewej / prawej strony, czego szukają, kiedy chcą wyrównać tekst do lewej / prawej strony. Ta odpowiedź wyjaśnia, jak osiągnąć wyrównanie tekstu do lewej / prawej.
Możliwe jest wyrównanie tekstu do lewej / prawej strony (w przeciwieństwie do pełnego justowania, o jakie pyta pytanie). Aby to zademonstrować, użyję podstawowego 2-kolumnowego formularza (etykiety w lewej kolumnie i pola tekstowe w prawej kolumnie) jako przykład. W tym przykładzie tekst na etykietach w lewej kolumnie zostanie wyrównany do prawej, dzięki czemu będą wyglądać na wyrównane z polami tekstowymi w prawej kolumnie.
W układzie XML można ustawić same elementy TextView (lewa kolumna), aby wyrównać do prawej, dodając następujący atrybut do wszystkich TextViews:
<TextView
...
android:layout_gravity="center_vertical|end">
...
</TextView>
Jeśli jednak tekst zostanie zawinięty w wiele wierszy, tekst nadal będzie wyrównany do lewej w wyrównaniu w TextView. Dodanie następującego atrybutu powoduje wyrównanie tekstu w prawo z wyrównaniem do prawej (nierówny do lewej) w TextView:
<TextView
...
android:gravity="end">
...
</TextView>
Zatem atrybut grawitacji określa sposób wyrównywania tekstu wewnątrz TextView układ_grawitacyjny określa sposób wyrównywania / układu samego elementu TextView .
android:layout_gravity="center_horizontal|center"
android:gravity="center"
.
justify
Aby uzasadnić tekst w Androidzie, użyłem WebView
setContentView(R.layout.main);
WebView view = new WebView(this);
view.setVerticalScrollBarEnabled(false);
((LinearLayout)findViewById(R.id.inset_web_view)).addView(view);
view.loadData(getString(R.string.hello), "text/html; charset=utf-8", "utf-8");
i HTML.
<string name="hello">
<![CDATA[
<html>
<head></head>
<body style="text-align:justify;color:gray;background-color:black;">
Lorem ipsum dolor sit amet, consectetur
adipiscing elit. Nunc pellentesque, urna
nec hendrerit pellentesque, risus massa
</body>
</html>
]]>
</string>
Nie mogę jeszcze przesłać zdjęć, aby to udowodnić, ale „to działa dla mnie”.
view.loadData()
z view.setBackgroundColor("#00000000")
.
view.loadUrl()
utworów, podczas view.loadData()
gdy nie. Nie mam pojęcia, dlaczego to drugie nie.
Stworzyliśmy do tego prostą klasę. Obecnie istnieją dwie metody osiągnięcia tego, czego szukasz. Oba nie wymagają WEBVIEW i WSPIERA SPANNABLES .
BIBLIOTEKA : https://github.com/bluejamesbond/TextJustify-Android
WSPIERA : Android 2.0 do 5.X
USTAWIAĆ
// Please visit Github for latest setup instructions.
ZRZUT EKRANU
TextView
w Android O
ofertach samo pełne uzasadnienie (nowe wyrównanie typograficzne).
Musisz tylko to zrobić:
Kotlin
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
textView.justificationMode = JUSTIFICATION_MODE_INTER_WORD
}
Jawa
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
textView.setJustificationMode(JUSTIFICATION_MODE_INTER_WORD);
}
domyślnie jest JUSTIFICATION_MODE_NONE
.
Możesz użyć projektu JustifiedTextView dla Androida w github. jest to widok niestandardowy, który symuluje dla Ciebie wyjustowany tekst. Obsługuje Android 2.0+ i języki od prawej do lewej.
Piszę widget na podstawie natywnego widoku tekstu, aby to zrobić.
Znalazłem sposób na rozwiązanie tego problemu, ale może to nie być bardzo łaska, ale efekt nie jest zły.
Jego zasadą jest zamiana spacji każdej linii na ImageSpan o stałej szerokości (kolor jest przezroczysty).
public static void justify(final TextView textView) {
final AtomicBoolean isJustify = new AtomicBoolean(false);
final String textString = textView.getText().toString();
final TextPaint textPaint = textView.getPaint();
final SpannableStringBuilder builder = new SpannableStringBuilder();
textView.post(new Runnable() {
@Override
public void run() {
if (!isJustify.get()) {
final int lineCount = textView.getLineCount();
final int textViewWidth = textView.getWidth();
for (int i = 0; i < lineCount; i++) {
int lineStart = textView.getLayout().getLineStart(i);
int lineEnd = textView.getLayout().getLineEnd(i);
String lineString = textString.substring(lineStart, lineEnd);
if (i == lineCount - 1) {
builder.append(new SpannableString(lineString));
break;
}
String trimSpaceText = lineString.trim();
String removeSpaceText = lineString.replaceAll(" ", "");
float removeSpaceWidth = textPaint.measureText(removeSpaceText);
float spaceCount = trimSpaceText.length() - removeSpaceText.length();
float eachSpaceWidth = (textViewWidth - removeSpaceWidth) / spaceCount;
SpannableString spannableString = new SpannableString(lineString);
for (int j = 0; j < trimSpaceText.length(); j++) {
char c = trimSpaceText.charAt(j);
if (c == ' ') {
Drawable drawable = new ColorDrawable(0x00ffffff);
drawable.setBounds(0, 0, (int) eachSpaceWidth, 0);
ImageSpan span = new ImageSpan(drawable);
spannableString.setSpan(span, j, j + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
builder.append(spannableString);
}
textView.setText(builder);
isJustify.set(true);
}
}
});
}
Umieszczam kod na GitHub: https://github.com/twiceyuan/TextJustification
Przegląd:
Układ XML: deklaruj WebView zamiast TextView
<WebView
android:id="@+id/textContent"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
Kod Java: ustaw dane tekstowe na WebView
WebView view = (WebView) findViewById(R.id.textContent);
String text;
text = "<html><body><p align=\"justify\">";
text+= "This is the text will be justified when displayed!!!";
text+= "</p></body></html>";
view.loadData(text, "text/html", "utf-8");
To może rozwiązać problem. W pełni działało dla mnie.
Oto jak to zrobiłem, myślę, że najbardziej elegancki sposób, w jaki mogłem. Dzięki temu rozwiązaniu jedyne rzeczy, które musisz zrobić w swoich układach to:
xmlns
deklaracjęTextView
źródłową przestrzeń nazw tekstu z Androida na nowąTextView
szx.y.z.JustifiedTextView
Oto kod. Działa idealnie na moich telefonach (Galaxy Nexus Android 4.0.2, Galaxy Teos Android 2.1). Oczywiście nie krępuj się i zastąp moją nazwę paczki nazwą swoją.
/assets/justified_textview.css :
body {
font-size: 1.0em;
color: rgb(180,180,180);
text-align: justify;
}
@media screen and (-webkit-device-pixel-ratio: 1.5) {
/* CSS for high-density screens */
body {
font-size: 1.05em;
}
}
@media screen and (-webkit-device-pixel-ratio: 2.0) {
/* CSS for extra high-density screens */
body {
font-size: 1.1em;
}
}
/res/values/attrs.xml :
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="JustifiedTextView">
<attr name="text" format="reference" />
</declare-styleable>
</resources>
/res/layout/test.xml :
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:myapp="http://schemas.android.com/apk/res/net.bicou.myapp"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<net.bicou.myapp.widget.JustifiedTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
myapp:text="@string/surv1_1" />
</LinearLayout>
</ScrollView>
/src/net/bicou/myapp/widget/JustifiedTextView.java :
package net.bicou.myapp.widget;
import net.bicou.myapp.R;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import android.webkit.WebView;
public class JustifiedTextView extends WebView {
public JustifiedTextView(final Context context) {
this(context, null, 0);
}
public JustifiedTextView(final Context context, final AttributeSet attrs) {
this(context, attrs, 0);
}
public JustifiedTextView(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
if (attrs != null) {
final TypedValue tv = new TypedValue();
final TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.JustifiedTextView, defStyle, 0);
if (ta != null) {
ta.getValue(R.styleable.JustifiedTextView_text, tv);
if (tv.resourceId > 0) {
final String text = context.getString(tv.resourceId).replace("\n", "<br />");
loadDataWithBaseURL("file:///android_asset/",
"<html><head>" +
"<link rel=\"stylesheet\" type=\"text/css\" href=\"justified_textview.css\" />" +
"</head><body>" + text + "</body></html>",
"text/html", "UTF8", null);
setTransparentBackground();
}
}
}
}
public void setTransparentBackground() {
try {
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
} catch (final NoSuchMethodError e) {
}
setBackgroundColor(Color.TRANSPARENT);
setBackgroundDrawable(null);
setBackgroundResource(0);
}
}
Musimy ustawić renderowanie na oprogramowanie, aby uzyskać przezroczyste tło na Androidzie 3+. Stąd try-catch dla starszych wersji Androida.
Mam nadzieję że to pomoże!
PS: nie należy dodawać tego do całej aktywności na Androidzie 3+, aby uzyskać oczekiwane zachowanie:
android:hardwareAccelerated="false"
Bardzo proste Możemy to zrobić w pliku xml
<TextView
android:justificationMode="inter_word"
/>
Mimo że nadal nie uzupełniasz wyjustowanego tekstu, możesz teraz wyrównywać długości linii, używając android:breakStrategy="balanced"
interfejsu API 23 lub nowszego
http://developer.android.com/reference/android/widget/TextView.html#attr_android:breakStrategy
Piszę własną klasę, aby rozwiązać ten problem. Tutaj wystarczy wywołać funkcję justowania statycznego, która przyjmuje dwa argumenty
//Główna aktywność
package com.fawad.textjustification;
import android.app.Activity;
import android.database.Cursor;
import android.graphics.Point;
import android.graphics.Typeface;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.Gravity;
import android.view.Menu;
import android.widget.TextView;
public class MainActivity extends Activity {
static Point size;
static float density;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Display display = getWindowManager().getDefaultDisplay();
size=new Point();
DisplayMetrics dm=new DisplayMetrics();
display.getMetrics(dm);
density=dm.density;
display.getSize(size);
TextView tv=(TextView)findViewById(R.id.textView1);
Typeface typeface=Typeface.createFromAsset(this.getAssets(), "Roboto-Medium.ttf");
tv.setTypeface(typeface);
tv.setLineSpacing(0f, 1.2f);
tv.setTextSize(10*MainActivity.density);
//some random long text
String myText=getResources().getString(R.string.my_text);
tv.setText(myText);
TextJustification.justify(tv,size.x);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
// TextJustificationClass
package com.fawad.textjustification;
import java.util.ArrayList;
import android.graphics.Paint;
import android.text.TextUtils;
import android.widget.TextView;
public class TextJustification {
public static void justify(TextView textView,float contentWidth) {
String text=textView.getText().toString();
Paint paint=textView.getPaint();
ArrayList<String> lineList=lineBreak(text,paint,contentWidth);
textView.setText(TextUtils.join(" ", lineList).replaceFirst("\\s", ""));
}
private static ArrayList<String> lineBreak(String text,Paint paint,float contentWidth){
String [] wordArray=text.split("\\s");
ArrayList<String> lineList = new ArrayList<String>();
String myText="";
for(String word:wordArray){
if(paint.measureText(myText+" "+word)<=contentWidth)
myText=myText+" "+word;
else{
int totalSpacesToInsert=(int)((contentWidth-paint.measureText(myText))/paint.measureText(" "));
lineList.add(justifyLine(myText,totalSpacesToInsert));
myText=word;
}
}
lineList.add(myText);
return lineList;
}
private static String justifyLine(String text,int totalSpacesToInsert){
String[] wordArray=text.split("\\s");
String toAppend=" ";
while((totalSpacesToInsert)>=(wordArray.length-1)){
toAppend=toAppend+" ";
totalSpacesToInsert=totalSpacesToInsert-(wordArray.length-1);
}
int i=0;
String justifiedText="";
for(String word:wordArray){
if(i<totalSpacesToInsert)
justifiedText=justifiedText+word+" "+toAppend;
else
justifiedText=justifiedText+word+toAppend;
i++;
}
return justifiedText;
}
}
// 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"
>
<ScrollView
android:id="@+id/scrollView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
</LinearLayout>
</ScrollView>
</RelativeLayout>
FILL_HORIZONTAL
jest równoważne z CENTER_HORIZONTAL
. Możesz zobaczyć ten fragment kodu w kodzie źródłowym textview:
case Gravity.CENTER_HORIZONTAL:
case Gravity.FILL_HORIZONTAL:
return (mLayout.getLineWidth(0) - ((mRight - mLeft) -
getCompoundPaddingLeft() - getCompoundPaddingRight())) /
getHorizontalFadingEdgeLength();
Dla tego problemu istnieje CustomView, ten niestandardowy widok tekstu obsługuje Widok uzasadnionego tekstu.
Łup na to: JustifiedTextView
import java.util.ArrayList;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.text.TextPaint;
import android.view.View;
public class JustifiedTextView extends View {
String text;
ArrayList<Line> linesCollection = new ArrayList<Line>();
TextPaint textPaint;
Typeface font;
int textColor;
float textSize = 42f, lineHeight = 57f, wordSpacing = 15f, lineSpacing = 15f;
float onBirim, w, h;
float leftPadding, rightPadding;
public JustifiedTextView(Context context, String text) {
super(context);
this.text = text;
init();
}
private void init() {
textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
textColor = Color.BLACK;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (font != null) {
font = Typeface.createFromAsset(getContext().getAssets(), "font/Trykker-Regular.ttf");
textPaint.setTypeface(font);
}
textPaint.setColor(textColor);
int minw = getPaddingLeft() + getPaddingRight() + getSuggestedMinimumWidth();
w = resolveSizeAndState(minw, widthMeasureSpec, 1);
h = MeasureSpec.getSize(widthMeasureSpec);
onBirim = 0.009259259f * w;
lineHeight = textSize + lineSpacing;
leftPadding = 3 * onBirim + getPaddingLeft();
rightPadding = 3 * onBirim + getPaddingRight();
textPaint.setTextSize(textSize);
wordSpacing = 15f;
Line lineBuffer = new Line();
this.linesCollection.clear();
String[] lines = text.split("\n");
for (String line : lines) {
String[] words = line.split(" ");
lineBuffer = new Line();
float lineWidth = leftPadding + rightPadding;
float totalWordWidth = 0;
for (String word : words) {
float ww = textPaint.measureText(word) + wordSpacing;
if (lineWidth + ww + (lineBuffer.getWords().size() * wordSpacing) > w) {// is
lineBuffer.addWord(word);
totalWordWidth += textPaint.measureText(word);
lineBuffer.setSpacing((w - totalWordWidth - leftPadding - rightPadding) / (lineBuffer.getWords().size() - 1));
this.linesCollection.add(lineBuffer);
lineBuffer = new Line();
totalWordWidth = 0;
lineWidth = leftPadding + rightPadding;
} else {
lineBuffer.setSpacing(wordSpacing);
lineBuffer.addWord(word);
totalWordWidth += textPaint.measureText(word);
lineWidth += ww;
}
}
this.linesCollection.add(lineBuffer);
}
setMeasuredDimension((int) w, (int) ((this.linesCollection.size() + 1) * lineHeight + (10 * onBirim)));
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawLine(0f, 10f, getMeasuredWidth(), 10f, textPaint);
float x, y = lineHeight + onBirim;
for (Line line : linesCollection) {
x = leftPadding;
for (String s : line.getWords()) {
canvas.drawText(s, x, y, textPaint);
x += textPaint.measureText(s) + line.spacing;
}
y += lineHeight;
}
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public Typeface getFont() {
return font;
}
public void setFont(Typeface font) {
this.font = font;
}
public float getLineHeight() {
return lineHeight;
}
public void setLineHeight(float lineHeight) {
this.lineHeight = lineHeight;
}
public float getLeftPadding() {
return leftPadding;
}
public void setLeftPadding(float leftPadding) {
this.leftPadding = leftPadding;
}
public float getRightPadding() {
return rightPadding;
}
public void setRightPadding(float rightPadding) {
this.rightPadding = rightPadding;
}
public void setWordSpacing(float wordSpacing) {
this.wordSpacing = wordSpacing;
}
public float getWordSpacing() {
return wordSpacing;
}
public float getLineSpacing() {
return lineSpacing;
}
public void setLineSpacing(float lineSpacing) {
this.lineSpacing = lineSpacing;
}
class Line {
ArrayList<String> words = new ArrayList<String>();
float spacing = 15f;
public Line() {
}
public Line(ArrayList<String> words, float spacing) {
this.words = words;
this.spacing = spacing;
}
public void setSpacing(float spacing) {
this.spacing = spacing;
}
public float getSpacing() {
return spacing;
}
public void addWord(String s) {
words.add(s);
}
public ArrayList<String> getWords() {
return words;
}
}
}
Dodaj powyższą klasę do folderu src i użyj tego przykładowego kodu, aby dodać do swojego układu:
JustifiedTextView jtv= new JustifiedTextView(getApplicationContext(), "Lorem ipsum dolor sit amet... ");
LinearLayout place = (LinearLayout) findViewById(R.id.book_profile_content);
place.addView(jtv);
patrz tutaj na githubie
Wystarczy zaimportować dwa pliki „TextJustifyUtils.java” i „TextViewEx.java” do swojego projektu.
public class TextJustifyUtils {
// Please use run(...) instead
public static void justify(TextView textView) {
Paint paint = new Paint();
String[] blocks;
float spaceOffset = 0;
float textWrapWidth = 0;
int spacesToSpread;
float wrappedEdgeSpace;
String block;
String[] lineAsWords;
String wrappedLine;
String smb = "";
Object[] wrappedObj;
// Pull widget properties
paint.setColor(textView.getCurrentTextColor());
paint.setTypeface(textView.getTypeface());
paint.setTextSize(textView.getTextSize());
textWrapWidth = textView.getWidth();
spaceOffset = paint.measureText(" ");
blocks = textView.getText().toString().split("((?<=\n)|(?=\n))");
if (textWrapWidth < 20) {
return;
}
for (int i = 0; i < blocks.length; i++) {
block = blocks[i];
if (block.length() == 0) {
continue;
} else if (block.equals("\n")) {
smb += block;
continue;
}
block = block.trim();
if (block.length() == 0)
continue;
wrappedObj = TextJustifyUtils.createWrappedLine(block, paint,
spaceOffset, textWrapWidth);
wrappedLine = ((String) wrappedObj[0]);
wrappedEdgeSpace = (Float) wrappedObj[1];
lineAsWords = wrappedLine.split(" ");
spacesToSpread = (int) (wrappedEdgeSpace != Float.MIN_VALUE ? wrappedEdgeSpace
/ spaceOffset
: 0);
for (String word : lineAsWords) {
smb += word + " ";
if (--spacesToSpread > 0) {
smb += " ";
}
}
smb = smb.trim();
if (blocks[i].length() > 0) {
blocks[i] = blocks[i].substring(wrappedLine.length());
if (blocks[i].length() > 0) {
smb += "\n";
}
i--;
}
}
textView.setGravity(Gravity.LEFT);
textView.setText(smb);
}
protected static Object[] createWrappedLine(String block, Paint paint,
float spaceOffset, float maxWidth) {
float cacheWidth = maxWidth;
float origMaxWidth = maxWidth;
String line = "";
for (String word : block.split("\\s")) {
cacheWidth = paint.measureText(word);
maxWidth -= cacheWidth;
if (maxWidth <= 0) {
return new Object[] { line, maxWidth + cacheWidth + spaceOffset };
}
line += word + " ";
maxWidth -= spaceOffset;
}
if (paint.measureText(block) <= origMaxWidth) {
return new Object[] { block, Float.MIN_VALUE };
}
return new Object[] { line, maxWidth };
}
final static String SYSTEM_NEWLINE = "\n";
final static float COMPLEXITY = 5.12f; // Reducing this will increase
// efficiency but will decrease
// effectiveness
final static Paint p = new Paint();
public static void run(final TextView tv, float origWidth) {
String s = tv.getText().toString();
p.setTypeface(tv.getTypeface());
String[] splits = s.split(SYSTEM_NEWLINE);
float width = origWidth - 5;
for (int x = 0; x < splits.length; x++)
if (p.measureText(splits[x]) > width) {
splits[x] = wrap(splits[x], width, p);
String[] microSplits = splits[x].split(SYSTEM_NEWLINE);
for (int y = 0; y < microSplits.length - 1; y++)
microSplits[y] = justify(removeLast(microSplits[y], " "),
width, p);
StringBuilder smb_internal = new StringBuilder();
for (int z = 0; z < microSplits.length; z++)
smb_internal.append(microSplits[z]
+ ((z + 1 < microSplits.length) ? SYSTEM_NEWLINE
: ""));
splits[x] = smb_internal.toString();
}
final StringBuilder smb = new StringBuilder();
for (String cleaned : splits)
smb.append(cleaned + SYSTEM_NEWLINE);
tv.setGravity(Gravity.LEFT);
tv.setText(smb);
}
private static String wrap(String s, float width, Paint p) {
String[] str = s.split("\\s"); // regex
StringBuilder smb = new StringBuilder(); // save memory
smb.append(SYSTEM_NEWLINE);
for (int x = 0; x < str.length; x++) {
float length = p.measureText(str[x]);
String[] pieces = smb.toString().split(SYSTEM_NEWLINE);
try {
if (p.measureText(pieces[pieces.length - 1]) + length > width)
smb.append(SYSTEM_NEWLINE);
} catch (Exception e) {
}
smb.append(str[x] + " ");
}
return smb.toString().replaceFirst(SYSTEM_NEWLINE, "");
}
private static String removeLast(String s, String g) {
if (s.contains(g)) {
int index = s.lastIndexOf(g);
int indexEnd = index + g.length();
if (index == 0)
return s.substring(1);
else if (index == s.length() - 1)
return s.substring(0, index);
else
return s.substring(0, index) + s.substring(indexEnd);
}
return s;
}
private static String justifyOperation(String s, float width, Paint p) {
float holder = (float) (COMPLEXITY * Math.random());
while (s.contains(Float.toString(holder)))
holder = (float) (COMPLEXITY * Math.random());
String holder_string = Float.toString(holder);
float lessThan = width;
int timeOut = 100;
int current = 0;
while (p.measureText(s) < lessThan && current < timeOut) {
s = s.replaceFirst(" ([^" + holder_string + "])", " "
+ holder_string + "$1");
lessThan = p.measureText(holder_string) + lessThan
- p.measureText(" ");
current++;
}
String cleaned = s.replaceAll(holder_string, " ");
return cleaned;
}
private static String justify(String s, float width, Paint p) {
while (p.measureText(s) < width) {
s = justifyOperation(s, width, p);
}
return s;
}
}
i
public class TextViewEx extends TextView {
private Paint paint = new Paint();
private String[] blocks;
private float spaceOffset = 0;
private float horizontalOffset = 0;
private float verticalOffset = 0;
private float horizontalFontOffset = 0;
private float dirtyRegionWidth = 0;
private boolean wrapEnabled = false;
int left, top, right, bottom = 0;
private Align _align = Align.LEFT;
private float strecthOffset;
private float wrappedEdgeSpace;
private String block;
private String wrappedLine;
private String[] lineAsWords;
private Object[] wrappedObj;
private Bitmap cache = null;
private boolean cacheEnabled = false;
public TextViewEx(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// set a minimum of left and right padding so that the texts are not too
// close to the side screen
// this.setPadding(10, 0, 10, 0);
}
public TextViewEx(Context context, AttributeSet attrs) {
super(context, attrs);
// this.setPadding(10, 0, 10, 0);
}
public TextViewEx(Context context) {
super(context);
// this.setPadding(10, 0, 10, 0);
}
@Override
public void setPadding(int left, int top, int right, int bottom) {
// TODO Auto-generated method stub
super.setPadding(left + 10, top, right + 10, bottom);
}
@Override
public void setDrawingCacheEnabled(boolean cacheEnabled) {
this.cacheEnabled = cacheEnabled;
}
public void setText(String st, boolean wrap) {
wrapEnabled = wrap;
super.setText(st);
}
public void setTextAlign(Align align) {
_align = align;
}
@SuppressLint("NewApi")
@Override
protected void onDraw(Canvas canvas) {
// If wrap is disabled then,
// request original onDraw
if (!wrapEnabled) {
super.onDraw(canvas);
return;
}
// Active canas needs to be set
// based on cacheEnabled
Canvas activeCanvas = null;
// Set the active canvas based on
// whether cache is enabled
if (cacheEnabled) {
if (cache != null) {
// Draw to the OS provided canvas
// if the cache is not empty
canvas.drawBitmap(cache, 0, 0, paint);
return;
} else {
// Create a bitmap and set the activeCanvas
// to the one derived from the bitmap
cache = Bitmap.createBitmap(getWidth(), getHeight(),
Config.ARGB_4444);
activeCanvas = new Canvas(cache);
}
} else {
// Active canvas is the OS
// provided canvas
activeCanvas = canvas;
}
// Pull widget properties
paint.setColor(getCurrentTextColor());
paint.setTypeface(getTypeface());
paint.setTextSize(getTextSize());
paint.setTextAlign(_align);
paint.setFlags(Paint.ANTI_ALIAS_FLAG);
// minus out the paddings pixel
dirtyRegionWidth = getWidth() - getPaddingLeft() - getPaddingRight();
int maxLines = Integer.MAX_VALUE;
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
if (currentapiVersion >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
maxLines = getMaxLines();
}
int lines = 1;
blocks = getText().toString().split("((?<=\n)|(?=\n))");
verticalOffset = horizontalFontOffset = getLineHeight() - 0.5f; // Temp
// fix
spaceOffset = paint.measureText(" ");
for (int i = 0; i < blocks.length && lines <= maxLines; i++) {
block = blocks[i];
horizontalOffset = 0;
if (block.length() == 0) {
continue;
} else if (block.equals("\n")) {
verticalOffset += horizontalFontOffset;
continue;
}
block = block.trim();
if (block.length() == 0) {
continue;
}
wrappedObj = TextJustifyUtils.createWrappedLine(block, paint,
spaceOffset, dirtyRegionWidth);
wrappedLine = ((String) wrappedObj[0]);
wrappedEdgeSpace = (Float) wrappedObj[1];
lineAsWords = wrappedLine.split(" ");
strecthOffset = wrappedEdgeSpace != Float.MIN_VALUE ? wrappedEdgeSpace
/ (lineAsWords.length - 1)
: 0;
for (int j = 0; j < lineAsWords.length; j++) {
String word = lineAsWords[j];
if (lines == maxLines && j == lineAsWords.length - 1) {
activeCanvas.drawText("...", horizontalOffset,
verticalOffset, paint);
} else if (j == 0) {
// if it is the first word of the line, text will be drawn
// starting from right edge of textview
if (_align == Align.RIGHT) {
activeCanvas.drawText(word, getWidth()
- (getPaddingRight()), verticalOffset, paint);
// add in the paddings to the horizontalOffset
horizontalOffset += getWidth() - (getPaddingRight());
} else {
activeCanvas.drawText(word, getPaddingLeft(),
verticalOffset, paint);
horizontalOffset += getPaddingLeft();
}
} else {
activeCanvas.drawText(word, horizontalOffset,
verticalOffset, paint);
}
if (_align == Align.RIGHT)
horizontalOffset -= paint.measureText(word) + spaceOffset
+ strecthOffset;
else
horizontalOffset += paint.measureText(word) + spaceOffset
+ strecthOffset;
}
lines++;
if (blocks[i].length() > 0) {
blocks[i] = blocks[i].substring(wrappedLine.length());
verticalOffset += blocks[i].length() > 0 ? horizontalFontOffset
: 0;
i--;
}
}
if (cacheEnabled) {
// Draw the cache onto the OS provided
// canvas.
canvas.drawBitmap(cache, 0, 0, paint);
}
}
}
Teraz, jeśli używasz normalnego tekstu, zobacz:
<TextView
android:id="@+id/original"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/lorum_ipsum" />
Po prostu użyj
<yourpackagename.TextViewEx
android:id="@+id/changed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/lorum_ipsum" />
Zdefiniuj zmienną i ustaw justify to true,
TextViewEx changed = (TextViewEx) findViewById(R.id.changed);
changed.setText(getResources().getString(R.string.lorum_ipsum),true);
Android Text Justify For TextView XML
Po prostu uzasadnij tekst za pomocą Androida w XML. Możesz po prostu zaimplementować w widżecie widoku tekstu.
<TextView
android:justificationMode="inter_word"
/>
Domyślnie jest android:justificationMode="none"
Myślę, że są dwie opcje:
Użyj czegoś takiego jak Pango, który specjalizuje się w tym za pośrednictwem NDK i renderuj tekst na OpenGL lub innej powierzchni.
Użyj Paint.measureText () i znajomych, aby uzyskać długości słów i ułożyć je ręcznie na kanwie w widoku niestandardowym.
Na Androidzie, aby po lewej stronie wyjustować tekst i nie mieć obcięcia koloru tła, spróbuj tego, działało to dla mnie, dając spójne wyniki na Androidzie, FF, tj. & Chrome, ale musisz zmierzyć miejsce, które pozostało pomiędzy tekstem przy obliczaniu wypełnienia.
<td style="font-family:Calibri,Arial;
font-size:15px;
font-weight:800;
background-color:#f5d5fd;
color:black;
border-style:solid;
border-width:1px;
border-color:#bd07eb;
padding-left:10px;
padding-right:1000px;
padding-top:3px;
padding-bottom:3px;
>
Włamanie polega na padding-right:1000px;
popychaniu tekstu do skrajnej lewej strony.
Każda próba opuszczenia lub uzasadnienia kodu w css lub html powoduje, że tło ma tylko połowę szerokości.
W przypadku formatowania HTML nie musisz dzwonić do Webkita, możesz to Html.fromHtml(text)
zrobić.
Źródło: http://developer.android.com/guide/topics/resources/string-resource.html
Android nie obsługuje jeszcze pełnego uzasadnienia. Możemy korzystać z Webview i uzasadniać HTML zamiast z textview. Działa tak dobrze. Jeśli nie macie jasności, zapytajcie mnie :)
WebView
transparent
. Mam obraz tła.
Wypróbuj to rozwiązanie w poniższym linku, po prostu utwórz tę klasę w folderze projektu i użyj jej. działa dla mnie dobrze :)
TextView Content Uzasadnienie: Łatwi faceci po prostu używają Androida: justificationMode = "inter_word" w tagu TextView.
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="92dp"
android:text="@string/contents"
android:layout_margin="20dp"
android:justificationMode="inter_word"
/>
Spróbuj użyć < RelativeLayout >
(upewniając się, że fill_parent), a następnie po prostu dodaj android:layout_alignParentLeft="true"
i
android:layout_alignParentRight="true"
do elementów, które chcesz na zewnątrz LEWO i PRAWO.
BLAM, uzasadnione!
To tak naprawdę nie usprawiedliwia twojego tekstu, ale
android:gravity="center_horizontal"
to najlepszy wybór, jaki masz.