Как вы получаете текст a, TextView
который будет оправдан (с текстом сбоку на левой и правой сторонах)?
Я нашел возможное решение здесь , но оно не работает (даже если вы измените вертикальный-центр на center_vertical и т. Д.).
Как вы получаете текст a, TextView
который будет оправдан (с текстом сбоку на левой и правой сторонах)?
Я нашел возможное решение здесь , но оно не работает (даже если вы измените вертикальный-центр на center_vertical и т. Д.).
Ответы:
Я не верю, что Android поддерживает полное оправдание.
ОБНОВЛЕНИЕ 2018-01-01 : Android 8.0+ поддерживает режимы выравнивания сTextView
.
Ответ @CommonsWare правильный. Android 8.0+ поддерживает «Полное обоснование» (или просто «Обоснование», как это иногда называют неоднозначно).
Android также поддерживает «выравнивание текста по левому / правому краю». См. Статью об оправдании в Википедии . Многие люди считают, что концепция «выравнивания» включает в себя полное выравнивание, а также выравнивание текста влево / вправо, что они и ищут, когда хотят выполнить выравнивание текста влево / вправо. Этот ответ объясняет, как добиться выравнивания текста влево / вправо.
Можно добиться выравнивания текста по левому / правому краю (в отличие от полного выравнивания, о чем вопрос). Для демонстрации я буду использовать базовую форму с двумя столбцами (метки в левом столбце и текстовые поля в правом столбце) в качестве примера. В этом примере текст в метках в левом столбце будет выровнен по правому краю, поэтому они будут отображаться вровень с текстовыми полями в правом столбце.
В макете XML вы можете заставить сами элементы TextView (левый столбец) выравниваться вправо, добавив следующий атрибут во все TextViews:
<TextView
...
android:layout_gravity="center_vertical|end">
...
</TextView>
Однако если текст переносится на несколько строк, текст все равно будет выровнен по левому краю внутри TextView. При добавлении следующего атрибута фактический текст выравнивается по правому краю (неровно по левому краю) внутри TextView:
<TextView
...
android:gravity="end">
...
</TextView>
Таким образом, атрибут gravity определяет, как выровнять текст внутри TextView layout_gravity указывает, как выровнять / расположить сам элемент TextView.
android:layout_gravity="center_horizontal|center"
android:gravity="center"
.
justify
Для выравнивания текста в Android я использовал 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");
и 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>
Я пока не могу загрузить изображения, чтобы доказать это, но "это работает для меня".
view.loadData()
с view.setBackgroundColor("#00000000")
.
view.loadUrl()
работает, тогда как view.loadData()
нет. Я понятия не имею, почему последний не делает.
Для этого мы создали простой класс. В настоящее время есть два метода для достижения того, что вы ищете. Оба не требуют веб-просмотра и поддерживает поддержку .
БИБЛИОТЕКА : https://github.com/bluejamesbond/TextJustify-Android
ПОДДЕРЖКА : Android 2.0 до 5.X
НАСТРОИТЬ
// Please visit Github for latest setup instructions.
СКРИНШОТ
TextView
в Android O
предлагает полное оправдание (новое типографское выравнивание) себя.
Вам просто нужно сделать это:
Котлин
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
textView.justificationMode = JUSTIFICATION_MODE_INTER_WORD
}
Ява
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
textView.setJustificationMode(JUSTIFICATION_MODE_INTER_WORD);
}
по умолчанию JUSTIFICATION_MODE_NONE
.
Вы можете использовать проект JustifiedTextView for Android в github. это пользовательский вид, имитирующий оправданный текст для вас. Он поддерживает Android 2.0+ и справа налево языки.
Я пишу базу виджетов на родном textview, чтобы сделать это.
Я нашел способ решить эту проблему, но это может быть не очень благодати, но эффект не плохой.
Его принцип заключается в замене пробелов каждой строки на ImageSpan фиксированной ширины (цвет прозрачный).
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);
}
}
});
}
Я положил код на GitHub: https://github.com/twiceyuan/TextJustification
Обзор:
XML-макет: объявите WebView вместо TextView
<WebView
android:id="@+id/textContent"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
Java-код: установить текстовые данные в 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");
Это может решить вашу проблему. Это полностью сработало для меня.
Вот как я это сделал, я думаю, самый элегантный способ, которым я мог. С этим решением единственные вещи, которые вам нужно сделать в ваших макетах:
xmlns
декларациюTextView
исходное текстовое пространство имен с Android на новое пространство именTextView
сx.y.z.JustifiedTextView
Вот код Отлично работает на моих телефонах (Galaxy Nexus Android 4.0.2, Galaxy Teos Android 2.1). Не стесняйтесь, конечно, заменить имя моего пакета на ваше.
/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);
}
}
Нам нужно настроить рендеринг на программное обеспечение, чтобы получить прозрачный фон на Android 3+. Отсюда и попытка поймать старые версии Android.
Надеюсь это поможет!
PS: пожалуйста, помните, что было бы полезно добавить это к вашей активности на Android 3+, чтобы получить ожидаемое поведение:
android:hardwareAccelerated="false"
Очень просто Мы можем сделать это в файле XML
<TextView
android:justificationMode="inter_word"
/>
Несмотря на то, что вы еще не завершили выровненный текст, теперь вы можете балансировать длины строк, используя android:breakStrategy="balanced"
API 23 и выше
http://developer.android.com/reference/android/widget/TextView.html#attr_android:breakStrategy
Я пишу свой собственный класс, чтобы решить эту проблему, Вот только вы должны вызвать статическую функцию justify, которая принимает два аргумента
//Основная деятельность
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
эквивалентно CENTER_HORIZONTAL
. Вы можете увидеть этот фрагмент кода в исходном коде textview:
case Gravity.CENTER_HORIZONTAL:
case Gravity.FILL_HORIZONTAL:
return (mLayout.getLineWidth(0) - ((mRight - mLeft) -
getCompoundPaddingLeft() - getCompoundPaddingRight())) /
getHorizontalFadingEdgeLength();
Существует CustomView для этой проблемы, это настраиваемое текстовое представление поддерживает Justered Text View.
Взгляните на это: 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;
}
}
}
Добавьте вышеупомянутый класс в вашу папку src и используйте этот пример кода, чтобы добавить в свой макет:
JustifiedTextView jtv= new JustifiedTextView(getApplicationContext(), "Lorem ipsum dolor sit amet... ");
LinearLayout place = (LinearLayout) findViewById(R.id.book_profile_content);
place.addView(jtv);
смотрите здесь в GitHub
Просто импортируйте два файла "TextJustifyUtils.java" и "TextViewEx.java" в ваш проект.
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;
}
}
а также
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);
}
}
}
Теперь, если вы используете обычный textView, как:
<TextView
android:id="@+id/original"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/lorum_ipsum" />
Просто использовать
<yourpackagename.TextViewEx
android:id="@+id/changed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/lorum_ipsum" />
Определите переменную и установите justify на true,
TextViewEx changed = (TextViewEx) findViewById(R.id.changed);
changed.setText(getResources().getString(R.string.lorum_ipsum),true);
Android Text Justify For TextView XML
Просто Android-текст оправдать использование в XML. Вы можете просто реализовать в виджете textview.
<TextView
android:justificationMode="inter_word"
/>
По умолчанию android:justificationMode="none"
Я думаю, что есть два варианта:
Используйте что-то вроде Pango, который специализируется на этом через NDK, и визуализируйте текст на OpenGL или другой поверхности.
Используйте Paint.measureText () и друзей, чтобы получить длины слов и выложить их вручную на холсте в пользовательском представлении.
На Android, чтобы выровнять текст по левому краю и не иметь усечения цвета фона, попробуйте это, это сработало для меня, производя согласованные результаты на Android, FF, т.е. и Chrome, но вы должны измерить пространство, оставшееся между текстом при расчете заполнения.
<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;
>
Хак это то, padding-right:1000px;
что толкает текст в крайнее левое положение.
Любая попытка влево или выровнять код в CSS или HTML приводит к фону, который имеет только половинную ширину.
Для форматирования HTML вам не нужно вызывать Webkit, вы можете использовать Html.fromHtml(text)
для выполнения этой работы.
Источник: http://developer.android.com/guide/topics/resources/string-resource.html
Android пока не поддерживает полное обоснование. Мы можем использовать Webview и обосновать HTML вместо использования textview. Это работает так хорошо. Если вы, ребята, не ясно, не стесняйтесь спрашивать меня :)
WebView
transparent
. У меня есть фоновое изображение.
Попробуйте это решение по ссылке ниже, просто создайте этот класс в папке проекта и используйте его. Он отлично работает для меня :)
Обоснование содержимого TextView. Его простые парни просто используют android: justificationMode = "inter_word" в вашем теге 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"
/>
Попробуйте использовать < RelativeLayout >
(убедитесь, что fill_parent), затем просто добавьте android:layout_alignParentLeft="true"
и
android:layout_alignParentRight="true"
к элементам, которые вы хотели бы снаружи слева и справа.
БЛАМ, оправдано!
Это не совсем оправдывает ваш текст, но
android:gravity="center_horizontal"
это лучший выбор, который у вас есть.