`

用ViewGroup实现多View自动换行的功能

 
阅读更多
public class PredicateLayout extends ViewGroup {
    private int line_height;
    public static final int DEFAULT_HORIZONTAL_SPACING = 5;
    public static final int DEFAULT_VERTICAL_SPACING = 5;

    private int horizontalSpacing;
    private int verticalSpacing;

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

    public PredicateLayout(Context context, int horizontalSpacing, int verticalSpacing) {
        super(context);
        this.horizontalSpacing = horizontalSpacing;
        this.verticalSpacing = verticalSpacing;
    }

    public PredicateLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        //TypedArray styledAttributes = context.obtainStyledAttributes(attrs, R.styleable.PredicateLayout);
        //horizontalSpacing = styledAttributes.getDimensionPixelSize(R.styleable.PredicateLayout_item_h_space, DEFAULT_HORIZONTAL_SPACING);
        //verticalSpacing = styledAttributes.getDimensionPixelSize(R.styleable.PredicateLayout_item_v_space, DEFAULT_VERTICAL_SPACING);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        assert (MeasureSpec.getMode(widthMeasureSpec) != MeasureSpec.UNSPECIFIED);

        final int width = MeasureSpec.getSize(widthMeasureSpec) - getPaddingLeft() - getPaddingRight();
        int height = MeasureSpec.getSize(heightMeasureSpec) - getPaddingTop() - getPaddingBottom();
        final int count = getChildCount();
        int line_height = 0;
        // int line_height = 22;

        int xpos = getPaddingLeft();
        int ypos = getPaddingTop();

        for (int i = 0; i < count; i++) {
            final View child = getChildAt(i);
            if (child.getVisibility() != GONE) {
                child.measure(MeasureSpec.makeMeasureSpec(LayoutParams.WRAP_CONTENT, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(LayoutParams.WRAP_CONTENT, MeasureSpec.UNSPECIFIED));

                final int childw = child.getMeasuredWidth();
                line_height = Math.max(line_height, child.getMeasuredHeight() + verticalSpacing);

                if (xpos + childw > width) {
                    xpos = getPaddingLeft();
                    ypos += line_height;
                }

                xpos += childw + horizontalSpacing;
            }
        }
        this.line_height = line_height;

        if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.UNSPECIFIED) {
            height = ypos + line_height;

        } else if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST) {
            if (ypos + line_height < height) {
                height = ypos + line_height;
            }
        }
        setMeasuredDimension(width, height);
    }

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

    @Override
    protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
        return p instanceof LayoutParams;
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        final int count = getChildCount();
        final int width = r - l;
        int xpos = getPaddingLeft();
        int ypos = getPaddingTop();

        for (int i = 0; i < count; i++) {
            final View child = getChildAt(i);
            if (child.getVisibility() != GONE) {
                final int childw = child.getMeasuredWidth();
                final int childh = child.getMeasuredHeight();
                // final int childh = 24;
                if (xpos + childw > width) {
                    xpos = getPaddingLeft();
                    ypos += line_height;
                }
                child.layout(xpos, ypos, xpos + childw, ypos + childh);
                xpos += childw + horizontalSpacing;
            }
        }
    }

}

 

分享到:
评论

相关推荐

    多个view自动换行

    为了实现“多个view自动换行”,我们可以考虑使用`GridLayout`或者自定义布局。`GridLayout`允许每个子视图占据固定大小的网格,并会自动换行以填充整个容器。然而,`GridLayout`在处理不同大小的视图时可能会显得...

    Android 实现View的排列自动换行

    本示例“Android实现View的排列自动换行”着重讲解如何在自定义View中实现视图元素的自动布局,即当一行无法容纳所有视图时,自动将超出的视图换行到下一行,并保持适当的间距。 首先,我们需要创建一个新的...

    AndroidAutoLayout自动换行viewgroup

    然后在布局XML文件中声明并使用这个自定义ViewGroup,通过设置子View和选择模式,即可实现自动换行和选择功能。 总之,"AndroidAutoLayout"是一个强大且灵活的组件,它解决了Android开发中多元素自动布局的问题,...

    多标签自动换行的控件ViewGroup

    总的来说,创建一个多标签自动换行的`ViewGroup`需要理解Android布局系统的底层工作原理,以及如何通过自定义`ViewGroup`来实现特定的布局需求。通过这样的实践,开发者可以更灵活地控制界面的布局,以适应各种屏幕...

    Android自定义标签view——可自动换行

    通过深入研究这个项目,开发者不仅可以学习到自定义View和布局管理的相关知识,还能掌握如何实现自动换行的功能,这对于优化Android应用的界面布局和提高用户体验具有很大的价值。同时,从开源社区获取和贡献代码也...

    Android自动换行标签控件(二)

    在这个案例中,我们将自定义一个`ViewGroup`子类,比如命名为`AutoWrapTagLayout`,来实现自动换行的功能。 实现这个功能的关键在于计算每个标签的宽度,并根据屏幕宽度动态调整它们的布局。我们需要覆写`onMeasure...

    listView实现文字编辑的自动换行

    要实现ListView中的文字编辑自动换行,我们需要结合EditText控件和自定义Adapter来完成这一功能。以下将详细阐述如何实现这一需求。 首先,我们创建一个布局文件,用于定义ListView中每一项的视图。在这个布局中,...

    android自定义控件自动换行效果实现 简化版demo

    在自定义自动换行的效果时,我们通常会创建一个自定义的ViewGroup来实现这一功能。 在创建自定义控件时,我们首先需要继承ViewGroup,并重写其关键方法。例如,`onMeasure()`方法用于测量每个子View的大小,`...

    解决自动换行,自适应高度。常见与标签样式的 ViewGroup

    当我们在设计用户界面时,有时需要创建一个标签样式(Tag-style)的ViewGroup,这种组件通常包含多个标签,它们需要自动换行以适应有限的屏幕宽度,并且整个组件能自适应高度,以显示所有标签而不被截断。"解决自动...

    android 实现自动换行的流布局

    以上代码实现了基本的FlowViewGroup功能,包括自动换行和对padding、margin的支持。为了更好地适应各种场景,还可以添加以下特性: - **垂直对齐**:在每行内支持顶部对齐、底部对齐或居中对齐。 - **动态调整列数*...

    android商品属性选择标签控件,可实现自动换行

    这里我们将详细探讨如何实现一个支持自动换行、默认选中首个标签,并且能够进行多选的标签控件。 首先,我们来看"标签选择"这个概念。标签(Tag)是一种常用的数据展示方式,通常用于表示某个对象或内容的特性。在...

    Android自动换行控件,邮件收件人

    在Android开发中,创建自定义ViewGroup以实现自动换行的功能是一个常见的需求,尤其是在构建复杂的用户界面时。这个场景特别适用于邮件应用中的收件人输入框,用户可以连续添加多个收件人,而这些收件人的显示需要...

    Android自定义组件之自动换行View

    本篇文章将深入探讨如何实现一个自动换行的View,这种组件通常用于显示一行排满后自动换行的文本或小图标。在Android应用设计中,这样的组件能够提供更灵活的布局和更丰富的用户体验。 首先,我们需要创建一个新的...

    android自定义控件自动换行效果实现

    本教程将探讨如何实现一个自定义控件,它具有自动换行的效果,使得在有限的屏幕空间内,元素能够整齐地排列成多行。参考链接为:。 首先,我们需要创建一个新的`ViewGroup`子类,例如`AutoWrapLayout`。这个自定义...

    Android 自定义控件实现自动换行效果

    本示例将探讨如何创建一个自定义的ViewGroup来实现商品属性显示时的自动换行效果,类似于常见于电商应用的商品详情页。这个过程涉及到布局管理、事件处理以及自定义View的基本原理。 首先,我们需要理解Android中的...

    android 自动换行

    `AutoLineLayoutManager`将接管ViewGroup的布局过程,通过计算每个子View的尺寸和位置,确保它们在达到边界时自动换行。这样的类可能需要重写`onLayout()`方法,以实现自定义的换行逻辑。 这三种自定义类提供了不同...

    Android 控件可以根据长度自动换行

    6. **DeseListView**: 这可能是项目中自定义的ListView库或者类,具体实现可能包含了更多的优化或功能,比如更好的自动换行逻辑,或者是对长列表的优化处理。需要查看源代码或文档来了解其详细功能。 7. **性能优化...

    子控件排列自动换行

    "子控件排列自动换行"这个主题涉及到如何构建一个自定义的ViewGroup,使得其内部的子控件能够根据空间自动进行换行排列,类似于搜索引擎下方的关键字展示。这样的布局可以有效地利用屏幕空间,提供良好的用户体验。...

    一行代码搞定标签换行,自定义ViewGroup

    在Android开发中,有时我们需要创建一个布局,其中包含多个可点击的标签,并且这些标签能够自动换行以适应屏幕宽度。这就是"标签换行"的需求。`FlowLayout`是一种自定义的`ViewGroup`,它允许子视图(标签)根据需要...

Global site tag (gtag.js) - Google Analytics