此自定義佈局實現的效果是:整個佈局的最大寬度給定情況下,左邊TextView寬度自適應,最多兩行顯示;右邊控件緊貼左邊TextView,如果TextView顯示兩行,右邊控件轉到緊貼第二行文本後面顯示。最終的效果圖如下:
自定義控件代碼如下:
package com.rzc.widget;
import android.content.Context;
import android.support.annotation.Nullable;
import android.text.Layout;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
/**
* Created by rzc on 17/10/23.
*/
public class MaxTwoLineTextLabelLayout extends ViewGroup {
private static final int MAX_LINE = 2;//如果要改成TextView最大其他行數,這裏跟xml文件同時修改,保持值一致(目前支持2行,其他行還有bug,需要下面代碼調整下
private static final int CHILD_COUNT = 2;//目前支持包含兩個子控件,左邊必須是TextView,右邊是任意的View或ViewGroup
public MaxTwoLineTextLabelLayout(Context context) {
super(context);
}
public MaxTwoLineTextLabelLayout(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new MarginLayoutParams(getContext(), attrs);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
if (getChildCount() == CHILD_COUNT && getChildAt(0) instanceof TextView) {
int width = r - l;
TextView child0 = (TextView) getChildAt(0);
int child0Width = child0.getMeasuredWidth();
int child0Height = child0.getMeasuredHeight();
View child1 = getChildAt(1);
int child1Width = child1.getMeasuredWidth();
MarginLayoutParams lp = (MarginLayoutParams) child1.getLayoutParams();
int child1Height = child1.getMeasuredHeight();
int destWidth = child0Width + child1Width + lp.leftMargin;
if (destWidth > width) {//一行顯示不下
if (child0.getLineCount() == 1) {//文本只有一行
child0.layout(0, 0, child0Width, child0Height);
int top = child0Height + lp.topMargin;
child1.layout(0, top, child1Width, top + child1Height);
} else {
child0.layout(0, 0, child0Width, child0Height);
int lineWidth = getLineWidth(child0, MAX_LINE - 1);
if (lineWidth + lp.leftMargin + child1Width < width) {
int left = lineWidth + lp.leftMargin;
int top = (child0Height + child0Height / 2 - child1Height) / 2;
child1.layout(left, top, left + child1Width, top + child1Height);
}
}
} else {
child0.layout(0, 0, child0Width, child0Height);
int left = child0Width + lp.leftMargin;
int top = (child0Height - child1Height) / 2;
child1.layout(left, top, left + child1Width, top + child1Height);
}
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int maxWidth = MeasureSpec.getSize(widthMeasureSpec);
int maxHeight = MeasureSpec.getSize(heightMeasureSpec);
if (getChildCount() == 2 && getChildAt(0) instanceof TextView) {
TextView child0 = (TextView) getChildAt(0);
measureChild(child0, widthMeasureSpec, heightMeasureSpec);
int child0Width = child0.getMeasuredWidth();
int child0Height = child0.getMeasuredHeight();
View child1 = getChildAt(1);
measureChild(child1, widthMeasureSpec, heightMeasureSpec);
int child1Width = child1.getMeasuredWidth();
MarginLayoutParams lp = (MarginLayoutParams) child1.getLayoutParams();
int child1Height = child1.getMeasuredHeight();
int destWidth = child0Width + child1Width + lp.leftMargin;
int destHeight = 0;
if (destWidth > maxWidth) {//一行顯示不下
if (child0.getLineCount() == 1) {//文本只有一行
destWidth = child0Width;
destHeight = lp.topMargin + child0Height + child1Height;//+ line extraspace
} else {
destWidth = Math.max(child0Width, maxWidth);
destHeight = child0Height;
}
} else {
destHeight = child0Height;
}
setMeasuredDimension(destWidth, destHeight);
} else {
setMeasuredDimension(maxWidth, maxHeight);
}
}
private int getLineWidth(TextView textView, int lineNum) {
Layout layout = textView.getLayout();
int lineCount = textView.getLineCount();
if (layout != null && lineNum >= 0 && lineNum < lineCount) {
return (int) (layout.getLineWidth(lineNum) + 0.5);
}
return 0;
}
}
上面demo圖片的xml佈局代碼如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="20dp">
<com.rzc.widget.MaxTwoLineTextLabelLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginRight="50dp" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="2"
android:text="文本只顯示了一行,圖片接着文本顯示"
android:textSize="15dp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="3dp"
android:layout_marginTop="2dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:layout_width="12dp"
android:layout_height="12dp"
android:src="@mipmap/ic_launcher" />
</LinearLayout>
</com.rzc.widget.MaxTwoLineTextLabelLayout>
<com.rzc.widget.MaxTwoLineTextLabelLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginRight="50dp"
android:layout_marginTop="30dp" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="2"
android:text="文本顯示了一行,圖片顯示在第二行的情況"
android:textSize="15dp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="3dp"
android:layout_marginTop="2dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:layout_width="12dp"
android:layout_height="12dp"
android:src="@mipmap/ic_launcher" />
</LinearLayout>
</com.rzc.widget.MaxTwoLineTextLabelLayout>
<com.rzc.widget.MaxTwoLineTextLabelLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginRight="50dp"
android:layout_marginTop="30dp" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="2"
android:text="文本顯示了兩行,圖片跟着文本顯示在第二行文字後面"
android:textSize="15dp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="3dp"
android:layout_marginTop="2dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:layout_width="12dp"
android:layout_height="12dp"
android:src="@mipmap/ic_launcher" />
</LinearLayout>
</com.rzc.widget.MaxTwoLineTextLabelLayout>
</LinearLayout>