android - एंड्रॉइड टेक्स्टव्यू टेक्स्ट जस्टिफ़ाई करें




text format (15)

आपको TextView का टेक्स्ट जस्टिफाइड करने के लिए कैसे मिलता है (बाएं- और दाईं ओर वाले टेक्स्ट फ्लश के साथ)?

मुझे here एक संभावित समाधान मिला, लेकिन यह काम नहीं करता है (भले ही आप वर्टिकल-सेंटर को center_vertical, आदि में बदल दें)।


UPDATED

हमने इसके लिए एक साधारण वर्ग बनाया है। आप जो खोज रहे हैं उसे प्राप्त करने के लिए वर्तमान में दो विधियां हैं। दोनों को कोई वेबब्यू और सप्लायर स्पैनबैबल्स की आवश्यकता नहीं है

पुस्तकालय : https://github.com/bluejamesbond/TextJustify-Android

समर्थन : एंड्रॉइड 2.0 से 5.X

सेट अप

// Please visit Github for latest setup instructions.

SCREENSHOT


< RelativeLayout > (fill_parent सुनिश्चित करने के लिए सुनिश्चित करें) का उपयोग करने का प्रयास करें, फिर केवल android:layout_alignParentLeft="true" जोड़ें android:layout_alignParentLeft="true" और

android:layout_alignParentRight="true" उन तत्वों के लिए android:layout_alignParentRight="true" जिन्हें आप बाहरी बाएं और दाएं भाग पर चाहते हैं।

ब्लाम, न्यायसंगत!


आप github में एंड्रॉइड प्रोजेक्ट के लिए JustifiedTextView का उपयोग कर सकते हैं। यह एक कस्टम दृश्य है जो आपके लिए उचित पाठ अनुकरण करता है। यह एंड्रॉइड 2.0+ और बाएं से दाएं भाषाओं का समर्थन करता है।


आपको सेट करना है

android:layout_height="wrap_content"

तथा

android:layout_centerInParent="true"

एंड्रॉइड अभी तक पूर्ण औचित्य का समर्थन नहीं करता है। हम वेबव्यू का उपयोग कर सकते हैं और टेक्स्टव्यू का उपयोग करने के बजाय एचटीएमएल को न्यायसंगत बना सकते हैं। यह बहुत अच्छा काम करता है। यदि आप लोग स्पष्ट नहीं हैं, तो मुझसे पूछने में संकोच न करें :)


एंड्रॉइड पर, टेक्स्ट को औचित्य देने के लिए और पृष्ठभूमि रंग का छंटनी नहीं करने के लिए, इसे आजमाएं, यह मेरे लिए काम करता है, एंड्रॉइड, एफएफ, यानी क्रोम पर लगातार परिणाम उत्पन्न करता है लेकिन आपको टेक्स्ट के बीच में मौजूद स्पेस को मापना होगा पैडिंग की गणना करते समय।

<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; जो पाठ को चरम बाईं ओर धक्का देता है।

सीएसएस या एचटीएमएल में बाएं या औचित्य कोड को करने का कोई भी प्रयास पृष्ठभूमि में केवल आधा चौड़ाई है।


एक्सएमएल लेआउट: TextView के बजाय WebView घोषित करें

<WebView
 android:id="@+id/textContent"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content" />

जावा कोड: वेब व्यू पर टेक्स्ट डेटा सेट करें

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

यह आपकी समस्या हल कर सकता है। यह पूरी तरह से मेरे लिए काम किया।


एचटीएमएल बनाने के लिए आपको वेबकिट को कॉल करने की आवश्यकता नहीं है, आप नौकरी करने के लिए Html.fromHtml(text) का उपयोग कर सकते हैं।

स्रोत: http://developer.android.com/guide/topics/resources/string-resource.html


मुझे इस समस्या को हल करने का एक तरीका मिला, लेकिन यह बहुत अनुग्रह नहीं हो सकता है, लेकिन प्रभाव खराब नहीं है।

इसका सिद्धांत प्रत्येक पंक्ति की रिक्त स्थान को निश्चित-चौड़ाई 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);
            }
        }
    });
}

मैंने गिटहब पर कोड डाला: https://github.com/twiceyuan/TextJustification

अवलोकन:


मुझे लगता है कि दो विकल्प हैं:

  • पेंगो जैसे कुछ का उपयोग करें जो एनडीके के माध्यम से इसमें माहिर हैं और ओपनजीएल या अन्य सतह पर टेक्स्ट प्रस्तुत करते हैं।

  • शब्दों की लंबाई प्राप्त करने के लिए Paint.measureText() और दोस्तों का उपयोग करें और कस्टम दृश्य में कैनवास पर मैन्युअल रूप से उन्हें बाहर रखें।


मैं इस समस्या को हल करने के लिए अपनी खुद की कक्षा लिखता हूं, यहां बस आपको स्थिर औचित्य समारोह को कॉल करना है जो दो तर्क लेता है

  1. टेक्स्ट व्यू ऑब्जेक्ट
  2. सामग्री चौड़ाई (आपके टेक्स्ट व्यू की कुल चौड़ाई)

//मुख्य गतिविधि

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;
    }

}

// एक्सएमएल

 <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>

मैं इसे करने के लिए मूल पाठ दृश्य पर एक विजेट आधार लिखता हूं।

github


यहां बताया गया है कि मैंने यह कैसे किया, मुझे लगता है कि मैं सबसे शानदार तरीका कर सकता हूं। इस समाधान के साथ, आपके लेआउट में केवल एक चीज करने की आवश्यकता है:

  • एक अतिरिक्त xmlns घोषणा जोड़ें
  • अपने टेक्स्ट TextView स्रोत टेक्स्ट नेमस्पेस को एंड्रॉइड से अपने नए नेमस्पेस में बदलें
  • xyzJustifiedTextView साथ अपने xyzJustifiedTextView प्रतिस्थापित करें

कोड यहाँ है। मेरे फोन पर पूरी तरह से ठीक काम करता है (गैलेक्सी नेक्सस एंड्रॉइड 4.0.2, गैलेक्सी टीओएस एंड्रॉइड 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+ पर पारदर्शी पृष्ठभूमि प्राप्त करने के लिए हमें प्रतिपादन को सॉफ़्टवेयर में सेट करने की आवश्यकता है। इसलिए एंड्रॉइड के पुराने संस्करणों के लिए प्रयास करें।

उम्मीद है की यह मदद करेगा!

पीएस: कृपया अपेक्षित व्यवहार प्राप्त करने के लिए एंड्रॉइड 3+ पर अपनी पूरी गतिविधि में इसे जोड़ने के लिए उपयोगी नहीं हो सकता है:
android:hardwareAccelerated="false"


हालांकि अभी भी उचित टेक्स्ट पूरा नहीं किया गया है, अब आप android:breakStrategy="balanced" का उपयोग कर लाइन लम्बाई को संतुलित कर सकते हैं android:breakStrategy="balanced" API 23 से आगे android:breakStrategy="balanced"

http://developer.android.com/reference/android/widget/TextView.html#attr_android:breakStrategy


FILL_HORIZONTAL के समतुल्य है। आप टेक्स्टव्यू के स्रोत कोड में यह कोड स्निपेट देख सकते हैं:

case Gravity.CENTER_HORIZONTAL:
case Gravity.FILL_HORIZONTAL:
    return (mLayout.getLineWidth(0) - ((mRight - mLeft) -
            getCompoundPaddingLeft() - getCompoundPaddingRight())) /
            getHorizontalFadingEdgeLength();




justify