【问题标题】:Gridlayout with ColumnSpec causing layout to use full screen width带有 ColumnSpec 的 Gridlayout 导致布局使用全屏宽度
【发布时间】:2016-01-19 02:08:20
【问题描述】:

我正在使用带有两列的 GridLayout,对于其中的一行,我想插入一个分隔条。当我插入栏时,布局变为全屏宽度。没有栏,它的行为与我对 WRAP_CONTENT 的预期一样。

我动态创建布局及其所有内容,而不是使用 XML。以下是要点:

private class ContentView extends GridLayout 
{
    ContentView (Context context) 
    {
        super (context);
        setColumnCount (2);
    }

    // adds "child" to the next cell in the layout
    public void addView (View child, ViewGroup.LayoutParams params) 
    {
        super.addView (child, params);
        //... other code not shown ...
    }

    public void addDivider() 
    {
        int padding = (int) getResources().getDimension (R.dimen.normal_text_margin);
        GridLayout.LayoutParams params = new GridLayout.LayoutParams();
        params.width = LayoutParams.WRAP_CONTENT;
        params.height = (int) getResources().getDimension (R.dimen.divider_bar_height);
        params.columnSpec = GridLayout.spec (0,2); // add to pair of columns
        View v = new View (getContext());
        v.setBackgroundColor (Color.BLACK);
        v.setPadding (padding, 0, padding, 0);
        v.setLayoutParams (params);
        super.addView (v, params);
    }
}

这由以下调用,其中“v”是 GridLayout:

public View setContentView (ViewGroup v) 
{
    contentView = v;
    ViewGroup.LayoutParams params = new ViewGroup.LayoutParams (ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
    borderView.addView (contentView, params);
    return contentView;
}

如果我注释掉 addDivider 代码,布局会很窄。当我启用代码时,布局是全屏宽度。我需要设置什么不同的属性才能让栏不增加布局宽度?

【问题讨论】:

    标签: android android-gridlayout


    【解决方案1】:

    我没有找到使用 GridLayout 完成这项工作的方法(尽管我不得不承认我没有花时间检查源代码)。相反,我写了一些非常简单的东西来做我需要的事情。

    如果其他人发现此代码有用,就在这里。它允许多列和多行,其中每列的宽度由最宽成员的宽度定义。同样对于行高。我添加了一个用于插入行分隔符的 api(只允许一个分隔符,但您可以将其扩展为多个)。

    还缺少每个单元格的布局参数,因为我现在不需要它。它左对齐内容并将其垂直居中。还缺少单元格填充。就像我说的,一个简单的实现。但易于增强。

    public class SimpleGridLayout extends ViewGroup
    {
      private Paint barPaint;
    
      int cols = 0;
      int[] colWidths = null;
      int[] rowHeights = null;
      int dividerRow = -1; // only allow one divider row, keep implementation simple
      int dividerHeight = 0; // pixels
      int dividerMargin = 0; // pixels
      int yDivider = 0;
    
      //-----------------------------------------------------------------------------
      public SimpleGridLayout (Context context)
      {
        super (context);
        barPaint = new Paint(); // for painting insertion line
        dividerHeight = (int) getResources().getDimension(R.dimen.divider_bar_height);
        dividerMargin = (int) getResources().getDimension(R.dimen.divider_bar_margin);
        setWillNotDraw (false);
      }
    
      //-----------------------------------------------------------------------------
      @Override
      protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec)
      {
        // clear column widths, create height array
        for (int i = 0;  i < cols;  i++)
          colWidths[i] = 0;
        rowHeights = new int [(getChildCount() + cols - 1) / cols]; // account for partial row
    
        // determine column widths, working from left to right
        int widthAvailable = MeasureSpec.getSize (widthMeasureSpec);
        for (int iCol = 0; iCol < cols;  iCol++)
        {
          // visit each row
          for (int i = iCol, iRow = 0, limit = getChildCount();  i < limit;  i += cols, iRow++)
          {
            View child = getChildAt(i);
            int itemWidthSpec = MeasureSpec.makeMeasureSpec (widthAvailable, MeasureSpec.AT_MOST);
            int itemHeightSpec = MeasureSpec.makeMeasureSpec (0, MeasureSpec.UNSPECIFIED);
            child.measure (itemWidthSpec, itemHeightSpec);
    
            colWidths [iCol] = Math.max (colWidths [iCol], child.getMeasuredWidth());
            rowHeights [iRow] = Math.max (rowHeights [iRow], child.getMeasuredHeight());
          }
    
          widthAvailable -= colWidths [iCol];
        }
    
        // get total width
        int width = 0;
        for (int i = 0;  i < cols;  i++)
          width += colWidths [i];
    
        // get total height
        int height = 0;
        for (int i = 0;  i < rowHeights.length;  i++)
          height += rowHeights [i];
    
        if (dividerRow != -1)
          height += dividerHeight;
    
        setMeasuredDimension (width, height);
      }
    
      //-----------------------------------------------------------------------------
      @Override
      protected void onLayout (boolean changed, int l, int t, int r, int b)
      {
        // layout each column, working from left to right
        int xCol = 0;
        for (int iCol = 0; iCol < cols;  iCol++)
        {
          int yRow = 0;
    
          // visit each row
          for (int i = iCol, iRow = 0, limit = getChildCount();  i < limit;  i += cols, iRow++)
          {
            View child = getChildAt(i);
    
            if (iRow == dividerRow)
            {
              yDivider = yRow;
              yRow += dividerHeight;
            }
    
            // left justify
            int left = xCol;
    
            // center vertically
            int dyRow = rowHeights [iRow];
            int top = yRow + (dyRow - child.getMeasuredHeight()) / 2;
    
            int right = left + child.getMeasuredWidth();
            int bottom = top + child.getMeasuredHeight();
            child.layout (left, top, right, bottom);
    
            yRow += rowHeights [iRow];
          }
    
          xCol += colWidths [iCol];
        }
      }
    
      //-----------------------------------------------------------------------------
      @Override
      protected void onDraw (Canvas canvas)
      {
        barPaint.setColor (getResources().getColor (R.color.divider_bar));
        canvas.drawRect (dividerMargin,
                         yDivider,
                         getWidth() - 2*dividerMargin,
                         yDivider + dividerHeight,
                         barPaint);
      }
    
      //-----------------------------------------------------------------------------
      @Override
      public void addView (View v, LayoutParams params)
      {
        super.addView (v, params);
        rowHeights = null;
      }
    
      //-----------------------------------------------------------------------------
      public void addDivider ()
      {
        rowHeights = null;
        dividerRow = (getChildCount() + 1) / cols;
      }
    
      //-----------------------------------------------------------------------------
      public void setColumnCount (int cols)
      {
        this.cols = cols;
        colWidths = new int[cols];
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-09
      相关资源
      最近更新 更多