添加 Android/Demo1/TextViewAutoLayout.java
This commit is contained in:
parent
55cb9f689b
commit
8798b50079
126
Android/Demo1/TextViewAutoLayout.java
Normal file
126
Android/Demo1/TextViewAutoLayout.java
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.text.Layout;
|
||||||
|
import android.text.StaticLayout;
|
||||||
|
import android.text.TextPaint;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TextView + View 动态布局
|
||||||
|
* 该布局目前仅支持TextView + View 组合。
|
||||||
|
* 来源:https://www.loongwind.com/archives/217.html
|
||||||
|
*/
|
||||||
|
public class CustomLayout extends ViewGroup {
|
||||||
|
//单行显示
|
||||||
|
private static final int SINGLE_LINE = 0x01;
|
||||||
|
//多行显示
|
||||||
|
private static final int MULTI_LINE = 0x02;
|
||||||
|
//显示到下一行
|
||||||
|
private static final int NEXT_LINE = 0x03;
|
||||||
|
//显示样式
|
||||||
|
private int type;
|
||||||
|
//绘制文字最后一行的顶部坐标
|
||||||
|
private int lastLineTop;
|
||||||
|
//绘制文字最后一行的右边坐标
|
||||||
|
private float lastLineRight;
|
||||||
|
|
||||||
|
public CustomLayout(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CustomLayout(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CustomLayout(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||||
|
super(context, attrs, defStyleAttr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||||
|
int childCount = getChildCount();
|
||||||
|
int w = MeasureSpec.getSize(widthMeasureSpec);
|
||||||
|
if (childCount == 2) {
|
||||||
|
TextView tv = null;
|
||||||
|
if(getChildAt(0) instanceof TextView){
|
||||||
|
tv = (TextView) getChildAt(0);
|
||||||
|
initTextParams(tv.getText(), tv.getMeasuredWidth(), tv.getPaint());
|
||||||
|
}else{
|
||||||
|
throw new RuntimeException("CustomLayout first child view not a TextView");
|
||||||
|
}
|
||||||
|
|
||||||
|
View sencodView = getChildAt(1);
|
||||||
|
|
||||||
|
//测量子view的宽高
|
||||||
|
measureChildren(widthMeasureSpec, heightMeasureSpec);
|
||||||
|
|
||||||
|
//两个子view宽度相加小于该控件宽度的时候
|
||||||
|
if (tv.getMeasuredWidth() + sencodView.getMeasuredWidth() <= w) {
|
||||||
|
int width = tv.getMeasuredWidth()+sencodView.getMeasuredWidth();
|
||||||
|
//计算高度
|
||||||
|
int height = Math.max(tv.getMeasuredHeight(), sencodView.getMeasuredHeight());
|
||||||
|
//设置该viewgroup的宽高
|
||||||
|
setMeasuredDimension(width, height);
|
||||||
|
type = SINGLE_LINE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (getChildAt(0) instanceof TextView) {
|
||||||
|
//最后一行文字的宽度加上第二个view的宽度大于viewgroup宽度时第二个控件换行显示
|
||||||
|
if (lastLineRight + sencodView.getMeasuredWidth() > w) {
|
||||||
|
setMeasuredDimension(tv.getMeasuredWidth(), tv.getMeasuredHeight() + sencodView.getMeasuredHeight());
|
||||||
|
type = NEXT_LINE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int height = Math.max(tv.getMeasuredHeight(), lastLineTop + sencodView.getMeasuredHeight());
|
||||||
|
setMeasuredDimension(tv.getMeasuredWidth(), height);
|
||||||
|
type = MULTI_LINE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("CustomLayout child count must is 2");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
||||||
|
if (type == SINGLE_LINE || type == MULTI_LINE) {
|
||||||
|
TextView tv = (TextView) getChildAt(0);
|
||||||
|
View v1 = getChildAt(1);
|
||||||
|
//设置第二个view在Textview文字末尾位置
|
||||||
|
tv.layout(0, 0, tv.getMeasuredWidth(), tv.getMeasuredHeight());
|
||||||
|
int left = (int) lastLineRight;
|
||||||
|
int top = lastLineTop;
|
||||||
|
//最后一行的高度 注:通过staticLayout得到的行高不准确故采用这种方式
|
||||||
|
int lastLineHeight = tv.getBottom()-tv.getPaddingBottom() -lastLineTop;
|
||||||
|
//当第二view高度小于单行文字高度时竖直居中显示
|
||||||
|
if(v1.getMeasuredHeight() < lastLineHeight){
|
||||||
|
top = lastLineTop + (lastLineHeight - v1.getMeasuredHeight())/2;
|
||||||
|
}
|
||||||
|
v1.layout(left, top, left + v1.getMeasuredWidth(), top+v1.getMeasuredHeight());
|
||||||
|
} else if (type == NEXT_LINE) {
|
||||||
|
View v0 = getChildAt(0);
|
||||||
|
View v1 = getChildAt(1);
|
||||||
|
//设置第二个view换行显示
|
||||||
|
v0.layout(0, 0, v0.getMeasuredWidth(), v0.getMeasuredHeight());
|
||||||
|
v1.layout(0, v0.getMeasuredHeight(), v1.getMeasuredWidth(), v0.getMeasuredHeight() + v1.getMeasuredHeight());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 得到Textview绘制文字的基本信息
|
||||||
|
* @param text Textview的文字内容
|
||||||
|
* @param maxWidth Textview的宽度
|
||||||
|
* @param paint 绘制文字的paint
|
||||||
|
*/
|
||||||
|
private void initTextParams(CharSequence text, int maxWidth, TextPaint paint) {
|
||||||
|
StaticLayout staticLayout = new StaticLayout(text, paint, maxWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
|
||||||
|
int lineCount = staticLayout.getLineCount();
|
||||||
|
lastLineTop = staticLayout.getLineTop(lineCount - 1);
|
||||||
|
lastLineRight = staticLayout.getLineRight(lineCount - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user