दिलचस्प पोस्ट
उत्तरदायी रूप से पक्ष आकार रखते हुए पहलू अनुपात शुरुआती के लिए गिट: निश्चित व्यावहारिक गाइड PHP के साथ आईपी पता देश प्राप्त करें जावास्क्रिप्ट में GUID / यूयूआईडी बनाएँ? कैसे चर असाइन जावास्क्रिप्ट में काम करता है? गैरोस्कोप और एक्सीलरोमीटर पर आधारित इंडोर पोजिशनिंग सिस्टम कैसे बाश में दो तारों को अलग संस्करण स्वरूप में तुलना करें? सॉकेट प्रोग्रामिंग के लिए नेट 4.5 Async फ़ीचर का उपयोग करना java runtime.getruntime () कमांड लाइन प्रोग्राम निष्पादित करने से आउटपुट प्राप्त कर रहा है 0.0 द्वारा विभाजित करते समय जावा एक अपवाद क्यों नहीं फेंकता? jQuery: क्या मैं addClass () और इस तरह के बीच देरी () को कॉल कर सकता हूं? क्या कोई सरणी में कुछ के पहले सूचकांक को वापस करने के लिए एक नफ काम है? जावास्क्रिप्ट में सरणी चौराहे के लिए सबसे सरल कोड कैसे jQuery का उपयोग कर पेज की स्क्रॉल स्थिति का पता लगाने के लिए AsyncTask और Looper.prepare () त्रुटि

टेक्स्टव्यू फिट करने के लिए टेक्स्ट फ़ॉन्ट आकार को कैसे समायोजित करें

क्या किसी भी तरह से एंड्रॉइड के लिए किसी टेक्स्टव्यू में टेक्स्ट का आकार समायोजित करने के लिए कोई स्थान है जो इसे स्थान पर रखता है?

उदाहरण के लिए, मैं एक TableLayout का उपयोग कर रहा हूं और कई पंक्तियों में कई TextView TableLayout जोड़ रहा हूं। चूंकि मैं TextView को पाठ लपेट नहीं करना चाहता हूं इसलिए यह देखना है कि यह सामग्री के फ़ॉन्ट आकार को कम करता है

कोई विचार?

मैंने measureText की कोशिश की है, लेकिन जब से मुझे पता नहीं है कि स्तंभ के आकार का उपयोग करने के लिए परेशानी लगता है यह वह कोड है जहां मैं फ़ॉन्ट आकार को किसी चीज को बदलना चाहता हूं

 TableRow row = new TableRow(this); for (int i=0; i < ColumnNames.length; i++) { TextView textColumn = new TextView(this); textColumn.setText(ColumnNames[i]); textColumn.setPadding(0, 0, 1, 0); textColumn.setTextColor(getResources().getColor(R.drawable.text_default)); row.addView(textColumn, new TableRow.LayoutParams()); } table.addView(row, new TableLayout.LayoutParams()); 

वेब के समाधान से एकत्रित समाधान "टेक्स्टव्यू फिट करने के लिए टेक्स्ट फ़ॉन्ट आकार को कैसे समायोजित करें"

