Justifying text inside a TextView in android

前端 未结 4 1399
醉话见心
醉话见心 2021-01-13 10:43

So, as most of you know, there is no text justifying inside a TextView in Android. So, I built a custom TextView to get around the problem. However, for some reason, sometim

相关标签:
4条回答
  • 2021-01-13 10:54

    Try this way to justify text, it works for me

    public class MainActivity extends Activity {
    
        private JustifiedTextView mJTv;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            mJTv=(JustifiedTextView) findViewById(R.id.activity_main_jtv_text);
            mJTv.setText(getResources().getString(R.string.test));
            mJTv.setTextSize(TypedValue.COMPLEX_UNIT_SP,20);
            mJTv.setLineSpacing(15);
            mJTv.setBackgroundColor(Color.RED);
            mJTv.setAlignment(Align.LEFT);
            mJTv.setTypeFace(Typeface.createFromAsset(getAssets(), "fonts/naskh_bold.ttf"));
    
        }
    }
    

    XML

    <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/activity_main_jsv"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    
        <ir.noghteh.JustifiedTextView
            android:id="@+id/activity_main_jtv_text"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="right"
            android:padding="25dp"
            xmlns:noghteh="http://noghteh.ir"
            noghteh:text="@string/hello_world"
            noghteh:textColor="@color/text"
            noghteh:textSize="18sp"
           >
        </ir.noghteh.JustifiedTextView>
    
    </ScrollView>
    

    https://github.com/navabi/JustifiedTextView

    https://github.com/ufo22940268/android-justifiedtextview

    https://github.com/PareshMayani/Android-JustifyText

    0 讨论(0)
  • 2021-01-13 10:55

    LIBRARY: https://github.com/bluejamesbond/TextJustify-Android

    SUPPORTS: Android 2.0 to 5.X

    SCREENSHOT

    0 讨论(0)
  • 2021-01-13 11:03

    So, after looking a bit more at this: https://github.com/ufo22940268/android-justifiedtextview and TextView in general, I discovered that my main problem was my approach.

    Using the approach of scaling the width of the " " characters was sound in theory, but after doing so, the width of the line changes again, as it seems that the width of the line is NOT the sum of its parts.

    I have changed my approach and took inspiration from the link above, and so in my new approach I draw each character by itself, instead of drawing the whole line. If the text needs to be justified (based on a custom "justify" boolean attribute) then it will draw the line and justify it, else it will just draw the line.

    Edit: I have changed the code now so that it also supports RTL texts. I will upload the code somewhere in the next few days.

    Here's the result:

    Here's the code:

    public class DTextView extends AppCompatTextView {
    
    
        private boolean justify;
        private float textAreaWidth;
        private float spaceCharSize;
        private float lineY;
    
        public DTextView(Context context) {
            super(context);
        }
    
        public DTextView(Context context, AttributeSet attrs) {
            super(context, attrs);
            init(attrs);
        }
    
        public DTextView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init(attrs);
        }
    
        /**
         * @param attrs the attributes from the xml
         *              This function loads all the parameters from the xml
         */
        private void init(AttributeSet attrs) {
    
            TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.DTextView, 0, 0);
    
            justify = ta.getBoolean(R.styleable.DTextView_justify, false);
    
            ta.recycle();
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            drawText(canvas);
        }
    
        private void drawText(Canvas canvas) {
            TextPaint paint = getPaint();
            paint.setColor(getCurrentTextColor());
            paint.drawableState = getDrawableState();
            textAreaWidth = getMeasuredWidth() - (getPaddingLeft() + getPaddingRight());
    
            spaceCharSize = paint.measureText(" ");
    
            String text = getText().toString();
            lineY = getTextSize();
    
            Layout textLayout = getLayout();
    
            if (textLayout == null)
                return;
    
            Paint.FontMetrics fm = paint.getFontMetrics();
            int textHeight = (int) Math.ceil(fm.descent - fm.ascent);
            textHeight = (int) (textHeight * getLineSpacingMultiplier() + textLayout.getSpacingAdd());
    
            for (int i = 0; i < textLayout.getLineCount(); i++) {
    
                int lineStart = textLayout.getLineStart(i);
                int lineEnd = textLayout.getLineEnd(i);
    
                float lineWidth = StaticLayout.getDesiredWidth(text, lineStart, lineEnd, paint);
                String line = text.substring(lineStart, lineEnd);
    
                if (line.charAt(line.length() - 1) == ' ') {
                    line = line.substring(0, line.length() - 1);
                }
    
                if (justify && i < textLayout.getLineCount() - 1) {
                    drawLineJustified(canvas, line, lineWidth);
                } else {
                    canvas.drawText(line, 0, lineY, paint);
                }
    
                lineY += textHeight;
            }
    
        }
    
        private void drawLineJustified(Canvas canvas, String line, float lineWidth) {
            TextPaint paint = getPaint();
    
            float emptySpace = textAreaWidth - lineWidth;
            int spaces = line.split(" ").length - 1;
            float newSpaceSize = (emptySpace / spaces) + spaceCharSize;
    
            float charX = 0;
    
            for (int i = 0; i < line.length(); i++) {
                String character = String.valueOf(line.charAt(i));
                float charWidth = StaticLayout.getDesiredWidth(character, paint);
                if (!character.equals(" ")) {
                    canvas.drawText(character, charX, lineY, paint);
                }
    
                if (character.equals(" ") && i != line.length() - 1)
                    charX += newSpaceSize;
                else
                    charX += charWidth;
            }
    
        }
    }
    

    and the XML:

    <il.co.drapp.views.text.DTextView
                    android:layout_width="match_parent"
                    android:inputType="textMultiLine|textNoSuggestions"
                    app:justify="true"
                    android:id="@+id/justifyText"
                    android:text="@string/article_dummy_text"
                    android:layout_height="wrap_content" />
    

    Thanks to Aditya Vyas-Lakhan for the links

    0 讨论(0)
  • 2021-01-13 11:03

    Just user like bellow

    <TextView
        android:id="@+id/tvMessageDetails"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:justificationMode="inter_word"/>
                            
    
    0 讨论(0)
提交回复
热议问题