Android:多个TextView自动换行

2019-01-10  本文已影响0人  lv_mock

一个能够根据TextView长度自动换行的View(可能有bug)

代码

public class AutoChangeLineTextView extends ViewGroup implements View.OnClickListener {
    private String[] txt;
    private Context mContext;
    private int maxWidth, maxHeight;

    private final int tvPaddingLeftDp = 10;//dp
    private final int tvPaddingRightDp = 10;
    private final int tvPaddingTopDp = 3;
    private final int tvPaddingBottomDp = 3;
    private int tvPaddingLeftPx, tvPaddingRightPx, tvPaddingTopPx, tvPaddingBottomPx;
    private final int tvMarginLeftDp = 10;
    private final int tvMarginTopDp = 10;
    private int tvMarginLeftPx, tvMarginTopPx;
    private int tvColor ;
    private int tvBackgroundRes;
    private ItemClickCallBack itemClickCallBack;

    public AutoChangeLineTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
        TypedArray a = mContext.obtainStyledAttributes(attrs, R.styleable.AutoChangeLineTextView);
        tvColor = a.getColor(R.styleable.AutoChangeLineTextView_text_color,Color.parseColor("#999999"));
        tvBackgroundRes = a.getResourceId(R.styleable.AutoChangeLineTextView_text_background,R.drawable.shape_search_txt);//
        a.recycle();
        initValue();
    }

    private void initValue() {
        tvPaddingLeftPx = dp2px(tvPaddingLeftDp);
        tvPaddingRightPx = dp2px(tvPaddingRightDp);
        tvPaddingTopPx = dp2px(tvPaddingTopDp);
        tvPaddingBottomPx = dp2px(tvPaddingBottomDp);
        tvMarginLeftPx = dp2px(tvMarginLeftDp);
        tvMarginTopPx = dp2px(tvMarginTopDp);
    }

    public int dp2px(float dp) {
        final float scale = mContext.getResources().getDisplayMetrics().density;
        return (int) (dp * scale + 0.5f);
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        maxWidth = MeasureSpec.getSize(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        maxHeight = MeasureSpec.getSize(heightMeasureSpec);
        for (int k = 0; k < getChildCount(); k++) {
            View view = getChildAt(k);
            view.measure(view.getMeasuredWidth(), view.getHeight());
        }
        if (widthMode == MeasureSpec.AT_MOST && heightMode == MeasureSpec.EXACTLY) {
            getMaxWidthAndHeight();
            maxHeight = MeasureSpec.getSize(heightMeasureSpec);
        }
        if (widthMode == MeasureSpec.EXACTLY && heightMode == MeasureSpec.AT_MOST) {
            getMaxWidthAndHeight();
            maxWidth = MeasureSpec.getSize(widthMeasureSpec);
        }
        if (widthMode == MeasureSpec.AT_MOST && heightMode == MeasureSpec.AT_MOST) {
            getMaxWidthAndHeight();
        }
        setMeasuredDimension(maxWidth, maxHeight);

    }

    private void getMaxWidthAndHeight() {
        int lineWidth = -tvMarginLeftPx;//第一个没有marginLeft 一行的宽度
        int totalHeight = 0;//控件的实际高度
        int actualWidth = 0;//控件的实际宽度
        for (int k = 0; k < getChildCount(); k++) {
            View view = getChildAt(k);
            int width = view.getMeasuredWidth();
            int height = view.getMeasuredHeight();
            if (k == 0) {
                totalHeight += height;
            }
            lineWidth += width + tvMarginLeftPx;//一行的总宽度
            if (lineWidth > maxWidth) {//超过能设置对最大宽度
                if (lineWidth - width - tvMarginLeftPx > actualWidth) {
                    actualWidth = lineWidth - width - tvMarginLeftPx;
                }
                lineWidth = -tvMarginLeftPx + width;//第一个没有marginLeft
                totalHeight += tvMarginTopPx + height;
            } else {
                if (actualWidth < lineWidth) {
                    actualWidth = lineWidth;
                }
            }
        }
        maxWidth = actualWidth;
        maxHeight = totalHeight;
    }

    @Override
    protected void onLayout(boolean b, int i, int i1, int i2, int i3) {
        int currentX = 0, currentY = 0;
        for (int k = 0; k < getChildCount(); k++) {
            View view = getChildAt(k);
            int width = view.getMeasuredWidth();
            int height = view.getMeasuredHeight();
            if (currentX + width > maxWidth) {
                currentX = 0;
                currentY += tvMarginTopPx + height;
            }
            view.layout(currentX, currentY, currentX + width, currentY + height);
            currentX += width + tvMarginLeftPx;
        }
    }

    private void addTextView() {
        removeAllViews();
        for (int i = 0; i < txt.length; i++) {
            TextView textView = new TextView(mContext);
            textView.setText(txt[i]);
            textView.setTag(i);
            textView.setTextColor(tvColor);
            textView.setPadding(tvPaddingLeftPx, tvPaddingTopPx, tvPaddingRightPx, tvPaddingBottomPx);
            textView.setBackgroundResource(tvBackgroundRes);
            addView(textView);
            if (itemClickCallBack != null) {
                textView.setOnClickListener(this);
            }
        }
        requestLayout();
    }

    public void setTxt(String[] txt, ItemClickCallBack callBack) {
        this.txt = txt;
        itemClickCallBack = callBack;
        addTextView();
    }

    private int getRandomColor() {
        int r = (int) (Math.random() * 255);
        int g = (int) (Math.random() * 255);
        int b = (int) (Math.random() * 255);
        String colorStr = Integer.toHexString(r);
        if (colorStr.length() == 1) {
            colorStr = "0" + colorStr;
        }
        colorStr += Integer.toHexString(g);
        if (colorStr.length() == 3) {
            colorStr = "0" + colorStr;
        }
        colorStr += Integer.toHexString(b);
        if (colorStr.length() == 5) {
            colorStr = "0" + colorStr;
        }
        return Color.parseColor("#" + colorStr);
    }

    @Override
    public void onClick(View v) {
        if (itemClickCallBack != null) {
            itemClickCallBack.doClick((int) v.getTag());
        }
    }
}

调用示例

xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <com.zjp.customerview.view.AutoChangeLineTextView
        android:background="#f00"
        android:layout_marginLeft="15dp"
        android:layout_marginRight="15dp"
        android:id="@+id/auto_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
</LinearLayout>

activity

public class AutoLineTextViewActivity extends Activity{
    AutoChangeLineTextView autoChangeLineTextView;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.cus_acitivyt_auto_line_text_view);
        autoChangeLineTextView = findViewById(R.id.auto_view);
        String str = "咯哦哦too莫看看啊,咯哦哦too莫看看,来来来,可,too莫,咯哦哦我2261331渴了饿了,咯哦哦我2261331,咯哦哦我,咯哦哦,的,";
        final String[] txt =str.split(",");// new String[]{"aaa","bbddddddddddddddddddb","aaa","bbdddddddddddddddddddddddddddddb","aaa","bbdddddddddddddddddddddddddddddb"};
        autoChangeLineTextView.setTxt(txt, new ItemClickCallBack() {
            @Override
            public void doClick(int index) {
                Toast.makeText(AutoLineTextViewActivity.this,txt[index],Toast.LENGTH_LONG).show();
            }
        });
    }
}
上一篇下一篇

猜你喜欢

热点阅读