Android 自动换行的布局 AutoNextLineLinearLayout 实现标签墙排列

Android 自动换行的布局 AutoNextLineLinearLayout 实现标签墙排列很多人会遇到满行就自动换到下一行的界面需求, 而Android自带的LinearLayout布局自能横排或者竖排,不够显示就加ScrollView,横竖混排就不行了。

前言

最近公司项目有个标签集功能 用户通过标签筛选 生成一系列操作 实现漏斗筛选 并最终推荐药品

废话不多说 看下是不是想要的效果

实现效果

1

实现代码 AutoNextLineLinearLayout

很多人会遇到满行就自动换到下一行的界面需求, 而Android自带的LinearLayout布局自能横排或者竖排,不够显示就加ScrollView,横竖混排就不行了。

/**
 * 自动换行的LinearLayout
 */
public class AutoNextLineLinearLayout extends LinearLayout {

    int mLeft, mRight, mTop, mBottom;
    Hashtable map = new Hashtable();

    public AutoNextLineLinearLayout(Context context) {
        super(context);
    }

    public AutoNextLineLinearLayout(Context context, int horizontalSpacing, int verticalSpacing) {
        super(context);
    }

    public AutoNextLineLinearLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        int mWidth = MeasureSpec.getSize(widthMeasureSpec);
        int mCount = getChildCount();
        int mX = 0;
        int mY = 0;
        mLeft = 0;
        mRight = 0;
        mTop = 5;
        mBottom = 0;

        int j = 0;

        for (int i = 0; i < mCount; i++) {
            final View child = getChildAt(i);
            LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) child.getLayoutParams();
            child.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
            // 此处增加onlayout中的换行判断,用于计算所需的高度
            int childw = child.getMeasuredWidth()+params.leftMargin + params.rightMargin;
            int childh = child.getMeasuredHeight();
            mX += childw; // 将每次子控件宽度进行统计叠加,如果大于设定的高度则需要换行,高度即Top坐标也需重新设置

            Position position = new Position();
            mLeft = getPosition(i - j, i);
            mRight = mLeft + child.getMeasuredWidth();
            if (mX >= mWidth) {
                mX = childw;
                mY += childh;
                j = i;
                mLeft = 0;
                mRight = mLeft + child.getMeasuredWidth();
                mTop = mY + params.topMargin;
            // PS:如果发现高度还是有问题就得自己再细调了
            }
            mBottom = mTop + child.getMeasuredHeight()+params.bottomMargin;
            mY = mTop; // 每次的高度必须记录 否则控件会叠加到一起
            position.left = mLeft;
            position.top = mTop + 3;
            position.right = mRight;
            position.bottom = mBottom;
            map.put(child, position);
        }
        setMeasuredDimension(mWidth, mBottom);
    }

    @Override
    protected LayoutParams generateDefaultLayoutParams() {
        return new LayoutParams(0, 0); // default of 1px spacing
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {

        int count = getChildCount();
        for (int i = 0; i < count; i++) {
            View child = getChildAt(i);
            Position pos = (Position) map.get(child);
            if (pos != null) {
                child.layout(pos.left, pos.top, pos.right, pos.bottom);
            } else {
                Log.i("MyLayout", "error");
            }
        }
    }

    private static class Position {
        int left, top, right, bottom;
    }

    public int getPosition(int IndexInRow, int childIndex) {
        if (IndexInRow > 0) {
            return getPosition(IndexInRow - 1, childIndex - 1) + getChildAt(childIndex - 1).getMeasuredWidth()+30;
        }
        return getPaddingLeft();
    }
}

在布局中使用 和普通布局一样

 <com.jk.house.shopping_main.view.AutoNextLineLinearLayout
                android:id="@+id/tagLayout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginLeft="30dp"
                android:layout_marginTop="10dp"
                android:layout_marginRight="30dp"
                android:orientation="horizontal"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/tv_tips" />

实体类中运用

//往AutoNextLineLinearLayout容器里添加数据
tagLayout.removeAllViews();
        for (int i = 0; i < detailsSymptomList.size(); i++) {
            DetailsSymptomBean detailsSymptomBean = detailsSymptomList.get(i);
            if (detailsSymptomBean.getDepartname().equals(type)) {
                for (String taboo : detailsSymptomBean.getTaboo()) {
                    TextView textView = new TextView(getActivity());
                    textView.setText(taboo);
                    textView.setBackgroundResource(R.drawable.selector_checkbox_bg_add_personal_info);
                    AutoNextLineLinearLayout.LayoutParams params = new AutoNextLineLinearLayout
                            .LayoutParams(AutoNextLineLinearLayout.LayoutParams.WRAP_CONTENT, 
                            AutoNextLineLinearLayout.LayoutParams.WRAP_CONTENT);
					//通过这个属性可以控制 排列方式
                    params.setMargins(20, 20, 0, 0);
                    textView.setLayoutParams(params);
                    //通过这个属性可以控制 排列方式
                    textView.setPadding(40, 20, 40, 20);
                    textView.setTextColor(getActivity().getResources().
                    getColorStateList(R.drawable.selector_checkbox_text_color_add_personal_info));
                    textView.setTextSize(30);
                    textView.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            if (view.isSelected()) {
                                view.setSelected(false);
                                tabooList.remove(((TextView) view).getText().toString());
                            } else {
                                view.setSelected(true);
                                tabooList.add(((TextView) view).getText().toString());
                            }
                        }
                    });
                    tagLayout.addView(textView);
                }
            }
        }

总结

在使用中 可能遇到标签排列问题 我尝试改变间距和padding 来控制标签的显示问题

//这个是控制单个标签在 布局中的位置
params.setMargins(20, 20, 0, 0);
//这个是标签内容在TextView中的排列
textView.setPadding(40, 20, 40, 20);

每个人项目要求 可能不一样 所以我们要灵活的感觉 内容来排列 来达到一个满意效果

最后 2021 请再努力一点 继续加油~

今天的文章Android 自动换行的布局 AutoNextLineLinearLayout 实现标签墙排列分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/20503.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注