所以我知道可以通过调用SurfaceHolder上的setFixedSize()来更改SurfaceView的表面大小,但是当我尝试在任意窗口上执行相同的操作时,从一个活动中获取,我不能。这是相关的测试代码:
public class TestActivity extends Activity implements Callback2 {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getWindow().takeSurface(this);
}
@Override
public void surfaceCreated(SurfaceHolder arg0) {
// TODO Auto-generated method stub
arg0.setFixedSize(300, 300);
}
}
这会导致以下错误日志:
01-15 23:21:46.111:E / AndroidRuntime(9748):致命异乎寻常:主
01-15 23:21:46.111:E / AndroidRuntime(9748):进程:com.example.windowtest,PID:9748
01-15 23:21:46.111:E / AndroidRuntime(9748):java.lang.UnsupportedOperationException:目前仅支持从布局调整大小
01-15 23:21:46.111:E / AndroidRuntime(9748):在android.view.ViewRootImpl $ TakenSurfaceHolder.setFixedSize(ViewRootImpl.java:6094)
在布局中,我认为它意味着WindowManager.LayoutParams,它也会调整Window的尺寸。那么在不改变Window的尺寸的情况下,是否无法改变Window Surface的大小?我认为有,因为我们可以使用SurfaceView,但我不确定如何。
先谢谢!
编辑:此外,SurfaceView setFixedSize()调用会生成requestLayout(),它会传播到实现ViewParent接口的对象。什么是在运行时附加到SurfaceView的ViewParent对象?也许那么表面缓冲区如何调整大小背后的逻辑将是明确的。
答案 0 :(得分:1)
实际上可以使用NDK的ANativeWindow_setBuffersGeometry:
JNIEXPORT void JNICALL Java_com_organization_app_TestActivity_setBufferGeometry(JNIEnv *env, jobject thiz, jobject surface, jint width, jint height)
{
__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "setBufferGeometry(): %p %dx%d", surface, width, height);
ANativeWindow* window = ANativeWindow_fromSurface(env, surface);
__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "setBufferGeometry(): window: %p", window);
ANativeWindow_setBuffersGeometry(window, width, height, AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM);
}
Java代码:
private static native void setBufferGeometry(Surface surface, int width , int height );
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{
Log.d( TAG, "surfaceChanged()...");
setBufferGeometry(holder.getSurface(), 768, 1366);
/* ... */
来自ANativeWindow_setBuffersGeometry文档:
更改窗口缓冲区的格式和大小。
宽度和高度控制缓冲区中的像素数,而不是 屏幕上窗口的尺寸。 如果这些与 窗口的物理尺寸,则其缓冲区将被缩放以匹配 将其合成到屏幕上时的大小。
答案 1 :(得分:0)
所有基于视图的UI都在单个图层上(a / k / a窗口)。您无法更改单个视图的曲面缩放比例;这没有意义。您必须更改整个View合成曲面的设置,框架并不想让您这样做。
SurfaceView的表面位于一个单独的图层上,独立合成,因此您可以更自由地更改其尺寸。