I have a tablet application with a split layout – a list on the left, and a detail pane on the right. The right-hand pane is a WebView, and it contains a
<video> tag. That’s all working fine, except the entire right-hand side of the WebView is cut off and renders plain white.
Why is it rendering this way, and how can I avoid it without inserting a huge hack?
I have boiled it down to a simple test project, which I’ve posted on github.
Here is a screenshot: http://d.pr/i/dfEh.
The grey area along the left is where the list view belongs. I have changed it to an empty
FrameLayout for simplicity. The cut off portion along the right side of the WebView IS the same width as the list view. It’s also worth noting that any content below the video is also cut off–the white area extends the full height of the WebView.
Some things I’ve tried:
- replace the list view with something else
- enable and disable
- set a
- turn hardware acceleration on and off
- various settings in
WebView.setVerticalScrollBarOverlay, and similar
- tweak the
<video>‘s height/width attributes and styles
- various video formats, including mp4 with h264 and aac, m3u8, and a youtube rtsp stream
- various devices, including the Fire HD shown, a Nexus 7, a Galaxy 10.1, and a Xoom
- Android versions 3.1, 3.2, 4.0, 4.1
I ended up working around this by using a full-screen WebView, overlaying my list view on top of it, and setting a left margin on the outermost container element in the html. This is rather hacky, and getting the size of the list view on various densities and resolutions is error-prone, so I would really like to solve this the right way.
As I mentioned, a (non-) working test bed is posted on github, but here are the important bits:
Html loaded into the WebView (this is ALL of it):
<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>
The main layout file:
<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>
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;
I am really scratching my head over this one, and I’m surprised I haven’t been able to find any mention of it. Any input is appreciated, however far-fetched.
The problem seems to be with the hardware/opengl layer. Since the VideoView uses an hardware layer to render the video I believe that the same happens with the webView with a video.
So if you set the layers right, they shouldn’t interfere with each other, so like I said on the coments, you should set the ListView to layer none or software, to disable the hardware acceleration and enable it on the webView or the window.
More info about the hardware acceleration at http://developer.android.com/guide/topics/graphics/hardware-accel.html#controlling
I had the same problem, it had to with me using a relative layout. The layer it renders the video to, does not move with the webview. So it will render the video as if the webview was positioned at 0,0.
You can work around this by actually position the webview at 0 0, behind any components that may already be there. Then in css give the content a margin to position it on the correct spot.
It may not be clean, but I haven’t found another solution.
EDIT: After taking a better look at your question I think it doesn’t have anything to do with the relative layout as you’re not using one. Nevertheless this workaround worked for me. So I guess the ‘Video layer’ stays at 0,0 no matter what layout you’re using. I only came across this problem on a Galaxy Tab 2(android 4.0.3) by the way.
I had the same issue in a master/detail flow layout. By setting the layer type to software my video being cut in half issues were gone. This turns off hardware acceleration for the webview.
FYI I only experienced this issue on Amazon Tablets.