Question

I have method, which should create a Bitmap from the RelativeLayout. My RelativeLayout creates dynamically and place all input Views into the circle. It looks like this:

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));
                   }
          }
}

When I pass several views into my CircleView and setContentView of it, everything works fine. But I need also implement ability to rotate this CircleView. So I need to convert my RelativeLayout to the Bitmap. I do it like this:

  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;
}

as a result I've got my view, but it looks like ugly. So not every view displays and they are not in circle. So my guess is what measuring of the View acts not like it should to be. Maybe, I should to measure all the children? Or maybe call Bitmap convertion method in onPreDraw()? I've tried both of solutions but they didn't work for me.

Était-ce utile?

La solution

I solved this by

 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;
    } 

so DisplayMetrics solved my problem.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top