Вопрос по textview, text-justify, android, java – Обоснование текста в Android

2

Мне нужно обосновать некоторый текст (RTL), который представляет собой строку (S1) с сервера. НоTextView Можно'т текст, поэтому я должен использоватьWebViewТеперь я должен создать HTML-файл, в котором будет отображатьсяS1, Затем я сохраняю адрес этого HTML-файла в базе данных и затем отображаю этот HTML-файл. Я'Я видел этот вопрос, заданный ранее на SO, и многие рекомендовали использовать стороннюю библиотеку, яМы испробовали все эти подходы безрезультатно (они работают в 90% сценариев, но не являются полностью надежными).

Я чувствую, что этот подход кажется запутанным, мне было интересно, есть ли лучший подход?

Можете ли вы дать образец. Как вы хотите оправдать? .. проверьте этоответ. amalBit
Я обновилgithub.com/bluejamesbond/TextJustify-Android с новейшей техникой. Теперь это должно быть лучше. @amalBit Есть обходной путь! Mathew Kurian
Вот именно то, что вы ищете.stackoverflow.com/a/4314724/2219600 amalBit
я хочу выровнять персидский текст, и если я не могу выровнять его с помощью некоторого класса или библиотеки, я должен получить файл String и Create HTML и загрузить в WebView. Shayan Pourvatan

Ваш Ответ

6   ответов
0

