在绘制之前测量RelativeView的所有子视图

时间:2013-05-21 10:03:54

标签: android android-layout bitmap relativelayout measure

我有方法,应该从RelativeLayout创建一个Bitmap。我的RelativeLayout动态创建并将所有输入视图放入圆圈。它看起来像这样:

public class CircleView extends RelativeLayout {
static final int centerId = 111;
private final int radius;
Bitmap returnedBitmap;
private RelativeLayout.LayoutParams createNewRelativeLayoutParams() {
          RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
                             RelativeLayout.LayoutParams.WRAP_CONTENT,
                             RelativeLayout.LayoutParams.WRAP_CONTENT);
          lp.addRule(RelativeLayout.ABOVE, centerId);
          lp.addRule(RIGHT_OF, centerId);
          return lp;
}

private View prepareElementForCircle(View elem, int distX, int distY) {
          RelativeLayout.LayoutParams lp = createNewRelativeLayoutParams();

          elem.measure(0, 0);
          int deltaX = elem.getMeasuredWidth() / 2;
          int deltaY = elem.getMeasuredHeight() / 2;
          lp.setMargins(distX - deltaX, 0, 0, radius - distY - deltaY);
          elem.setLayoutParams(lp);
          return elem;
}

public CircleView(Context context, int radius, View[] elements) {
          super(context);
          this.radius = radius;

          RelativeLayout.LayoutParams lpView = new RelativeLayout.LayoutParams(
                             RelativeLayout.LayoutParams.FILL_PARENT,
                             RelativeLayout.LayoutParams.FILL_PARENT);
          this.setLayoutParams(lpView);

          View center = new View(context);
          center.setId(centerId);
          RelativeLayout.LayoutParams lpcenter = new RelativeLayout.LayoutParams(
                             0, 0);
          lpcenter.addRule(CENTER_HORIZONTAL);
          lpcenter.addRule(CENTER_VERTICAL);
          center.setLayoutParams(lpcenter);
          this.addView(center);

          this.addView(prepareElementForCircle(elements[0], 0, 0));
          if (elements.length % 2 == 0) {
                   this.addView(prepareElementForCircle(elements[elements.length / 2],
                                      0, 2 * radius));
          }
          if (elements.length > 2) {
                   for (int i = 1; i <= (elements.length - 1) / 2; i++) {
                             int y = i * 4 * radius / elements.length;
                             int x = (int) Math.sqrt(Math.pow(radius, 2)
                                               - Math.pow((radius - y), 2));
                             this.addView(prepareElementForCircle(elements[i], x, y));
                             this.addView(prepareElementForCircle(elements[elements.length
                                               - i], -x, y));
                   }
          }
}

当我将几个视图传递到我的CircleView和setContentView时,一切正常。但我还需要实现旋转此CircleView的能力。所以我需要将RelativeLayout转换为Bitmap。我是这样做的:

  public  Bitmap getBitmapFromView() {

    this.measure(MeasureSpec.makeMeasureSpec(createNewRelativeLayoutParams().width, MeasureSpec.UNSPECIFIED),
            MeasureSpec.makeMeasureSpec(createNewRelativeLayoutParams().height, MeasureSpec.UNSPECIFIED));
    this.layout(0, 0, this.getMeasuredWidth(), this.getMeasuredHeight());
    this.setGravity(Gravity.CENTER);
    Bitmap returnedBitmap = Bitmap.createBitmap(this.getMeasuredWidth(), this.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
    Canvas c = new Canvas(returnedBitmap);
    this.draw(c);
    return returnedBitmap;
}

因此我得到了我的观点,但它看起来很难看。因此,并非每个视图都显示,并且它们不在圆圈中。所以我的猜测是衡量View的行为不应该是它应该是的。也许,我应该衡量所有的孩子?或者可以在onPreDraw()中调用Bitmap转换方法?我尝试了两种解决方案,但它们对我不起作用。

1 个答案:

答案 0 :(得分:1)

我通过

解决了这个问题
 public  Bitmap getBitmapFromView() {
        DisplayMetrics dm = context.getApplicationContext().getResources().getDisplayMetrics(); 
        this.measure(MeasureSpec.makeMeasureSpec(dm.widthPixels, MeasureSpec.EXACTLY),
                MeasureSpec.makeMeasureSpec(dm.heightPixels, MeasureSpec.EXACTLY));
        this.layout(0, 0, this.getMeasuredWidth(), this.getMeasuredHeight());
        this.setGravity(Gravity.CENTER);
        Bitmap returnedBitmap = Bitmap.createBitmap(this.getMeasuredWidth(),
                this.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(returnedBitmap);
        this.draw(c);
        return returnedBitmap;
    } 

所以DisplayMetrics解决了我的问题。