首页 > 解决方案 > 自定义视图应该如何处理最大宽度?

问题描述

假设我想构建一个这样的工具栏: https ://i.stack.imgur.com/a15lj.png

因此,工具栏有一个最大宽度,我想将项目(搜索、复制等)添加到工具栏,直到它达到最大宽度。

挑战在于,如果不实际膨胀它们,我不会知道这些“项目”的尺寸。

最好的方法是什么?下面的计划听起来好吗?

ViewGroup toolbar;
int remaining_width = max_width;
for item in items:
    view = inflate(item);
    view.measure()
    remaining_width -= view.getMeasuredWidth();
    if (remaining_width < 0) {
         break;
     } 
     toolbar.addView(view);        
}

谢谢。

标签: androidandroid-view

解决方案


您可以通过编程方式或使用 xml 布局创建工具栏视图组。如果您以编程方式执行此操作,那么在您的自定义视图组中,您可以覆盖 onMeasure() 并可以测量视图组子视图,然后在 onLayout 中,您可以根据测量的宽度布局子视图。

public class Toolbar extends ViewGroup{

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        final int width = MeasureSpec.getSize(widthMeasureSpec); 
        final int height = MeasureSpec.getSize(heightMeasureSpec);

        // measure child views here
        setMeasuredDimension(width, height);
    }


     @Override   
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        // layout your child views here
        View child = getChildAt(0);
        child.layout(0, 0, child.getMeasuredWidth, child.getMeasuredHeight());
    }
}

如果您希望坚持使用 xml 布局,则可以使用 OnGlobalLayoutListener()。

ViewGroup toolbar = findViewById();
toolbar.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        //Layout is now complete so dimens of toolbar and its child views are available 
       int toolbarW = toolbar.getWidth();
       int toolbarH = toolbar.getHeight();
       // you can add fixed child views in xml and if space is available add optional child views programmatically
       // listener will be called multiple times so do null check before adding views
    }
}

推荐阅读