简体   繁体   English

android studio中textview对齐的一种简单方法

[英]a simple way for textview justification in android studio

I saw this library : https://github.com/bluejamesbond/TextJustify-Android but it's so complicated and don't know how to use it. 我看到了这个库: https : //github.com/bluejamesbond/TextJustify-Android,但是它是如此复杂,不知道如何使用它。 I have a TextView that fill it programmatically from database in java. 我有一个TextView,可以从Java数据库中以编程方式填充它。 how can I use a simple library to justify it?! 如何使用简单的库对其进行辩护?!

UPDATE 更新

I found this class in Github and it's perfect but I don't remember the link...! 我在Github上找到了这个课程,它很完美,但是我不记得链接了!!

public class JustifiedTextView extends View {

private Context mContext;

private XmlToClassAttribHandler mXmlParser;

private TextPaint textPaint;

private int lineSpace = 0;

private int lineHeight;

private int textAreaWidth;

private int measuredViewHeight, measuredViewWidth;

private String text;

private List<String> lineList = new ArrayList<String>();


/**
 * when we want to draw text after view created to avoid loop in drawing we use this boolean
 */
boolean hasTextBeenDrown = false;

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

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

public JustifiedTextView(Context context) {
    super(context);
    constructor(context, null);

}

private void constructor(Context context, AttributeSet attrs) {

    mContext = context;
    mXmlParser = new XmlToClassAttribHandler(mContext, attrs);
    initTextPaint();

    if (attrs != null) {
        String text;
        int textColor;
        int textSize;
        int textSizeUnit;

        text = mXmlParser.getTextValue();
        textColor = mXmlParser.getColorValue();
        textSize = mXmlParser.getTextSize();
        textSizeUnit = mXmlParser.gettextSizeUnit();


        setText(text);
        setTextColor(textColor);
        if (textSizeUnit == -1)
            setTextSize(textSize);
        else
            setTextSize(textSizeUnit, textSize);



    }

    ViewTreeObserver observer = getViewTreeObserver();


    observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

        @Override
        public void onGlobalLayout() {

            if (hasTextBeenDrown)
                return;
            hasTextBeenDrown = true;
            setTextAreaWidth(getWidth() - (getPaddingLeft() + getPaddingRight()));
            calculate();

        }


    });

}

private void calculate() {
    setLineHeight(getTextPaint());
    lineList.clear();
    lineList = divideOriginalTextToStringLineList(getText());
    setMeasuredDimentions(lineList.size(), getLineHeight(), getLineSpace());
    measure(getMeasuredViewWidth(), getMeasuredViewHeight());
}

