Частичный экран WebView с <видео> срезанным наполовину

У меня есть приложение для планшета с разделенным макетом - список слева и панель деталей справа. Правая панель представляет собой WebView и содержит тег <video>. То, что все работает нормально, за исключением всей правой части WebView, отключается и отображает белый цвет.

Почему это делается так, и как я могу избежать этого, не вставляя огромный хак?

Я отложил его до простого тестового проекта, который я опубликовал в github.

Вот снимок экрана: http://d.pr/i/dfEh.

Серая область слева - это вид списка. Я просто изменил его на пустой FrameLayout. Отрезанная часть по правой стороне WebView IS та же ширина, что и представление списка. Также стоит отметить, что любой контент ниже видео также отключен - белая область расширяет всю высоту WebView.

Некоторые вещи, которые я пробовал:

  • заменить вид списка другим.
  • включить и отключить WebSettings: javascript, использовать широкоэкранный режим, загрузить с режимом обзора
  • установите a WebViewClient и a WebChromeClient
  • включить и выключить аппаратное ускорение
  • различные настройки в View.setScrollBarStyle, WebView.setVerticalScrollBarOverlay и аналогичные
  • настроить атрибуты и стили <video> height/width
  • различные видеоформаты, включая mp4 с h264 и aac, m3u8, и поток youtube rtsp.
  • различные устройства, включая показанную Fire HD, Nexus 7, Galaxy 10.1 и Xoom
  • Android версии 3.1, 3.2, 4.0, 4.1

Текущее обходное решение:

В итоге я обошел это, используя полноэкранный WebView, наложив на него верхний вид списка и установив левое поле на внешний элемент контейнера в html. Это довольно хаки, и получение размера списка в разных размерах и разрешениях является подверженным ошибкам, поэтому я бы очень хотел, чтобы это было правильно.

Отрывки:

Как я уже упоминал, тестовый слой (не) работает на github, но вот важные бит:

Html загружается в WebView (это ВСЕ):

<html>
<head><title>Title</title></head>
<body style="margin:0">
    <video x-webkit-airplay="allow" controls="controls" style="width:100%">
        <source src="http://clips.vorwaerts-gmbh.de/VfE_html5.mp4"></source>
    </video>
</body>
</html>

Основной файл макета:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <fragment android:name="com.concentricsky.android.webviewvideotest.ListFragment"
        android:id="@+id/item_list"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1" />

    <!-- The WebView is attached here -->
    <FrameLayout android:id="@+id/detail_container"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="3" />

</LinearLayout>

В onCreateView:

    View rootView = inflater.inflate(R.layout.fragment_detail, container, false);
    webView = (WebView) rootView.findViewById(R.id.webview);
    webView.setWebChromeClient(new WebChromeClient());
    webView.loadUrl("file:///android_asset/test.html");
    return rootView;

Я действительно почесываю голову над этим, и я удивлен, что не смог найти упоминания об этом. Любой вход оценивается, как бы надуманный.

Ответ 1

Проблема, похоже, связана с слоем hardware/opengl. Поскольку VideoView использует аппаратный уровень для рендеринга видео, я считаю, что то же самое происходит с webView с видео.

Итак, если вы правильно настроили слои, они не должны мешать друг другу, так что, как я уже сказал в рекомендациях, вы должны установить ListView на слой none или программное обеспечение, чтобы отключить аппаратное ускорение и включить его в webView или окно.

Дополнительная информация об аппаратном ускорении на http://developer.android.com/guide/topics/graphics/hardware-accel.html#controlling

Ответ 2

У меня была такая же проблема, она должна была со мной использовать относительный макет. Слой, на который он передает видео, не перемещается с веб-просмотром. Таким образом, он будет отображать видео, как если бы веб-представление было расположено на 0,0.

Вы можете обойти это, фактически разместив webview на 0 0, за любыми компонентами, которые уже могут быть там. Затем в css дайте контенту запас, чтобы поместить его в нужное место.

Это может быть не чисто, но я не нашел другого решения.

РЕДАКТИРОВАТЬ: после более тщательного изучения вашего вопроса я думаю, что это не имеет никакого отношения к относительной компоновке, поскольку вы не используете ее. Тем не менее этот обходной путь работал на меня. Поэтому я предполагаю, что "Уровень видео" остается на уровне 0,0 независимо от того, какой формат вы используете. Кстати, я столкнулся с этой проблемой на Galaxy Tab 2 (android 4.0.3).

Ответ 3

У меня была такая же проблема в макете макета/подробного потока. Установив тип слоя для программного обеспечения, мое видео было сокращено наполовину проблем. Это отключает аппаратное ускорение для веб-просмотра.

webview.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

FYI Я испытал эту проблему только на планшетах Amazon.