नीचे दिए गए समाधान में सभी सुझाव यहां शामिल हैं यह मूलतः दूनी द्वारा पोस्ट किया गया था के साथ शुरू होता है। यह एक द्विआधारी खोज का उपयोग करता है जैसे जीजेपीसी, लेकिन यह थोड़ा अधिक पठनीय है। इसमें ग्रेग के बग फिक्स और मेरे अपने बग फिक्स शामिल हैं

 import android.content.Context; import android.graphics.Paint; import android.util.AttributeSet; import android.util.TypedValue; import android.widget.TextView; public class FontFitTextView extends TextView { public FontFitTextView(Context context) { super(context); initialise(); } public FontFitTextView(Context context, AttributeSet attrs) { super(context, attrs); initialise(); } private void initialise() { mTestPaint = new Paint(); mTestPaint.set(this.getPaint()); //max size defaults to the initially specified text size unless it is too small } /* Re size the font so the specified text fits in the text box * assuming the text box is the specified width. */ private void refitText(String text, int textWidth) { if (textWidth <= 0) return; int targetWidth = textWidth - this.getPaddingLeft() - this.getPaddingRight(); float hi = 100; float lo = 2; final float threshold = 0.5f; // How close we have to be mTestPaint.set(this.getPaint()); while((hi - lo) > threshold) { float size = (hi+lo)/2; mTestPaint.setTextSize(size); if(mTestPaint.measureText(text) >= targetWidth) hi = size; // too big else lo = size; // too small } // Use lo so that we undershoot rather than overshoot this.setTextSize(TypedValue.COMPLEX_UNIT_PX, lo); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int parentWidth = MeasureSpec.getSize(widthMeasureSpec); int height = getMeasuredHeight(); refitText(this.getText().toString(), parentWidth); this.setMeasuredDimension(parentWidth, height); } @Override protected void onTextChanged(final CharSequence text, final int start, final int before, final int after) { refitText(text.toString(), this.getWidth()); } @Override protected void onSizeChanged (int w, int h, int oldw, int oldh) { if (w != oldw) { refitText(this.getText().toString(), w); } } //Attributes private Paint mTestPaint; } 

मैंने एक वर्ग लिखा है जो TextView फैलता है और यह करता है यह सिर्फ माप का उपयोग करता है जैसा कि आप सुझाव देते हैं मूल रूप से इसमें अधिकतम टेक्स्ट आकार और न्यूनतम टेक्स्ट आकार (जिसे बदला जा सकता है) है और यह केवल 1 के घटते समय उनके बीच के आकारों के माध्यम से चलाता है जब तक कि इसे फिट होने वाला सबसे बड़ा नहीं लगता विशेष रूप से सुरुचिपूर्ण नहीं है, लेकिन मुझे किसी अन्य तरीके से नहीं पता है।

यहां कोड है:

 import android.content.Context; import android.graphics.Paint; import android.util.AttributeSet; import android.widget.TextView; public class FontFitTextView extends TextView { public FontFitTextView(Context context) { super(context); initialise(); } public FontFitTextView(Context context, AttributeSet attrs) { super(context, attrs); initialise(); } private void initialise() { testPaint = new Paint(); testPaint.set(this.getPaint()); //max size defaults to the intially specified text size unless it is too small maxTextSize = this.getTextSize(); if (maxTextSize < 11) { maxTextSize = 20; } minTextSize = 10; } /* Re size the font so the specified text fits in the text box * assuming the text box is the specified width. */ private void refitText(String text, int textWidth) { if (textWidth > 0) { int availableWidth = textWidth - this.getPaddingLeft() - this.getPaddingRight(); float trySize = maxTextSize; testPaint.setTextSize(trySize); while ((trySize > minTextSize) && (testPaint.measureText(text) > availableWidth)) { trySize -= 1; if (trySize <= minTextSize) { trySize = minTextSize; break; } testPaint.setTextSize(trySize); } this.setTextSize(trySize); } } @Override protected void onTextChanged(final CharSequence text, final int start, final int before, final int after) { refitText(text.toString(), this.getWidth()); } @Override protected void onSizeChanged (int w, int h, int oldw, int oldh) { if (w != oldw) { refitText(this.getText().toString(), w); } } //Getters and Setters public float getMinTextSize() { return minTextSize; } public void setMinTextSize(int minTextSize) { this.minTextSize = minTextSize; } public float getMaxTextSize() { return maxTextSize; } public void setMaxTextSize(int minTextSize) { this.maxTextSize = minTextSize; } //Attributes private Paint testPaint; private float minTextSize; private float maxTextSize; } 

यह स्पीडप्लेन का FontFitTextView , लेकिन यह टेक्स्ट फ़ॉन्ट को कम करने के लिए फ़ॉन्ट आकार घटता है, और इसके फ़ॉन्ट आकार को अन्यथा रखता है। यह ऊंचाई फिट करने के लिए फ़ॉन्ट आकार में वृद्धि नहीं करता है

 public class FontFitTextView extends TextView { // Attributes private Paint mTestPaint; private float defaultTextSize; public FontFitTextView(Context context) { super(context); initialize(); } public FontFitTextView(Context context, AttributeSet attrs) { super(context, attrs); initialize(); } private void initialize() { mTestPaint = new Paint(); mTestPaint.set(this.getPaint()); defaultTextSize = getTextSize(); } /* Re size the font so the specified text fits in the text box * assuming the text box is the specified width. */ private void refitText(String text, int textWidth) { if (textWidth <= 0 || text.isEmpty()) return; int targetWidth = textWidth - this.getPaddingLeft() - this.getPaddingRight(); // this is most likely a non-relevant call if( targetWidth<=2 ) return; // text already fits with the xml-defined font size? mTestPaint.set(this.getPaint()); mTestPaint.setTextSize(defaultTextSize); if(mTestPaint.measureText(text) <= targetWidth) { this.setTextSize(TypedValue.COMPLEX_UNIT_PX, defaultTextSize); return; } // adjust text size using binary search for efficiency float hi = defaultTextSize; float lo = 2; final float threshold = 0.5f; // How close we have to be while (hi - lo > threshold) { float size = (hi + lo) / 2; mTestPaint.setTextSize(size); if(mTestPaint.measureText(text) >= targetWidth ) hi = size; // too big else lo = size; // too small } // Use lo so that we undershoot rather than overshoot this.setTextSize(TypedValue.COMPLEX_UNIT_PX, lo); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int parentWidth = MeasureSpec.getSize(widthMeasureSpec); int height = getMeasuredHeight(); refitText(this.getText().toString(), parentWidth); this.setMeasuredDimension(parentWidth, height); } @Override protected void onTextChanged(final CharSequence text, final int start, final int before, final int after) { refitText(text.toString(), this.getWidth()); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { if (w != oldw || h != oldh) { refitText(this.getText().toString(), w); } } } 

यहां एक उदाहरण है कि इसका इस्तेमाल एक्सएमएल में कैसे किया जा सकता है:

 <com.your.package.activity.widget.FontFitTextView android:id="@+id/my_id" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:text="My Text" android:textSize="60sp" /> 

यह फ़ॉन्ट आकार को 60 एसपी तक रखेगा, जब तक कि टेक्स्ट चौड़ाई में फिट बैठता है। यदि पाठ लंबा है, तो फ़ॉन्ट आकार कम हो जाएगा। इस स्थिति में, height=wrap_content की height=wrap_content भी height=wrap_content कारण बदल जाएगी height=wrap_content

अगर आपको कोई बग मिल जाए, तो संपादित करने में संकोच न करें।

यह मेरा समाधान है जो एमुलेटर और फोन पर काम करता है, लेकिन एक्लिप्स लेआउट एडिटर पर बहुत अच्छी तरह से नहीं है। यह किलाका के कोड से प्रेरित है, लेकिन पाठ का आकार पेंट से नहीं मिला है, लेकिन TextView को कॉलिंग measure(0, 0) को मापने से है।

जावा वर्ग:

 public class FontFitTextView extends TextView { private static final float THRESHOLD = 0.5f; private enum Mode { Width, Height, Both, None } private int minTextSize = 1; private int maxTextSize = 1000; private Mode mode = Mode.None; private boolean inComputation; private int widthMeasureSpec; private int heightMeasureSpec; public FontFitTextView(Context context) { super(context); } public FontFitTextView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public FontFitTextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); TypedArray tAttrs = context.obtainStyledAttributes(attrs, R.styleable.FontFitTextView, defStyle, 0); maxTextSize = tAttrs.getDimensionPixelSize(R.styleable.FontFitTextView_maxTextSize, maxTextSize); minTextSize = tAttrs.getDimensionPixelSize(R.styleable.FontFitTextView_minTextSize, minTextSize); tAttrs.recycle(); } private void resizeText() { if (getWidth() <= 0 || getHeight() <= 0) return; if(mode == Mode.None) return; final int targetWidth = getWidth(); final int targetHeight = getHeight(); inComputation = true; float higherSize = maxTextSize; float lowerSize = minTextSize; float textSize = getTextSize(); while(higherSize - lowerSize > THRESHOLD) { textSize = (higherSize + lowerSize) / 2; if (isTooBig(textSize, targetWidth, targetHeight)) { higherSize = textSize; } else { lowerSize = textSize; } } setTextSize(TypedValue.COMPLEX_UNIT_PX, lowerSize); measure(widthMeasureSpec, heightMeasureSpec); inComputation = false; } private boolean isTooBig(float textSize, int targetWidth, int targetHeight) { setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize); measure(0, 0); if(mode == Mode.Both) return getMeasuredWidth() >= targetWidth || getMeasuredHeight() >= targetHeight; if(mode == Mode.Width) return getMeasuredWidth() >= targetWidth; else return getMeasuredHeight() >= targetHeight; } private Mode getMode(int widthMeasureSpec, int heightMeasureSpec) { int widthMode = MeasureSpec.getMode(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); if(widthMode == MeasureSpec.EXACTLY && heightMode == MeasureSpec.EXACTLY) return Mode.Both; if(widthMode == MeasureSpec.EXACTLY) return Mode.Width; if(heightMode == MeasureSpec.EXACTLY) return Mode.Height; return Mode.None; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); if(!inComputation) { this.widthMeasureSpec = widthMeasureSpec; this.heightMeasureSpec = heightMeasureSpec; mode = getMode(widthMeasureSpec, heightMeasureSpec); resizeText(); } } protected void onTextChanged(final CharSequence text, final int start, final int before, final int after) { resizeText(); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { if (w != oldw || h != oldh) resizeText(); } public int getMinTextSize() { return minTextSize; } public void setMinTextSize(int minTextSize) { this.minTextSize = minTextSize; resizeText(); } public int getMaxTextSize() { return maxTextSize; } public void setMaxTextSize(int maxTextSize) { this.maxTextSize = maxTextSize; resizeText(); } } 

XML विशेषता फ़ाइल:

 <resources> <declare-styleable name="FontFitTextView"> <attr name="minTextSize" format="dimension" /> <attr name="maxTextSize" format="dimension" /> </declare-styleable> </resources> 

इस वर्ग के नवीनतम संस्करण के लिए मेरे गिथूब की जाँच करें। मुझे आशा है कि यह किसी के लिए उपयोगी हो सकता है यदि कोई बग मिला है या यदि कोड को स्पष्टीकरण की आवश्यकता है, तो गिटूब पर एक समस्या खोलने के लिए स्वतंत्र महसूस करें।

https://stackoverflow.com/users/234270/speedplane पर बहुत धन्यवाद। बहुत बढ़िया जवाब!

यहां उनकी प्रतिक्रिया का एक बेहतर संस्करण है जो ऊंचाई का ख्याल रखता है और फ़ॉन्ट आकार को सीमित करने के लिए अधिकतम फोंटसिज़ विशेषता के साथ आता है (मेरे मामले में उपयोगी था, इसलिए मैं इसे साझा करना चाहता था):

 package com.<your_package>; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Paint; import android.graphics.Rect; import android.util.AttributeSet; import android.util.TypedValue; import android.widget.TextView; public class FontFitTextView extends TextView { private Paint mTestPaint; private float maxFontSize; private static final float MAX_FONT_SIZE_DEFAULT_VALUE = 20f; public FontFitTextView(Context context) { super(context); initialise(context, null); } public FontFitTextView(Context context, AttributeSet attributeSet) { super(context, attributeSet); initialise(context, attributeSet); } public FontFitTextView(Context context, AttributeSet attributeSet, int defStyle) { super(context, attributeSet, defStyle); initialise(context, attributeSet); } private void initialise(Context context, AttributeSet attributeSet) { if(attributeSet!=null) { TypedArray styledAttributes = context.obtainStyledAttributes(attributeSet, R.styleable.FontFitTextView); maxFontSize = styledAttributes.getDimension(R.styleable.FontFitTextView_maxFontSize, MAX_FONT_SIZE_DEFAULT_VALUE); styledAttributes.recycle(); } else { maxFontSize = MAX_FONT_SIZE_DEFAULT_VALUE; } mTestPaint = new Paint(); mTestPaint.set(this.getPaint()); //max size defaults to the initially specified text size unless it is too small } /* Re size the font so the specified text fits in the text box * assuming the text box is the specified width. */ private void refitText(String text, int textWidth, int textHeight) { if (textWidth <= 0) return; int targetWidth = textWidth - this.getPaddingLeft() - this.getPaddingRight(); int targetHeight = textHeight - this.getPaddingTop() - this.getPaddingBottom(); float hi = maxFontSize; float lo = 2; // final float threshold = 0.5f; // How close we have to be final float threshold = 1f; // How close we have to be mTestPaint.set(this.getPaint()); Rect bounds = new Rect(); while ((hi - lo) > threshold) { float size = (hi + lo) / 2; mTestPaint.setTextSize(size); mTestPaint.getTextBounds(text, 0, text.length(), bounds); if (bounds.width() >= targetWidth || bounds.height() >= targetHeight) hi = size; // too big else lo = size; // too small // if (mTestPaint.measureText(text) >= targetWidth) // hi = size; // too big // else // lo = size; // too small } // Use lo so that we undershoot rather than overshoot this.setTextSize(TypedValue.COMPLEX_UNIT_PX, lo); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int parentWidth = MeasureSpec.getSize(widthMeasureSpec); int height = getMeasuredHeight(); refitText(this.getText().toString(), parentWidth, height); this.setMeasuredDimension(parentWidth, height); } @Override protected void onTextChanged(final CharSequence text, final int start, final int before, final int after) { refitText(text.toString(), this.getWidth(), this.getHeight()); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { if (w != oldw) { refitText(this.getText().toString(), w, h); } } } 

अनुरूप /res/values/attr.xml फ़ाइल:

 <?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="FontFitTextView"> <attr name="maxFontSize" format="dimension" /> </declare-styleable> </resources> 

उदाहरण:

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:res-auto="http://schemas.android.com/apk/res-auto" android:id="@+id/home_Layout" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/background" tools:ignore="ContentDescription" > ... <com.<your_package>.FontFitTextView android:layout_width="match_parent" android:layout_height="wrap_content" android:singleLine="true" android:text="Sample Text" android:textSize="28sp" res-auto:maxFontSize="35sp"/> ... </RelativeLayout> 

नया maxFontSize विशेषता का उपयोग करने के लिए, उदाहरण में दिखाने के रूप में xmlns:res-auto="http://schemas.android.com/apk/res-auto" को जोड़ने के लिए मत भूलना

मुझे एक ही समस्या थी और मेरे लिए काम करने वाला एक वर्ग लिखा था असल में, मैंने एक अलग कैनवास में टेक्स्ट खींचने के लिए एक स्थैतिक लेआउट का इस्तेमाल किया और जब तक मुझे फिट का आकार नहीं मिल पाया आप निम्न विषय में पोस्ट किए गए क्लास को देख सकते हैं। मुझे उम्मीद है यह मदद करेगा।

बाउंड्स के भीतर फिट करने के लिए ऑटो स्केल टेक्स्ट व्यू टेक्स्ट

संशोधन के साथ काम करता है

आपको पाठ दृश्य आकार इस तरह सेट करना होगा क्योंकि अन्यथा setTextSize मान मान एसपी इकाइयों में है:

 setTextSize(TypedValue.COMPLEX_UNIT_PX, trySize); 

और आपको स्पष्ट रूप से इस कोड को जोड़ने की आवश्यकता है।

 @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int parentWidth = MeasureSpec.getSize(widthMeasureSpec); int parentHeight = MeasureSpec.getSize(heightMeasureSpec); refitText(this.getText().toString(), parentWidth); } 

मापन पर थोड़ा बदलाव:

 @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int parentWidth = MeasureSpec.getSize(widthMeasureSpec); int parentHeight = MeasureSpec.getSize(heightMeasureSpec); refitText(this.getText().toString(), parentWidth); this.setMeasuredDimension(parentWidth, parentHeight); } 

और रिफाइट टेक्स्ट पर द्विआधारी खोज:

 private void refitText(String text, int textWidth) { if (textWidth > 0) { int availableWidth = textWidth - this.getPaddingLeft() - this.getPaddingRight(); int trySize = (int)maxTextSize; int increment = ~( trySize - (int)minTextSize ) / 2; testPaint.setTextSize(trySize); while ((trySize > minTextSize) && (testPaint.measureText(text) > availableWidth)) { trySize += increment; increment = ( increment == 0 ) ? -1 : ~increment / 2; if (trySize <= minTextSize) { trySize = (int)minTextSize; break; } testPaint.setTextSize(trySize); } this.setTextSize( TypedValue.COMPLEX_UNIT_PX, trySize); } } 

मुझे मेरे लिए अच्छी तरह से काम करने के लिए निम्न पाया गया यह ऊँचाई और चौड़ाई दोनों के लिए लूप और खाता नहीं है। ध्यान दें कि दृश्य पर setTextSize को फोन करते समय पीएक्स इकाई को निर्दिष्ट करना महत्वपूर्ण है इसके लिए पिछले पोस्ट में टिप के लिए धन्यवाद!

 Paint paint = adjustTextSize(getPaint(), numChars, maxWidth, maxHeight); setTextSize(TypedValue.COMPLEX_UNIT_PX,paint.getTextSize()); 

यहां मैं जो दिनचर्या का उपयोग करता हूं, वही दृश्य से getPaint () में गुजर रहा हूं। एक 'व्यापक' वर्ण के साथ एक 10 वर्ण स्ट्रिंग वास्तविक स्ट्रिंग से स्वतंत्र चौड़ाई का अनुमान लगाने के लिए उपयोग किया जाता है।

 private static final String text10="OOOOOOOOOO"; public static Paint adjustTextSize(Paint paint, int numCharacters, int widthPixels, int heightPixels) { float width = paint.measureText(text10)*numCharacters/text10.length(); float newSize = (int)((widthPixels/width)*paint.getTextSize()); paint.setTextSize(newSize); // remeasure with font size near our desired result width = paint.measureText(text10)*numCharacters/text10.length(); newSize = (int)((widthPixels/width)*paint.getTextSize()); paint.setTextSize(newSize); // Check height constraints FontMetricsInt metrics = paint.getFontMetricsInt(); float textHeight = metrics.descent-metrics.ascent; if (textHeight > heightPixels) { newSize = (int)(newSize * (heightPixels/textHeight)); paint.setTextSize(newSize); } return paint; } 

मैंने ऊपर दूनी समाधान के भिन्नता का इस्तेमाल किया, लेकिन उस विशेष कोड ने मेरे लिए काम नहीं किया विशेष रूप से, जब पेंट ऑब्जेक्ट का उपयोग दृश्य के पेंट ऑब्जेक्ट के गुणों के लिए सेट करने के लिए करते हैं, और फिर मापन टेक्स्ट () को कॉल करते हैं, तो यह वही मान वापस नहीं देता जैसा कि दृश्य के पेंट ऑब्जेक्ट को सीधे बुलाता है शायद मेरे विचारों के तरीके में कुछ मतभेद हैं जो व्यवहार को अलग करते हैं।

मेरा समाधान दृश्य के पेंट का सीधे उपयोग करना था, हालांकि कई बार दृश्य के लिए फ़ॉन्ट आकार को बदलने में कुछ प्रदर्शन दंड भी हो सकते हैं।

मैं तेज गति से उत्कृष्ट समाधान को सुधारने पर काम कर रहा हूं, और इस के साथ आया यह ऊँचाई का प्रबंधन करता है, जिसमें मार्जिन सेट करना शामिल है, जैसे पाठ को सही ढंग से लंबवत केंद्रित करना चाहिए।

यह चौड़ाई प्राप्त करने के लिए समान कार्य का उपयोग करता है, क्योंकि यह सबसे अच्छा काम करता है, लेकिन ऊंचाई प्राप्त करने के लिए यह एक अलग फ़ंक्शन का उपयोग करता है, क्योंकि ऊंचाई कहीं भी प्रदान नहीं की जाती है। कुछ सुधार किए गए हैं जिन्हें बनाने की ज़रूरत है, लेकिन मुझे ऐसा करने का एक तरीका पता चला है, जबकि आंखों को प्रसन्न करना

 import android.content.Context; import android.graphics.Paint; import android.graphics.Rect; import android.util.AttributeSet; import android.util.TypedValue; import android.widget.TextView; public class FontFitTextView extends TextView { public FontFitTextView(Context context) { super(context); initialize(); } public FontFitTextView(Context context, AttributeSet attrs) { super(context, attrs); initialize(); } private void initialize() { mTestPaint = new Paint(); mTestPaint.set(this.getPaint()); //max size defaults to the initially specified text size unless it is too small } /* Re size the font so the specified text fits in the text box * assuming the text box is the specified width. */ private void refitText(String text, int textWidth,int textHeight) { if (textWidth <= 0) return; int targetWidth = textWidth - this.getPaddingLeft() - this.getPaddingRight(); int targetHeight = textHeight - this.getPaddingTop() - this.getPaddingBottom(); float hi = Math.min(targetHeight,100); float lo = 2; final float threshold = 0.5f; // How close we have to be Rect bounds = new Rect(); mTestPaint.set(this.getPaint()); while((hi - lo) > threshold) { float size = (hi+lo)/2; mTestPaint.setTextSize(size); mTestPaint.getTextBounds(text, 0, text.length(), bounds); if((mTestPaint.measureText(text)) >= targetWidth || (1+(2*(size+(float)bounds.top)-bounds.bottom)) >=targetHeight) hi = size; // too big else lo = size; // too small } // Use lo so that we undershoot rather than overshoot this.setTextSize(TypedValue.COMPLEX_UNIT_PX,(float) lo); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int parentWidth = MeasureSpec.getSize(widthMeasureSpec); int parentHeight = MeasureSpec.getSize(heightMeasureSpec); int height = getMeasuredHeight(); refitText(this.getText().toString(), parentWidth,height); this.setMeasuredDimension(parentWidth, height); } @Override protected void onTextChanged(final CharSequence text, final int start, final int before, final int after) { refitText(text.toString(), this.getWidth(),this.getHeight()); } @Override protected void onSizeChanged (int w, int h, int oldw, int oldh) { if (w != oldw) { refitText(this.getText().toString(), w,h); } } //Attributes private Paint mTestPaint; } 

पिछली पोस्टर्स से प्रेरित होकर मैं अपना समाधान साझा करना चाहता था। यह एक स्केल कारक के साथ काम करता है जो कि पिछले फॉण्ट साइज़ पर लागू होता है ताकि इसे उपलब्ध स्थान में फिट किया जा सके। TextViews onDraw विधि के अप्रत्याशित व्यवहार को रोकने के अलावा, यह केवल अपने स्वयं के पाठ को खींचता है

 public class FontFitTextView extends TextView { // How much of the available space should be used in percent. private static final float MARGINHEIGHT = 0.8f; private static final float MARGINWIDTH = 0.8f; private Paint paint; private int viewWidth; private int viewHeight; private float textHeight; private float textWidth; public FontFitTextView(Context c) { this(c, null); } public FontFitTextView(Context c, AttributeSet attrs) { super(c, attrs); initComponent(); } // Default constructor override public FontFitTextView(Context c, AttributeSet attrs, int defStyle) { super(c, attrs, defStyle); initComponent(); } private void initComponent() { paint = new Paint(); paint.setTextSize(30); paint.setTextAlign(Align.CENTER); paint.setAntiAlias(true); } public void setFontColor(int c) { paint.setColor(c); } private void calcTextSize(String s, Canvas c) { float availableHeight = viewHeight; float availableWidth = viewWidth; // This value scales the old font up or down to match the available // space. float scale = 1.0f; // Rectangle for measuring the text dimensions Rect rect = new Rect(); float oldFontSize = paint.getTextSize(); // Calculate the space used with old font size paint.getTextBounds(s, 0, s.length(), rect); textWidth = rect.width(); textHeight = rect.height(); // find scale-value to fit the text horizontally float scaleWidth = 1f; if (textWidth > 0.0f) { scaleWidth = (availableWidth) / textWidth * MARGINWIDTH; } // find scale-value to fit the text vertically float scaleHeight = 1f; if (textHeight > 0.0f) { scaleHeight = (availableHeight) / textHeight * MARGINHEIGHT; } // We are always limited by the smaller one if (scaleWidth < scaleHeight) { scale = scaleWidth; } else { scale = scaleHeight; } // We apply the scale to the old font size to make it bigger or smaller float newFontSize = (oldFontSize * scale); paint.setTextSize(newFontSize); } /** * Calculates the origin on the Y-Axis (width) for the text in this view. * * @return */ private float calcStartDrawingPosX() { float left = getMeasuredWidth(); float centerY = left - (viewWidth / 2); return centerY; } /** * Calculates the origin on the Y-Axis (height) for the text in this view. * * @return */ private float calcStartDrawingPosY() { float bottom = getMeasuredHeight(); // The paint only centers horizontally, origin on the Y-Axis stays at // the bottom, thus we have to lift the origin additionally by the // height of the font. float centerX = bottom - (viewHeight / 2) + (textHeight / 2); return centerX; } @Override protected void onDraw(Canvas canvas) { String text = getText().toString(); if (text.length() > 0) { calcTextSize(text, canvas); canvas.drawText(text, calcStartDrawingPosX(), calcStartDrawingPosY(), paint); } }; @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { viewWidth = w; viewHeight = h; super.onSizeChanged(w, h, oldw, oldh); } } 
 /* get your context */ Context c = getActivity().getApplicationContext(); LinearLayout l = new LinearLayout(c); l.setOrientation(LinearLayout.VERTICAL); LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, 0); l.setLayoutParams(params); l.setBackgroundResource(R.drawable.border); TextView tv=new TextView(c); tv.setText(" your text here"); /* set typeface if needed */ Typeface tf = Typeface.createFromAsset(c.getAssets(),"fonts/VERDANA.TTF"); tv.setTypeface(tf); // LayoutParams lp = new LayoutParams(); tv.setTextColor(Color.parseColor("#282828")); tv.setGravity(Gravity.CENTER | Gravity.BOTTOM); // tv.setLayoutParams(lp); tv.setTextSize(20); l.addView(tv); return l; 

यह एक सरल समाधान होना चाहिए:

 public void correctWidth(TextView textView, int desiredWidth) { Paint paint = new Paint(); Rect bounds = new Rect(); paint.setTypeface(textView.getTypeface()); float textSize = textView.getTextSize(); paint.setTextSize(textSize); String text = textView.getText().toString(); paint.getTextBounds(text, 0, text.length(), bounds); while (bounds.width() > desiredWidth) { textSize--; paint.setTextSize(textSize); paint.getTextBounds(text, 0, text.length(), bounds); } textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize); } 

नीचे दिए गए कोड के साथ TextView बढ़ाएं और ओवरराइड ऑन ड्रॉ करें। यह पाठ पहलू अनुपात रखेगा लेकिन अंतरिक्ष को भरने के लिए इसे आकार देगा। यदि आवश्यक हो तो आप आसानी से कोड को संशोधित कर सकते हैं

  @Override protected void onDraw(@NonNull Canvas canvas) { TextPaint textPaint = getPaint(); textPaint.setColor(getCurrentTextColor()); textPaint.setTextAlign(Paint.Align.CENTER); textPaint.drawableState = getDrawableState(); String text = getText().toString(); float desiredWidth = getMeasuredWidth() - getPaddingLeft() - getPaddingRight() - 2; float desiredHeight = getMeasuredHeight() - getPaddingTop() - getPaddingBottom() - 2; float textSize = textPaint.getTextSize(); for (int i = 0; i < 10; i++) { textPaint.getTextBounds(text, 0, text.length(), rect); float width = rect.width(); float height = rect.height(); float deltaWidth = width - desiredWidth; float deltaHeight = height - desiredHeight; boolean fitsWidth = deltaWidth <= 0; boolean fitsHeight = deltaHeight <= 0; if ((fitsWidth && Math.abs(deltaHeight) < 1.0) || (fitsHeight && Math.abs(deltaWidth) < 1.0)) { // close enough break; } float adjustX = desiredWidth / width; float adjustY = desiredHeight / height; textSize = textSize * (adjustY < adjustX ? adjustY : adjustX); // adjust text size textPaint.setTextSize(textSize); } float x = desiredWidth / 2f; float y = desiredHeight / 2f - rect.top - rect.height() / 2f; canvas.drawText(text, x, y, textPaint); } 

I wrote a short helper class that makes a textview fit within a certain width and adds ellipsize "…" at the end if the minimum textsize cannot be achieved.

Keep in mind that it only makes the text smaller until it fits or until the minimum text size is reached. To test with large sizes, set the textsize to a large number before calling the help method.

It takes Pixels, so if you are using values from dimen, you can call it like this:


 float minTextSizePx = getResources().getDimensionPixelSize(R.dimen.min_text_size); float maxTextWidthPx = getResources().getDimensionPixelSize(R.dimen.max_text_width); WidgetUtils.fitText(textView, text, minTextSizePx, maxTextWidthPx); 

This is the class I use:


 public class WidgetUtils { public static void fitText(TextView textView, String text, float minTextSizePx, float maxWidthPx) { textView.setEllipsize(null); int size = (int)textView.getTextSize(); while (true) { Rect bounds = new Rect(); Paint textPaint = textView.getPaint(); textPaint.getTextBounds(text, 0, text.length(), bounds); if(bounds.width() < maxWidthPx){ break; } if (size <= minTextSizePx) { textView.setEllipsize(TextUtils.TruncateAt.END); break; } size -= 1; textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, size); } } } 

If a tranformation like allCaps is set, speedplane's approach is buggy. I fixed it, resulting in the following code (sorry, my reputation does not allow me to add this as a comment to speedplane's solution):

 import android.content.Context; import android.graphics.Paint; import android.util.AttributeSet; import android.util.TypedValue; import android.widget.TextView; public class FontFitTextView extends TextView { public FontFitTextView(Context context) { super(context); initialise(); } public FontFitTextView(Context context, AttributeSet attrs) { super(context, attrs); initialise(); } private void initialise() { mTestPaint = new Paint(); mTestPaint.set(this.getPaint()); //max size defaults to the initially specified text size unless it is too small } /* Re size the font so the specified text fits in the text box * assuming the text box is the specified width. */ private void refitText(String text, int textWidth) { if (getTransformationMethod() != null) { text = getTransformationMethod().getTransformation(text, this).toString(); } if (textWidth <= 0) return; int targetWidth = textWidth - this.getPaddingLeft() - this.getPaddingRight(); float hi = 100; float lo = 2; final float threshold = 0.5f; // How close we have to be mTestPaint.set(this.getPaint()); while((hi - lo) > threshold) { float size = (hi+lo)/2; if(mTestPaint.measureText(text) >= targetWidth) hi = size; // too big else lo = size; // too small } // Use lo so that we undershoot rather than overshoot this.setTextSize(TypedValue.COMPLEX_UNIT_PX, lo); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int parentWidth = MeasureSpec.getSize(widthMeasureSpec); int height = getMeasuredHeight(); refitText(this.getText().toString(), parentWidth); this.setMeasuredDimension(parentWidth, height); } @Override protected void onTextChanged(final CharSequence text, final int start, final int before, final int after) { refitText(text.toString(), this.getWidth()); } @Override protected void onSizeChanged (int w, int h, int oldw, int oldh) { if (w != oldw) { refitText(this.getText().toString(), w); } } //Attributes private Paint mTestPaint; } 

I don't known this is correct way or not bt its working …take your view and check OnGlobalLayoutListener() and get textview linecount then set textSize.

  yourView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { if (textView.getLineCount()>=3) { textView.setTextSize(20); }else{ //add somthing } } }); 

Its very simple few line code..

I had this pain in my projects for soooo long until I found this library:

 compile 'me.grantland:autofittextview:0.2.+' 

You just need to add the xml by your needs and it's done. उदाहरण के लिए:

 <me.grantland.widget.AutofitTextView android:layout_width="match_parent" android:layout_height="wrap_content" android:singleLine="true" android:maxLines="2" android:textSize="40sp" autofit:minTextSize="16sp" /> 

You can now do this without a third party library or a widget. It's built into TextView in API level 26. Add android:autoSizeTextType="uniform" to your TextView and set height to it. बस इतना ही।

https://developer.android.com/guide/topics/ui/look-and-feel/autosizing-textview.html

 <?xml version="1.0" encoding="utf-8"?> <TextView android:layout_width="match_parent" android:layout_height="200dp" android:autoSizeTextType="uniform" /> 

You can also use TextViewCompat for compatibility.

Google already made this feature.

 <TextView android:layout_width="match_parent" android:layout_height="200dp" android:autoSizeTextType="uniform" /> 

https://developer.android.com/guide/topics/ui/look-and-feel/autosizing-textview.html