实现TextView可最多两行显示、右边控件紧跟TextView效果自定义布局

来源:互联网 发布:打击网络犯罪电话 编辑:程序博客网 时间:2024/05/22 13:14

此自定义布局实现的效果是:整个布局的最大宽度给定情况下,左边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>


阅读全文
0 0
原创粉丝点击