使用ColumnSpec的Gridlayout导致布局使用全屏宽度

时间:2016-01-17 21:21:58

标签: android android-gridlayout

我正在使用带有两列的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代码,则布局很窄。当我启用代码时,布局是全屏宽度。我需要设置哪些属性才能使条形图不会增加布局宽度?

1 个答案:

答案 0 :(得分:0)

我没有找到使用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];
  }
}