Вид обрезается выше ширины 10.000 пикселей

ОБНОВЛЕНИЕ: Работает на эмуляторе с Android Oreo (8.X). Кто-то знает, где они могли что-то изменить в источниках Android, которые решили эту проблему?

У меня есть SurfaceView внутри FrameLayout. 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 я попытался установить scaleX и scaleY для Framelayout, но в итоге получил те же результаты.

(кстати, максимальный размер текстуры opengl составляет около 16000 пикселей - установка его выше ~16000 пикселей приводит к черному экрану и исключению, так что это не является причиной проблемы)

Обновление: размещены все источники. В любом случае, вот полный проект андроид-студии: [удалено - если кто-то снова захочет получить исходники, я могу их загрузить заново]

0 ответов

Другие вопросы по тегам