private void initTextPaint() {
    textPaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
    textPaint.setTextAlign( Paint.Align.RIGHT);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    if (getMeasuredViewWidth() > 0) {
        requestLayout();
        setMeasuredDimension(getMeasuredViewWidth(), getMeasuredViewHeight());
    } else {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
    invalidate();
}


private int rowIndex = 0, colIndex = 0;

@Override
protected void onDraw(Canvas canvas) {

    rowIndex = getPaddingTop();
    if (getAlignment() == Paint.Align.RIGHT)
        colIndex = getPaddingLeft() + getTextAreaWidth();
    else
        colIndex = getPaddingLeft();

    for (int i = 0; i < lineList.size(); i++) {
        rowIndex += getLineHeight() + getLineSpace();

        canvas.drawText(lineList.get(i), colIndex, rowIndex, getTextPaint());
    }

}


/**
 * this method get the string and divide it to a list of StringLines according to textAreaWidth
 *
 * @param originalText
 * @return
 */
private List<String> divideOriginalTextToStringLineList(String originalText) {

    List<String> listStringLine = new ArrayList<String>();

    String line = "";
    float textWidth;

    String[] listParageraphes = originalText.split("\n");

    for (int j = 0; j < listParageraphes.length; j++) {
        String[] arrayWords = listParageraphes[j].split(" ");

        for (int i = 0; i < arrayWords.length; i++) {

            line += arrayWords[i] + " ";
            textWidth = getTextPaint().measureText(line);

            //if text width is equal to textAreaWidth then just add it to ListStringLine
            if (getTextAreaWidth() == textWidth) {

                listStringLine.add(line);
                line = "";//make line clear
                continue;
            }
            //else if text width excite textAreaWidth then remove last word and justify the StringLine
            else if (getTextAreaWidth() < textWidth) {

                int lastWordCount = arrayWords[i].length();

                //remove last word that cause line width to excite textAreaWidth
                line = line.substring(0, line.length() - lastWordCount - 1);

                // if line is empty then should be skipped
                if (line.trim().length() == 0)
                    continue;

                //and then we need to justify line
                line = justifyTextLine(textPaint, line.trim(), getTextAreaWidth());

                listStringLine.add(line);
                line = "";
                i--;
                continue;
            }

            //if we are now at last line of paragraph then just add it
            if (i == arrayWords.length - 1) {
                listStringLine.add(line);
                line = "";
            }
        }
    }

    return listStringLine;

}

/**
 * this method add space in line until line width become equal to textAreaWidth
 *
 * @param lineString
 * @param lineWidth
 * @param textAreaWidth
 * @return
 */
private String justifyTextLine(TextPaint textPaint, String lineString, int textAreaWidth) {

    int gapIndex = 0;

    float lineWidth = textPaint.measureText(lineString);

    while (lineWidth < textAreaWidth && lineWidth > 0) {

        gapIndex = lineString.indexOf(" ", gapIndex + 2);
        if (gapIndex == -1) {
            gapIndex = 0;
            gapIndex = lineString.indexOf(" ", gapIndex + 1);
            if (gapIndex == -1)
                return lineString;
        }

        lineString = lineString.substring(0, gapIndex) + "  " + lineString.substring(gapIndex + 1, lineString.length());

        lineWidth = textPaint.measureText(lineString);
    }
    return lineString;
}

/**
 * this method calculate height for a line of text according to defined TextPaint
 *
 * @param textPaint
 */
private void setLineHeight(TextPaint textPaint) {

    Rect bounds = new Rect();
    String sampleStr = "این حسین کیست که عالم همه دیوانه اوست";
    textPaint.getTextBounds(sampleStr, 0, sampleStr.length(), bounds);

    setLineHeight(bounds.height());

}

/**
 * this method calculate  view's height   according to line count and line height and view's width
 *
 * @param lineListSize
 * @param lineHeigth
 * @param lineSpace
 */
public void setMeasuredDimentions(int lineListSize, int lineHeigth, int lineSpace) {
    int mHeight = lineListSize * (lineHeigth + lineSpace) + lineSpace;

    mHeight += getPaddingRight() + getPaddingLeft();

    setMeasuredViewHeight(mHeight);

    setMeasuredViewWidth(getWidth());
}


private int getTextAreaWidth() {
    return textAreaWidth;
}

private void setTextAreaWidth(int textAreaWidth) {
    this.textAreaWidth = textAreaWidth;
}

private int getLineHeight() {
    return lineHeight;
}

private int getMeasuredViewHeight() {
    return measuredViewHeight;
}

private void setMeasuredViewHeight(int measuredViewHeight) {
    this.measuredViewHeight = measuredViewHeight;
}

private int getMeasuredViewWidth() {
    return measuredViewWidth;
}

private void setMeasuredViewWidth(int measuredViewWidth) {
    this.measuredViewWidth = measuredViewWidth;
}

private void setLineHeight(int lineHeight) {
    this.lineHeight = lineHeight;
}

public String getText() {
    return text;
}

/**
 * Sets the string value of the JustifiedTextView. JustifiedTextView does not accept HTML-like formatting.
 * Related XML Attributes
 * -noghteh:text
 *
 * @param text
 */
public void setText(String text) {
    this.text = text;
    calculate();
    invalidate();
}

public void setText(int resid) {
    setText(mContext.getResources().getString(resid));
}

public Typeface getTypeFace() {
    return getTextPaint().getTypeface();
}

public void setTypeFace(Typeface typeFace) {
    getTextPaint().setTypeface(typeFace);
}

public float getTextSize() {
    return getTextPaint().getTextSize();
}

public void setTextSize(int unit, float textSize) {
    textSize = TypedValue.applyDimension(unit, textSize, mContext.getResources().getDisplayMetrics());
    setTextSize(textSize);
}

private void setTextSize(float textSize) {
    getTextPaint().setTextSize(textSize);
    calculate();
    invalidate();
}

public TextPaint getTextPaint() {
    return textPaint;
}

public void setTextPaint(TextPaint textPaint) {
    this.textPaint = textPaint;
}

/**
 * set text color
 *
 * @param textColor
 */
public void setTextColor(int textColor) {
    getTextPaint().setColor(textColor);
    invalidate();
}

/**
 * define space between lines
 *
 * @param lineSpace
 */
public void setLineSpacing(int lineSpace) {
    this.lineSpace = lineSpace;
    invalidate();
}

/**
 * @return text color
 */
public int getTextColor() {
    return getTextPaint().getColor();
}


/**
 * space between lines - default is 0
 *
 * @return
 */
public int getLineSpace() {
    return lineSpace;
}


/**
 * get text alignment
 *
 * @return
 */
public Paint.Align getAlignment() {
    return getTextPaint().getTextAlign();
}

/**
 * Align text according to your language
 *
 * @param align
 */
public void setAlignment(Paint.Align align) {
    getTextPaint().setTextAlign(align);
    invalidate();
}}

