1

I have an activity class, which I want to show a small dynamic content with translucent background on top of a main content, that is something like a moving overlay. I use a SurfaceView descendant for this purpose. For the simplicity I'm trying to code a POC, so I draw an arc in the surface view and rotate it, and move slightly on timer events. The problem is that the code works ok, only if rotation is involved. When I add a shift by (x, y) to change the surface view position, it begins to draw with black opaque rectangle as background. The code is presented below:

public class AndroidActivity extends Activity
{
  private RelativeLayout layout;
  private OverlayView mOverlay;
  private Handler mHandler = new Handler();
  private Timer timer = new Timer();
  private SurfaceHolder surfaceHolder;
  private int degrees = 0;
  private int x = 100;
  private int y = 200;

  @Override
  protected void onCreate(Bundle b)
  {
    super.onCreate(b);
    setContentView(R.layout.main_view); // inflate main view
    layout = (RelativeLayout) findViewById(R.id.mainview); // get parent layout
    mOverlay = new OverlayView(this);   // create the surface view descendant
    // prepare layout parameters for the surface view
    RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(50, 50);
    params.leftMargin = x;
    params.topMargin = y;
    mOverlay.setLayoutParams(params); // apply parameters
    // next 2 lines ensure transparent background mode
    mOverlay.setZOrderOnTop(true);
    mOverlay.getHolder().setFormat(PixelFormat.TRANSLUCENT);
    // add the surface view into the parent layout
    layout.addView(mOverlay);
    // lets start dynamic motion
    timer.schedule(new DebugTimerTask(), 500, 500);
  }


  private class OverlayView extends SurfaceView implements SurfaceHolder.Callback
  {
    private Paint mPaint = new Paint();

    public OverlayView(Context context)
    {
      super(context);
      surfaceHolder = getHolder();
      surfaceHolder.addCallback(this);
    }

    protected void doDraw(Canvas canvas)
    {
      mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
      mPaint.setStrokeWidth(1);
      // will draw semitransparent yellow arc
      mPaint.setColor(Color.YELLOW);
      mPaint.setAlpha(128);
      RectF oval = new RectF(0, 0, +50, +50);
      canvas.drawColor(0, android.graphics.PorterDuff.Mode.CLEAR);
      canvas.drawArc(oval, degrees, 90, true, mPaint);
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
    int height)
    {
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder)
    {
      setZOrderOnTop(true);
      holder.setFormat(PixelFormat.TRANSLUCENT);
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder)
    {
    }
  }

  private class DebugTimerTask extends TimerTask
  {
    public void run()
    {
      mHandler.post(new Runnable()
      {
        @Override
        public void run()
        {
          degrees += 10; // rotate a bit
          x += 1;        // move a bit
          y += 2;

          Canvas canvas = null;

          // if next lines are commented, code works almost perfectly:
          // rotation of semitransparent arc over content beneath,
          // but I need to move the overlay, so
          // if they are not commented, the overlay's background becomes black

          // variant A: doesn't work
          //RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(50, 50);
          //params.leftMargin = x;
          //params.topMargin = y;
          //mOverlay.setLayoutParams(params);

          // variant B: doesn't work
          //mOverlay.layout(x, y, x + 50, y + 50);

          try
          {
            synchronized(surfaceHolder)
            {
              canvas = surfaceHolder.lockCanvas(null);
              if(canvas != null)
              {
                mOverlay.doDraw(canvas);
              }
            }
          }
          finally
          {
            if(canvas != null)
            {
              surfaceHolder.unlockCanvasAndPost(canvas);
            }
          }
        }
      });
    }
  }
}

What is a proper way to move a surface view with transparent background?

Stan
  • 8,683
  • 9
  • 58
  • 102

0 Answers0