效果
实现逻辑
明确需求
目前遇到的需求就是,无论内容有多少,都要一行显示完整。(例如应用中金额的显示)整理思路
如果需要控件根据内容自适应文字的大小,那么我们首先要清楚控件的宽度,这里我们在onMeasure()
方法中获取。其次,我们就要在onDraw()
方法中,根据内容来动态的计算需要设置文字的大小。动手实现
在需求明确、思路清晰的情况下就要开始动手实现(需要了解自定义View的一些基础API),下面代码中注释写的基本都差不多,很好理解。欢迎指出讨论!!!补充
示例中忽略了一点就是在计算控件宽度的时候没有考虑到设置内边距这个问题,如果遇到了设置内边距的情况,需要在计算文字大小之前将宽度减去左右内边距PS这个自定义控件已经没有实际意义了,刚看了一篇文章发现Android原生已经有API来解决这个情况了!有兴趣的朋友可以去看看!
完整代码
/**
* 自定义自适应文字内容控件
*
* @attr CustomFitViewTextView
*/
public class CustomFitViewTextView extends AppCompatTextView {
private static final String TAG = "CustomFitViewTextView";
//控件的宽
private int mViewWidth;
//可以设置的最小文字
private float mMinTextSize = 10;
public CustomFitViewTextView(Context context) {
this(context, null);
}
public CustomFitViewTextView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomFitViewTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initAttrs(context, attrs);
}
/**
* 初始化自定义属性
*/
private void initAttrs(Context context, AttributeSet attrs) {
TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomFitViewTextView);
mMinTextSize = mTypedArray.getDimension(R.styleable.CustomFitViewTextView_customMinTextSize, mMinTextSize);
mTypedArray.recycle();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
TextPaint mTextPaint = CustomFitViewTextView.this.getPaint();
//获取当前设置文字的大小
float mSourceTextSize = CustomFitViewTextView.this.getTextSize();
//获取内容
String mLoadContent = CustomFitViewTextView.this.getText().toString().trim();
//测量内容的长度
float mSourceTextContentSize = mTextPaint.measureText(mLoadContent);
if (mSourceTextContentSize > mViewWidth) {//文字内容超过了控件的宽度
//计算文字长度与文字大小的比例
float scale = mSourceTextContentSize / mSourceTextSize;
//根据控件长度计算合适的文字大小
float newTextSize = mViewWidth / scale;
//增加最小限制
if (newTextSize < mMinTextSize) {
newTextSize = mMinTextSize;
}
//重新设置文字尺寸
CustomFitViewTextView.this.setTextSize(TypedValue.COMPLEX_UNIT_PX, newTextSize);
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//计算控件的宽度(如果设置了padding值,需要减去左右的padding值)
mViewWidth = MeasureSpec.getSize(widthMeasureSpec);
}
}
- 自定义属性
<declare-styleable name="CustomFitViewTextView">
<!--文字最小限制-->
<attr name="customMinTextSize" format="dimension" />
</declare-styleable>