1

我有一个活动类,我想在主要内容之上显示一个带有半透明背景的小型动态内容,这类似于移动覆盖。为此,我使用 SurfaceView 后代。为简单起见,我尝试编写 POC 代码,因此我在表面视图中绘制了一条弧线并旋转它,并在计时器事件上稍微移动。问题是代码可以正常工作,只有在涉及旋转的情况下。当我添加一个移位(x,y)来改变表面视图位置时,它开始以黑色不透明矩形作为背景进行绘制。代码如下:

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

移动具有透明背景的表面视图的正确方法是什么?

4

0 回答 0