更新: 在Android Oreo(8.X)的Emulator上运行。我有可能直接对android源进行更改,因此,如果有人知道我必须更改或更新以使其正常工作的android源中的内容,这也将有所帮助(因此,我实际上并不需要Android 7解决方法。虽然无法更新至Android 8。)
我在FrameLayout中有一个SurfaceView。 SurfaceView通常会显示视频,例如,我实际上是在绘制图像。 问题是,如果我将FrameLayout(或SurfaceView)的尺寸设置为宽度大于10.000像素,则会在左侧裁剪。
在Android 7.1.1上进行了测试(在设备和仿真器上:Android TV(1080p)API 25
public class TestActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//add surfaceview
TestSurfaceView testSurfaceView = new TestSurfaceView(this);
setContentView(testSurfaceView);
//resize
FrameLayout.LayoutParams bgParams = (FrameLayout.LayoutParams) testSurfaceView.getLayoutParams();
//testcase full hd - working
bgParams.width = 1920;
//testcase 2 - working - each segment is 330px as 9900 / 1920 * 64 (default segment width) == 330
//bgParams.width = 9900;
//testcase 3 - working
//bgParams.width = 10000;
//testcase 4 - not working - each segment is 335px which is correct but first cell gets cropped by exactly 50px to the left
//bgParams.width = 10050;
bgParams.height = (int)Math.floor(bgParams.width * (9d/16d)); //16:9
testSurfaceView.setX(0); //doesnt help
/*
Also the position counts into the 10000px limitation as you can see on following testcases
*/
/*
bgParams.width = 9900;
bgParams.height = (int)Math.floor(bgParams.width * (9d/16d)); //16:9
//works - as 9900 + 90 < 10000
testSurfaceView.setX(90);
//doesnt work, crops 50px to the left - 9900 + 150 -> 10050
testSurfaceView.setX(150);
*/
}
}
public class TestSurfaceView extends SurfaceView implements SurfaceHolder.Callback
{
public TestSurfaceView(TestActivity context) {
super(context);
SurfaceHolder holder = this.getHolder();
holder.addCallback(this);
}
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder)
{
//load bitmap from file
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bitmap = BitmapFactory.decodeFile(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath() + "/testimg.png", options);
Canvas c = surfaceHolder.lockCanvas();
Rect rect = new Rect();
rect.set(0,0, 1920, 1080); //image size
Rect destRect = new Rect();
destRect.set(0, 0, this.getWidth(), this.getHeight());
//draw the image on the surface
c.drawBitmap(bitmap, rect, destRect, null);
surfaceHolder.unlockCanvasAndPost(c);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
}
styles.xml-主题
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="android:Theme.Material.Light.NoActionBar.Fullscreen">
<!-- Customize your theme here. -->
</style>
</resources>
上面的代码会产生以下输出,这是正确的。
如果我将bgParams.width
更改为9600-它会正确放大,并且仍然从图像的左边缘开始显示:
但是如果我将代码更改为10050,图像向左裁剪50个像素。
如果我设置了
destRect.set(50, 0, this.getWidth(), this.getHeight());
它可以正确显示,但是由于MediaPlayer无法做到这一点,而且它非常怪异,因此我试图找到一个好的解决方案。
我还尝试直接在SurfaceView上设置尺寸,而不是更改LayoutParams,而是尝试设置Framelayout的scaleX和scaleY,但最终得到了相同的结果。
(请注意,opengl的最大纹理大小约为16000px-将其设置为〜16000px以上会导致黑屏和异常,因此不是问题的原因)
更新: 发表所有来源。无论如何,这是完整的android studio项目: WeTransfer project download link