Использовать веб-вид

  WebView tv = (WebView) findViewById(R.id.aboutme); 
  String youtContentStr = String.valueOf(Html
                        .fromHtml("<!--[CDATA[<body style=\"text-align:justify;background-color:#00222222;\"-->"
                                    + text
                                    + "]]>"));

  tv.setBackgroundColor(Color.TRANSPARENT);
  tv.loadData(youtContentStr, "text/html", "utf-8");`
0

Попробуй это:

ДобавитьTextViewJustify.java файл в папке src.

TextViewJustify.java будет так

import android.graphics.Paint;
import android.view.Gravity;
import android.widget.TextView;

public class TextViewJustify {

    /*
     * PLEASE DO NOT REMOVE Coded by Mathew Kurian I wrote this code for a
     * Google Interview for Internship. Unfortunately, I got too nervous during
     * the interview that I messed, but anyhow that doesn't matter. I have
     * resent my work in hopes that I might still get a position there. Thank
     * you :DD
     */

    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 justifyText(final TextView tv, final 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().sp,lit(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;
    }
}

И используйте этот класс так:

TextViewJustify.justifyText(your_text_view, 225f);

В моем случае это было 225f. измените его в соответствии с вашими потребностями.

@ Андру, я неЯ думаю, что люди на самом деле использовали бы это. Поэтому я буду оптимизировать это и повысить его надежность. Если вы являетесь пользователем этого, пожалуйста, следуйте его репозиторию на github, чтобы вы могли оставаться в курсе последних выпусков. Mathew Kurian
я использую этот класс, но эта работа в 90% сценариев, но не является полностью надежной Shayan Pourvatan
Нет я неустановить любую ширину. И я использовал это в диалоговом окне. Это работало как шарм в каждом устройстве. @Shayan Avijit
и для вашего номера (225f) вы должны установить ширину экрана, которая на каждом экране будет работать хорошо, если вы установите окончательное число на другом экране dp, не будет работать хорошо Shayan Pourvatan
Это потому, что вы не можете оправдать текст из XML. Avijit
0

Вы можете оправдать текст, используя WebView Simply

LinearLayout lv=(LinearLayout)dialog.findViewById(R.id.**yourId**);


                     String text1 = ""
                                + "

" +**your text** + "

" + ""; WebView wv=new WebView(getApplicationContext()); wv.loadData(text1,"text/html","utf-8"); lv.removeAllViews(); lv.addView(wv);
если вы можете разделить текст и распечатать его в разных текстовых представлениях, вы можете использовать html-теги для цвета текста, размера текста, стиля текста и т. д. Arunkumar
Мне нужно, чтобы для юридической книги, 100 страниц и многих строк это решение не работало в такой ситуации. В любом случае, проблема была решена с моим ответом на этот пост Shayan Pourvatan
да, вы правы, но в этом проекте я неЯ не хочу использовать HTML-файл, потому что у меня было много текста в базе данных, но спасибо за ваше решение. Shayan Pourvatan
0

Я сделал простой класс.

это можно использовать так же, как TextView

import android.content.Context;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.widget.TextView;

/**
 * text justifying
 * you can just use like TextView
 * @author hyunsikkim
 *
 */
public class JustifiedTextView extends TextView {

public JustifiedTextView(Context context) {
    super(context);
}

public JustifiedTextView(Context context, AttributeSet attrs) {
    super(context, attrs);
}

private void setBreakText(String text) {
    if(text == null) return;

    String breakText = breakText(getPaint(), text, 
            getWidth()-this.getPaddingLeft()-this.getPaddingRight());

    if(breakText.equals(getText()) == false) {
        setText(breakText);
    }
}

public String breakText(Paint textPaint, String strText, int breakWidth) { 
    StringBuilder sb = new StringBuilder(); 
    int endValue = 0; 
    final String NEW_LINE = "\n";
    do{ 
        endValue = textPaint.breakText(strText, true, breakWidth, null); 
        if(endValue > 0) {
            /**
             * handle if text contains NEW_LINE
             */
            final int index = strText.indexOf(NEW_LINE);
            if(0<=index && index <= endValue) {
                endValue = index + NEW_LINE.length();
            }
            final String sub = strText.substring(0, endValue);
            sb.append(sub);
            /**
             * handle breaked text endWidth NEW_LINE
             */
            if(sub.endsWith(NEW_LINE) == false) {
                if(strText.length() != endValue) {
                    sb.append(NEW_LINE);
                }
            }

            strText = strText.substring(endValue); 
        } 
    } while(endValue > 0);
    return sb.toString();
} 

public String breakText(Paint textPaint, int id, int breakWidth) {
    String strText = getResources().getString(id);
    return breakText(textPaint, strText, breakWidth);
}

@Override
protected void onTextChanged(CharSequence text, int start,
        int lengthBefore, int lengthAfter) {
    super.onTextChanged(text, start, lengthBefore, lengthAfter);
    /**
     * this control changes from setText(Charsequence text)
     */
    if(getWidth() != 0) {
        setBreakText(text.toString());
    }
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    /**
     * this help to break initial text.
     */
    if(w != oldw) {
        setBreakText(getText().toString());
    }
}


}
4

Я использую следующий код, который отвечает тем людям, которым нужен этот предмет, и я создаю формулу, которая поддерживается на каждом дисплее.

    public class TextJustify {

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();

/* @author Mathew Kurian */

public static void run(final TextView tv, float origWidth, int paddingLeft, int paddingRight, int marginLeft, int marginRight) {


    origWidth-= paddingRight+marginRight+paddingLeft+marginLeft;
    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.RIGHT);
    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 static final int FinallwidthDp  = 320 ;
     public static final int widthJustify  = 223 ;

     DisplayMetrics metrics = new DisplayMetrics();
     getWindowManager().getDefaultDisplay().getMetrics(metrics);
     int widthPixels = metrics.widthPixels;

     float scaleFactor = metrics.density;
     float widthDp = widthPixels / scaleFactor;

     TextView tv = (TextView) findViewById(R.id.textView1);
     ViewGroup.MarginLayoutParams lp1 = (ViewGroup.MarginLayoutParams) tv.getLayoutParams();

     tv.setText(text);
     TextJustify.run(tv,widthDp / FinallwidthDp * widthJustify , tv.getPaddingLeft(),tv.getPaddingRight() , lp1.leftMargin, lp1.rightMargin);

этот алгоритм проверен на различных устройствах и работал нормально при нормальной работе (не в диалоге) иwrap-content ширина дляTextViewи работал с каждым отступом и margin.if не подходит для вас, вы можете изменитьwidthJustify пока хорошо выглядишь, надеюсь это пригодится. для нового обновления см.это

@Shayanpourvatan тот же вопрос, если вы знаете, пожалуйста, помогите мне. John R
Второй вариант не работает. Так что автор этого проекта сказал мне использовать первый вариант. John R
Здравствуйте, я тот, кто написал эту библиотеку. Я был бы признателен, если бы вы могли добавить поддержку для всех расчетовwidthDp для всех устройств. Я неу меня нет устройства Android, так что мне было бы сложно кодировать и тестировать. Чтобы добавить эту поддержку, пожалуйста, раскошелитьсяgithub.com/bluejamesbond/TextJustify-Androidвнесите изменения, а затем сделайте запрос на удаление, и я объединю код. Я также добавлю вас в качестве участника. Большое спасибо. Mathew Kurian
@ mk1 Я редактировал твою библиотеку, но я неНе знаю, подтверждаю ли я редактирование или нет, потому что я никогда так не делаю, пожалуйста, сообщите мне результат My Edit, я редактирую два файла, читаю меня и ваш класс, в read me я добавляю 10-15 строк, а в вашем классе добавляем 2 строки , Shayan Pourvatan
2

БИБЛИОТЕКА:https://github.com/bluejamesbond/TextJustify-Android

ОПОРЫ: Android 2.0 до 5.X; Строка / Spannables; Поддержка языка RTL!НЕТ WEBVIEW :)

СКРИНШОТ

спасибо человек, я попробую это Shayan Pourvatan

Похожие вопросы