And this class : 这节课:

public class XmlToClassAttribHandler {
private Resources mRes;
private Context mContext;
private AttributeSet mAttributeSet;

private String namespace="http://noghteh.ir";
private final String KEY_TEXT="text";
private final String KEY_TEXT_SIZE="textSize";
private final String KEY_TEXT_COLOR="textColor";

public XmlToClassAttribHandler(Context context,AttributeSet attributeSet){
    mContext=context;
    mRes=mContext.getResources();
    mAttributeSet=attributeSet;


}

public String getTextValue(){

    String value=mAttributeSet.getAttributeValue(namespace, KEY_TEXT);

    if (value==null)
        return "";

    if (value.length()>1 &&
            value.charAt(0)=='@' &&
            value.contains("@string/")){
        int resId=mRes.getIdentifier(mContext.getPackageName()+":"+value.substring(1), null,null);
        value=mRes.getString(resId);
    }

    return value;

}

public int getColorValue(){

    String value=mAttributeSet.getAttributeValue(namespace, KEY_TEXT_COLOR);

    int color= Color.BLACK;

    if (value==null)
        return color;

    if (value.length()>1 &&
            value.charAt(0)=='@' &&
            value.contains("@color/")){
        int resId=mRes.getIdentifier(mContext.getPackageName()+":"+value.substring(1), null,null);
        color=mRes.getColor(resId);

        return color;
    }


    try{
        color=Color.parseColor(value);
    }
    catch(Exception e){
        return Color.BLACK;
    }


    return color;
}


public int getTextSize() {
    int textSize=12;

    String value=mAttributeSet.getAttributeValue(namespace, KEY_TEXT_SIZE );

    if (value==null)
        return textSize;

    if (value.length()>1 &&
            value.charAt(0)=='@' &&
            value.contains("@dimen/")){
        int resId=mRes.getIdentifier(mContext.getPackageName()+":"+value.substring(1), null,null);
        textSize=mRes.getDimensionPixelSize(resId);

        return textSize;
    }

    try{
        textSize=Integer.parseInt(value.substring(0, value.length()-2));
    }
    catch(Exception e){
        return 12;
    }

    return textSize;
}


public int gettextSizeUnit() {

    String value=mAttributeSet.getAttributeValue(namespace, KEY_TEXT_SIZE );

    if (value==null)
        return TypedValue.COMPLEX_UNIT_SP;

    try{
        String type=value.substring(value.length()-2, value.length());

        if (type.equals("dp"))
            return TypedValue.COMPLEX_UNIT_DIP;
        else if (type.equals("sp"))
            return TypedValue.COMPLEX_UNIT_SP;
        else if (type.equals("pt"))
            return TypedValue.COMPLEX_UNIT_PT;
        else if (type.equals("mm"))
            return TypedValue.COMPLEX_UNIT_MM;
        else if (type.equals("in"))
            return TypedValue.COMPLEX_UNIT_IN;
        else if (type.equals("px"))
            return TypedValue.COMPLEX_UNIT_PX;
    }
    catch(Exception e){
        return -1;
    }

    return -1;
}}

and then define a JustifiedTextView instead of simple TextView in your XML file...!! 然后在您的XML文件中定义JustifiedTextView而不是简单的TextView ...!

Follow the instructions in the readme. 请按照自述文件中的说明进行操作。

  1. Add to your build.gradle 添加到您的build.gradle

    dependencies { compile 'com.github.bluejamesbond:textjustify-android:2.1.1' }

  2. Then you define a DocumentView instead of a TextView : 然后,您定义一个DocumentView而不是TextView

    <com.bluejamesbond.text.DocumentView android:layout_width="fill_parent" android:layout_height="fill_parent"/>

You could also use https://github.com/merterhk/JustifiedTextView which is just a single class to avoid having to incorporate a new library. 您也可以使用https://github.com/merterhk/JustifiedTextView ,它只是一个类,以避免必须合并新的库。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM