为什么编辑 LayoutParams 大小没有 canvas 大小的效果
Why editing LayoutParams size doesn't have the effect of a canvas size
我正在处理扩展 SurfaceView 的幻灯片菜单视图,但是当我尝试更改视图大小时,canvas 没有改变。
出于调试目的,我正在更改视图调用方法的大小:
public void changeSize() {
width += 10;
getLayoutParams().width = width;
this.setLayoutParams(getLayoutParams());
}
然后在绘图函数中,我将 canvas 绘制为白色,并在视图对角线上绘制红线:
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);
}
}
我看到的是一个固定大小的白色矩形和部分红线:
demo.
此外,当我调用 this.getWidth()
时,我得到的宽度不变。
为什么视图大小没有改变? canvas 没有改变的原因是一样的吗?我能做些什么来修复它?
通过执行 getLayoutParams().width = width;
,您正在更改 View
的布局参数。但是你是在拥有 SurfaceHolder
的 Canvas
上进行绘图,而不是普通的 View
会提供给你的
。
因此,为了更改 SurfaceView
的大小,您必须与 SurfaceHolder
:
进行交互
surfaceView.getHolder().setFixedSize(width, height);
我为自己找到了理由。
我没有提到一些事情 - 我认为不重要 - 我通过其他线程调用 changeSize()
而不是创建视图,这是不允许的,因为:Only the original thread that created a view hierarchy can touch its views
。这个问题已经解决了很多次,例如here
我可以像这样在 changeSize()
中使用 Activity.runOnUiThread()
method but I did not want to pass the Activity
to the view so I use View.post() 方法:
Runnable changeParams = new Runnable() {
@Override
public void run() {
getLayoutParams().width = width;
setLayoutParams(getLayoutParams());
}
};
this.post(changeParams);
更新:
也许我不知道使用 UI 线程的正确方法,但无论我尝试过什么,我都无法顺利更改视图参数。
实现滑动菜单的一些解决方法:
- 做[Android导航抽屉][4]——你可以用限制来定制它,例如你不能让导航抽屉从顶部移动。
- 使用 [Android 动画][5] -- 使用它您可以移动或缩放视图但不能调整它的大小。
我的声誉链接不能超过 2 个:
(4): developer.android.com/training/implementing-navigation/nav-drawer.html
(5): developer.android.com/training/animation/index.html
我正在处理扩展 SurfaceView 的幻灯片菜单视图,但是当我尝试更改视图大小时,canvas 没有改变。
出于调试目的,我正在更改视图调用方法的大小:
public void changeSize() {
width += 10;
getLayoutParams().width = width;
this.setLayoutParams(getLayoutParams());
}
然后在绘图函数中,我将 canvas 绘制为白色,并在视图对角线上绘制红线:
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);
}
}
我看到的是一个固定大小的白色矩形和部分红线: demo.
此外,当我调用 this.getWidth()
时,我得到的宽度不变。
为什么视图大小没有改变? canvas 没有改变的原因是一样的吗?我能做些什么来修复它?
通过执行 getLayoutParams().width = width;
,您正在更改 View
的布局参数。但是你是在拥有 SurfaceHolder
的 Canvas
上进行绘图,而不是普通的 View
会提供给你的
因此,为了更改 SurfaceView
的大小,您必须与 SurfaceHolder
:
surfaceView.getHolder().setFixedSize(width, height);
我为自己找到了理由。
我没有提到一些事情 - 我认为不重要 - 我通过其他线程调用 changeSize()
而不是创建视图,这是不允许的,因为:Only the original thread that created a view hierarchy can touch its views
。这个问题已经解决了很多次,例如here
我可以像这样在 changeSize()
中使用 Activity.runOnUiThread()
method but I did not want to pass the Activity
to the view so I use View.post() 方法:
Runnable changeParams = new Runnable() {
@Override
public void run() {
getLayoutParams().width = width;
setLayoutParams(getLayoutParams());
}
};
this.post(changeParams);
更新:
也许我不知道使用 UI 线程的正确方法,但无论我尝试过什么,我都无法顺利更改视图参数。
实现滑动菜单的一些解决方法:
- 做[Android导航抽屉][4]——你可以用限制来定制它,例如你不能让导航抽屉从顶部移动。
- 使用 [Android 动画][5] -- 使用它您可以移动或缩放视图但不能调整它的大小。
我的声誉链接不能超过 2 个:
(4): developer.android.com/training/implementing-navigation/nav-drawer.html
(5): developer.android.com/training/animation/index.html