Search code examples
androidcanvaslayoutparams

Why editing LayoutParams size doesn't have the effect of a canvas size


I am working on slide menu view which extends SurfaceView but when I try to change size of the view a canvas does not change.

For debug purpose, I am changing size of the view calling method:

public void changeSize() {
    width += 10;
    getLayoutParams().width = width;
    this.setLayoutParams(getLayoutParams());
}

Then in a draw function I paint the canvas white and draw red line diagonally across the view:

public void draw() throws Exception {
  SurfaceHolder surfaceHolder = getHolder();
  if (surfaceHolder.getSurface().isValid()) {
    Canvas canvas = surfaceHolder.lockCanvas();
    Log.i(TAG, "draw > canvas size: " + canvas.getWidth() + " " + canvas.getHeight() );
    paint.setColor(Color.rgb(255,0,0));
    paint.setStrokeWidth(5);
    canvas.drawColor(Color.rgb(255, 255, 255));
    canvas.drawLine(0, getLayoutParams().height, getLayoutParams().width, 0, paint);

    surfaceHolder.unlockCanvasAndPost(canvas);
  }
}

What I see is a white rectangle with fixed size and part of red line: demo.

Also, when I call this.getWidth() I get unchanged width. Why view size is not changing? Is it the same reason that the canvas is not changing? What can I do to fix it?


Solution

  • I found reason for myself.

    I did not mention about something - that I thought was not important - I called changeSize() via other thread than created the view and this is not allowed because: Only the original thread that created a view hierarchy can touch its views. And this problem was many time solved, e.g. here

    I could use Activity.runOnUiThread() method but I did not want to pass the Activity to the view so I use View.post() method in the changeSize() like this:

    Runnable changeParams = new Runnable() {
      @Override
      public void run() {
        getLayoutParams().width = width;
        setLayoutParams(getLayoutParams());
      }
    };
    this.post(changeParams);
    

    Update:

    Maybe I do not know about proper way of using the UI Thread but whatever I tried I can not change view parameters smoothly.

    Some workarounds to implement a slide menu:

    1. Do [Android navigation Drawer][4] -- you can custiomize it with restictions e.g. you can not do the navigation drawer moving from top.
    2. Use [Android animations][5] -- with it you can move or scale a view but can not resizing it.

    I can not put more than 2 links with my reputation:

    (4): developer.android.com/training/implementing-navigation/nav-drawer.html

    (5): developer.android.com/training/animation/index.html