感謝您的點贊和關注!
『前提』
更新日誌:
2021-11-13==V.1.1
2019-1-13==V.1
即將學會
利用TextView的onTextChanged方法來實現寬度高度自適應的控制元件,目前只適用於單行。
背景
小空:出現的原因是專案需要的裝置廣(涉及到手機/平板/大電視/無數的定製裝置)。如果是知名的品牌還好,關鍵客戶還是一些亂七八糟的品牌,無數尺寸造成的螢幕密度。
小芝:你說氣人不氣人。我都炸了。
小空(嘆氣):關鍵又沒給更多的適配開始時間。這就很傷人了,如果使用資原始檔values適配的話,那燒香都怕香不夠,甚至引發一連串的事故。
小芝(疑問):所以呢?有解決辦法嗎!
小空:那當然,雖然是取巧的形式,但好歹解決了問題。最開始的時候也是沒有思路,在GitHub上搜索了半天,終於找到了類似的開源:AutoFitTextView,截止2021-8-2擁有800多Star。其他也搜尋到了不少,但是並不滿足解決需求。
小芝(很開心):哇,感謝開源。
實踐過程
目前適應的範圍:TextView無寬高限制;無其他限制; 不過專案中使用的權重佈局,可根據情況調整!實現的結果:在下方圖的控制元件上回自動填充滿,控制元件大,字型大,控制元件小,字型小!
程式:註釋解釋很全
import
android。content。Context
;
import
android。graphics。Paint
;
import
android。support。annotation。Nullable
;
import
android。text。TextPaint
;
import
android。util。AttributeSet
;
import
android。view。Gravity
;
import
android。widget。TextView
;
/**
* Created by akitaka on 2018-07-05。
* https://zhima。blog。csdn。net/
* https://juejin。cn/user/4265760844943479/columns
* https://www。zhihu。com/people/zhimalier
* @filename FitHeightTextView
* @describe 根據高度自適應字型文字大小
* @email 960576866@qq。com */
public
class
FitHeightTextView
extends
TextView
{
private
Paint
mTextPaint
;
private
float
mMaxTextSize
;
// 獲取當前所設定文字大小作為最大文字大小
private
float
mMinTextSize
=
8
;
//最小的字型大小
public
FitHeightTextView
(
Context
context
)
{
super
(
context
);
}
public
FitHeightTextView
(
Context
context
,
@Nullable
AttributeSet
attrs
)
{
super
(
context
,
attrs
);
setGravity
(
getGravity
()
|
Gravity
。
CENTER_VERTICAL
);
// 預設水平居中
setLines
(
1
);
initialise
();
}
private
void
initialise
()
{
mTextPaint
=
new
TextPaint
();
mTextPaint
。
set
(
this
。
getPaint
());
//預設的大小是設定的大小,如果撐不下了 就改變
mMaxTextSize
=
this
。
getTextSize
();
}
//文字改變的時候
@Override
protected
void
onTextChanged
(
CharSequence
text
,
int
start
,
int
lengthBefore
,
int
lengthAfter
)
{
refitText
(
text
。
toString
(),
this
。
getHeight
());
//textview檢視的高度
super
。
onTextChanged
(
text
,
start
,
lengthBefore
,
lengthAfter
);
}
private
void
refitText
(
String
textString
,
int
height
)
{
if
(
height
>
0
)
{
//減去邊距為字型的實際高度
int
availableHeight
=
height
-
this
。
getPaddingTop
()
-
this
。
getPaddingBottom
();
float
trySize
=
mMaxTextSize
;
mTextPaint
。
setTextSize
(
trySize
);
while
(
mTextPaint
。
descent
()-
mTextPaint
。
ascent
()
>
availableHeight
)
{
//測量的字型高度過大,不斷地縮放
trySize
-=
1
;
//字型不斷地減小來適應
if
(
trySize
<=
mMinTextSize
)
{
trySize
=
mMinTextSize
;
//最小為這個
break
;
}
mTextPaint
。
setTextSize
(
trySize
);
}
setTextSize
(
px2sp
(
getContext
(),
trySize
));
}
}
//大小改變的時候
@Override
protected
void
onSizeChanged
(
int
w
,
int
h
,
int
oldw
,
int
oldh
)
{
if
(
h
!=
oldh
)
{
refitText
(
this
。
getText
()。
toString
(),
h
);
}
}
/**
* 將px值轉換為sp值,保證文字大小不變
*/
public
static
float
px2sp
(
Context
context
,
float
pxValue
)
{
float
fontScale
=
context
。
getResources
()。
getDisplayMetrics
()。
scaledDensity
;
return
(
pxValue
/
fontScale
);
}
}
在佈局中使用的話,注意按照你最大的裝置來設定字型大小,這樣在小裝置上回自動縮放
android:textSize 保持為支援最大裝置的字型大小
android:layout_width=“wrap_content” android:layout_height=“wrap_content” android:gravity=“center_vertical” android:text=“設定” android:textSize=“28sp” android:textColor=“#56BBe0” /> 試驗後就會發現,真的很神奇; 有根據高度,就有根據寬度的自動適配,這個是網上的,同時github上也大多是這種效果;上個簡單的程式碼 /** * Created by akitaka on 2018-07-05。 * https://zhima。blog。csdn。net/ * https://juejin。cn/user/4265760844943479/columns * https://www。zhihu。com/people/zhimalier * @filename FitHeightTextView * @describe 根據高度自適應字型文字大小 * @email 960576866@qq。com */public class FitTextView extends TextView{ private Paint mTextPaint; private float mMaxTextSize; // 獲取當前所設定文字大小作為最大文字大小 private float mMinTextSize = 3; public FitTextView(Context context) { this(context, null); } public FitTextView(Context context, AttributeSet attrs) { super(context, attrs); setGravity(getGravity() | Gravity。CENTER_VERTICAL); // 預設水平居中 setLines(1); initialise(); } @Override protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) { refitText(text。toString(), this。getWidth()); super。onTextChanged(text, start, lengthBefore, lengthAfter); } private void initialise() { mTextPaint = new TextPaint(); mTextPaint。set(this。getPaint()); // 最大的大小預設為特定的文字大小,除非它太小了 mMaxTextSize = this。getTextSize(); // mMinTextSize = 8; } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { if (w != oldw) { refitText(this。getText()。toString(), w); } } /** * Resize 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 = mMaxTextSize; mTextPaint。setTextSize(trySize); while (mTextPaint。measureText(text) > availableWidth) { trySize -= 1; if (trySize <= mMinTextSize) { trySize = mMinTextSize; break; } mTextPaint。setTextSize(trySize); } // setTextSize引數值為sp值 setTextSize(px2sp(getContext(), trySize)); } } /** * 將px值轉換為sp值,保證文字大小不變 */ public static float px2sp(Context context, float pxValue) { float fontScale = context。getResources()。getDisplayMetrics()。scaledDensity; return (pxValue / fontScale); } } 主要的區別在於:TextPaint的方法:measureText(text) descent ascent! 作者:小空和小芝中的小空 轉載說明:務必註明來源: https://www。 zhihu。com/people/zhimal ier 。 謝謝你看到這裡,如果對你有幫助的話,點個贊再走吧! 關注我 @空名先生 『更多專欄』: 有意思又酷的網站網址www。zhihu。com/column/c_1223552298586140672www。zhihu。com/column/c_1223552298586140672精緻神器軟體推薦www。zhihu。com/column/c_1115315026340405248www。zhihu。com/column/c_1115315026340405248精品書籍圖譜www。zhihu。com/column/c_1318553820582780928www。zhihu。com/column/c_1318553820582780928