Android WebView 全屏视频退出创建额外的空白白色space
Android WebView full screen video exit create extra blank white space
我有一个 android 网络应用程序,我想在其中以隐藏系统栏和导航栏的全屏模式播放视频。一切正常,没有任何问题。
我的MainActivity的原始视图如下图所示。
但是当我退出全屏模式时出现了问题。每当我退出全屏视频时,都会创建一些空白区域。
我试过 YouTube、Vimeo 和 Dailymotion。但问题仍然存在于所有这些站点。下面我给出了他们的演示,退出全屏模式后的样子。
YouTube:
Vimeo:
DailyMotion:
这是我的activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".MainActivity">
<ProgressBar
android:id="@+id/mainProgressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:max="100"
android:visibility="gone" />
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/mainSrl"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@id/mainControllerContainer"
android:layout_below="@id/mainProgressBar">
<com.jobayr.webapp.ObservableWebView
android:id="@+id/mainWebView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<LinearLayout
android:id="@+id/mainControllerContainer"
android:layout_width="match_parent"
android:layout_height="?actionBarSize"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:background="@color/colorPrimary"
android:gravity="center"
android:orientation="horizontal"
android:weightSum="4">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/mainControllerBackBtn"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="?selectableItemBackgroundBorderless"
android:clickable="true"
android:focusable="true"
android:padding="12dp"
app:srcCompat="@drawable/icon_back" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/mainControllerRefreshBtn"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="?selectableItemBackgroundBorderless"
android:clickable="true"
android:focusable="true"
android:padding="12dp"
app:srcCompat="@drawable/icon_refresh" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/mainControllerHomeBtn"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="?selectableItemBackgroundBorderless"
android:clickable="true"
android:focusable="true"
android:padding="12dp"
app:srcCompat="@drawable/icon_home" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/mainControllerForwardBtn"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="?selectableItemBackgroundBorderless"
android:clickable="true"
android:focusable="true"
android:padding="12dp"
app:srcCompat="@drawable/icon_forward" />
</LinearLayout>
</RelativeLayout>
MainActivity.kt
class MainActivity : AppCompatActivity(), AdvancedWebView.Listener {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
init()
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.mian_menu, menu)
return super.onCreateOptionsMenu(menu)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == R.id.miClearCookies) {
AlertDialog.Builder(this)
.setTitle("Clear Data")
.setMessage("Are you sure you want to delete browser data?")
.setPositiveButton("Delete") { _, _ ->
WebStorage.getInstance().deleteAllData()
CookieManager.getInstance().removeAllCookies(null)
CookieManager.getInstance().flush()
mainWebView.clearCache(true)
mainWebView.clearFormData()
mainWebView.clearHistory()
mainWebView.clearSslPreferences()
}
.setNegativeButton("Cancel", null)
.show()
} else if (item.itemId == R.id.miExit) {
AlertDialog.Builder(this)
.setTitle("Confirmation")
.setMessage("Are you sure you want to exit?")
.setPositiveButton("YES") { _, _ ->
finishAffinity()
}
.setNegativeButton("CANCEL", null)
.show()
}
return super.onOptionsItemSelected(item)
}
override fun onResume() {
super.onResume()
mainWebView.onResume()
}
override fun onPause() {
super.onPause()
mainWebView.onPause()
}
override fun onDestroy() {
super.onDestroy()
mainWebView.onDestroy()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
mainWebView.onActivityResult(requestCode, resultCode, data)
}
private fun init() {
goOn()
initCallback()
}
private fun goOn() {
val permissionListener = object : PermissionListener {
override fun onPermissionGranted() {
initWebView()
}
override fun onPermissionDenied(deniedPermissions: MutableList<String>?) {
AlertDialog.Builder(this@MainActivity)
.setTitle("Permission Required")
.setMessage("Kindly grant all the permission to use this app")
.setPositiveButton("Retry") { _, _ ->
goOn()
}
.setNegativeButton("Cancel") { _, _ ->
finishAffinity()
}
.show()
}
}
TedPermission.with(this)
.setPermissionListener(permissionListener)
.setDeniedMessage("You need to grant all the permission to use this app")
.setPermissions(
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE
)
.check()
}
@SuppressLint("SetJavaScriptEnabled")
private fun initWebView() {
mainWebView.loadUrl(getString(R.string.url), true)
mainWebView.settings.javaScriptEnabled = true
mainWebView.setListener(this, this)
mainWebView.settings.javaScriptCanOpenWindowsAutomatically = true
mainWebView.webViewClient = WebViewClient()
mainWebView.settings.setSupportZoom(false)
mainWebView.settings.displayZoomControls = false
mainWebView.setCookiesEnabled(true)
mainWebView.setThirdPartyCookiesEnabled(true)
mainWebView.setMixedContentAllowed(true)
mainWebView.webChromeClient = CustomChromeClient(this, mainProgressBar)
}
private fun initCallback() {
mainControllerBackBtn.setOnClickListener {
if (mainWebView.canGoBack()) {
mainWebView.goBack()
} else Toast.makeText(this, "Going Back Is Not Available", Toast.LENGTH_SHORT)
.show()
}
mainControllerRefreshBtn.setOnClickListener {
mainWebView.reload()
}
mainControllerHomeBtn.setOnClickListener {
mainWebView.loadUrl(getString(R.string.url), true)
}
mainControllerForwardBtn.setOnClickListener {
if (mainWebView.canGoForward()) {
mainWebView.goForward()
} else Toast.makeText(this, "Going Forward Is Not Available", Toast.LENGTH_SHORT)
.show()
}
mainSrl.setOnRefreshListener {
mainWebView.reload()
}
mainWebView.setOnScrollChangedCallback { _, t, _, oldt ->
if (t > oldt) {
if (t - oldt >= 60) {
supportActionBar?.hide()
mainControllerContainer.visibility = View.GONE
}
} else if (t < oldt) {
if (oldt - t >= 60) {
supportActionBar?.show()
mainControllerContainer.visibility = View.VISIBLE
}
}
}
}
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
if (event!!.action == KeyEvent.ACTION_DOWN) {
when (keyCode) {
KeyEvent.KEYCODE_BACK -> {
if (mainWebView.canGoBack()) {
mainWebView.goBack()
} else {
AlertDialog.Builder(this)
.setTitle("Confirmation")
.setMessage("Are you sure you want to exit?")
.setPositiveButton("YES") { _, _ ->
finishAffinity()
}
.setNegativeButton("CANCEL", null)
.show()
}
return true
}
}
}
return super.onKeyDown(keyCode, event)
}
override fun onPageFinished(url: String?) {
if (mainSrl.isRefreshing) {
mainSrl.isRefreshing = false
}
}
override fun onPageError(errorCode: Int, description: String?, failingUrl: String?) {
if (mainSrl.isRefreshing) {
mainSrl.isRefreshing = false
}
description?.let {
Toast.makeText(this, it, Toast.LENGTH_LONG).show()
}
}
override fun onDownloadRequested(
url: String?,
suggestedFilename: String?,
mimeType: String?,
contentLength: Long,
contentDisposition: String?,
userAgent: String?
) {
try {
if (AdvancedWebView.handleDownload(this, url, suggestedFilename)) {
Toast.makeText(this, "Download Started", Toast.LENGTH_LONG).show()
} else {
AlertDialog.Builder(this)
.setTitle("Download Error")
.setMessage("Couldn't download ${suggestedFilename}. Make sure your download manager is working properly.")
.setPositiveButton("OK", null)
.show()
}
} catch (e: Exception) {
AlertDialog.Builder(this)
.setTitle("Download Error")
.setMessage(e.message.toString())
.setPositiveButton("OK", null)
.show()
}
}
override fun onExternalPageRequest(url: String?) {
mainWebView.loadUrl(url, true)
}
override fun onPageStarted(url: String?, favicon: Bitmap?) {}
}
CustomChromeClient.java
public class CustomChromeClient extends WebChromeClient {
private Activity activity;
private ProgressBar progressBar;
private View mCustomView;
private WebChromeClient.CustomViewCallback mCustomViewCallback;
private int mOriginalOrientation;
private int mOriginalSystemUiVisibility;
CustomChromeClient(Activity activity, ProgressBar progressBar) {
this.activity = activity;
this.progressBar = progressBar;
}
public Bitmap getDefaultVideoPoster() {
if (mCustomView == null) {
return null;
}
return BitmapFactory.decodeResource(activity.getResources(), 2130837573);
}
@Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
if (newProgress < 100) {
progressBar.setVisibility(View.VISIBLE);
progressBar.setProgress(newProgress);
} else {
progressBar.setVisibility(View.GONE);
progressBar.setProgress(0);
}
}
public void onHideCustomView() {
this.mCustomViewCallback.onCustomViewHidden();
this.mCustomViewCallback = null;
((FrameLayout) activity.getWindow().getDecorView()).removeView(this.mCustomView);
this.mCustomView = null;
activity.getWindow().getDecorView().setSystemUiVisibility(this.mOriginalSystemUiVisibility);
activity.setRequestedOrientation(this.mOriginalOrientation);
activity.getWindow().getDecorView().invalidate();
}
public void onShowCustomView(View paramView, WebChromeClient.CustomViewCallback paramCustomViewCallback) {
if (this.mCustomView != null) {
onHideCustomView();
return;
}
this.mCustomView = paramView;
this.mOriginalSystemUiVisibility = activity.getWindow().getDecorView().getSystemUiVisibility();
this.mOriginalOrientation = activity.getRequestedOrientation();
this.mCustomViewCallback = paramCustomViewCallback;
((FrameLayout) activity.getWindow().getDecorView()).addView(this.mCustomView, new FrameLayout.LayoutParams(-1, -1));
activity.getWindow().getDecorView().setSystemUiVisibility(3846 | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.demo.webapp">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:hardwareAccelerated="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"
android:usesCleartextTraffic="true"
tools:ignore="AllowBackup,UnusedAttribute">
<activity
android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|screenSize|screenLayout|keyboard|layoutDirection|uiMode">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
OvservableWebView.java这个不是感兴趣的主题(如果我没看错的话。这个主要是检测我的 webview 的滚动行为。不过我也发布了它。)
public class ObservableWebView extends AdvancedWebView {
private OnScrollChangedCallback mOnScrollChangedCallback;
public ObservableWebView(final Context context) {
super(context);
}
public ObservableWebView(final Context context, final AttributeSet attrs) {
super(context, attrs);
}
public ObservableWebView(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onScrollChanged(final int l, final int t, final int oldl, final int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
if (mOnScrollChangedCallback != null) mOnScrollChangedCallback.onScroll(l, t, oldl, oldt);
}
public OnScrollChangedCallback getOnScrollChangedCallback() {
return mOnScrollChangedCallback;
}
public void setOnScrollChangedCallback(final OnScrollChangedCallback onScrollChangedCallback) {
mOnScrollChangedCallback = onScrollChangedCallback;
}
public static interface OnScrollChangedCallback {
public void onScroll(int l, int t, int oldl, int oldt);
}
}
请帮我解决这个问题。任何解决方案,想法将不胜感激。提前致谢。
我找到了解决方案。
从您的 RelativeLayout
中删除 android:fitsSystemWindows="true"
,这将删除视图顶部的空白 space。
我找到了解决办法!
您必须使用此存储库中的 类:https://github.com/cprcrack/VideoEnabledWebView.
这是一个由 Stack Overflow 用户创建的存储库,用于帮助和改进在 Android WebView 中全屏播放 HTML 视频。
你可以在another user answer
中看到
这是唯一对我有用的解决方案。
我有一个 android 网络应用程序,我想在其中以隐藏系统栏和导航栏的全屏模式播放视频。一切正常,没有任何问题。
我的MainActivity的原始视图如下图所示。
但是当我退出全屏模式时出现了问题。每当我退出全屏视频时,都会创建一些空白区域。
我试过 YouTube、Vimeo 和 Dailymotion。但问题仍然存在于所有这些站点。下面我给出了他们的演示,退出全屏模式后的样子。
YouTube:
Vimeo:
DailyMotion:
这是我的activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".MainActivity">
<ProgressBar
android:id="@+id/mainProgressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:max="100"
android:visibility="gone" />
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/mainSrl"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@id/mainControllerContainer"
android:layout_below="@id/mainProgressBar">
<com.jobayr.webapp.ObservableWebView
android:id="@+id/mainWebView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<LinearLayout
android:id="@+id/mainControllerContainer"
android:layout_width="match_parent"
android:layout_height="?actionBarSize"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:background="@color/colorPrimary"
android:gravity="center"
android:orientation="horizontal"
android:weightSum="4">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/mainControllerBackBtn"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="?selectableItemBackgroundBorderless"
android:clickable="true"
android:focusable="true"
android:padding="12dp"
app:srcCompat="@drawable/icon_back" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/mainControllerRefreshBtn"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="?selectableItemBackgroundBorderless"
android:clickable="true"
android:focusable="true"
android:padding="12dp"
app:srcCompat="@drawable/icon_refresh" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/mainControllerHomeBtn"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="?selectableItemBackgroundBorderless"
android:clickable="true"
android:focusable="true"
android:padding="12dp"
app:srcCompat="@drawable/icon_home" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/mainControllerForwardBtn"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="?selectableItemBackgroundBorderless"
android:clickable="true"
android:focusable="true"
android:padding="12dp"
app:srcCompat="@drawable/icon_forward" />
</LinearLayout>
</RelativeLayout>
MainActivity.kt
class MainActivity : AppCompatActivity(), AdvancedWebView.Listener {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
init()
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.mian_menu, menu)
return super.onCreateOptionsMenu(menu)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == R.id.miClearCookies) {
AlertDialog.Builder(this)
.setTitle("Clear Data")
.setMessage("Are you sure you want to delete browser data?")
.setPositiveButton("Delete") { _, _ ->
WebStorage.getInstance().deleteAllData()
CookieManager.getInstance().removeAllCookies(null)
CookieManager.getInstance().flush()
mainWebView.clearCache(true)
mainWebView.clearFormData()
mainWebView.clearHistory()
mainWebView.clearSslPreferences()
}
.setNegativeButton("Cancel", null)
.show()
} else if (item.itemId == R.id.miExit) {
AlertDialog.Builder(this)
.setTitle("Confirmation")
.setMessage("Are you sure you want to exit?")
.setPositiveButton("YES") { _, _ ->
finishAffinity()
}
.setNegativeButton("CANCEL", null)
.show()
}
return super.onOptionsItemSelected(item)
}
override fun onResume() {
super.onResume()
mainWebView.onResume()
}
override fun onPause() {
super.onPause()
mainWebView.onPause()
}
override fun onDestroy() {
super.onDestroy()
mainWebView.onDestroy()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
mainWebView.onActivityResult(requestCode, resultCode, data)
}
private fun init() {
goOn()
initCallback()
}
private fun goOn() {
val permissionListener = object : PermissionListener {
override fun onPermissionGranted() {
initWebView()
}
override fun onPermissionDenied(deniedPermissions: MutableList<String>?) {
AlertDialog.Builder(this@MainActivity)
.setTitle("Permission Required")
.setMessage("Kindly grant all the permission to use this app")
.setPositiveButton("Retry") { _, _ ->
goOn()
}
.setNegativeButton("Cancel") { _, _ ->
finishAffinity()
}
.show()
}
}
TedPermission.with(this)
.setPermissionListener(permissionListener)
.setDeniedMessage("You need to grant all the permission to use this app")
.setPermissions(
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE
)
.check()
}
@SuppressLint("SetJavaScriptEnabled")
private fun initWebView() {
mainWebView.loadUrl(getString(R.string.url), true)
mainWebView.settings.javaScriptEnabled = true
mainWebView.setListener(this, this)
mainWebView.settings.javaScriptCanOpenWindowsAutomatically = true
mainWebView.webViewClient = WebViewClient()
mainWebView.settings.setSupportZoom(false)
mainWebView.settings.displayZoomControls = false
mainWebView.setCookiesEnabled(true)
mainWebView.setThirdPartyCookiesEnabled(true)
mainWebView.setMixedContentAllowed(true)
mainWebView.webChromeClient = CustomChromeClient(this, mainProgressBar)
}
private fun initCallback() {
mainControllerBackBtn.setOnClickListener {
if (mainWebView.canGoBack()) {
mainWebView.goBack()
} else Toast.makeText(this, "Going Back Is Not Available", Toast.LENGTH_SHORT)
.show()
}
mainControllerRefreshBtn.setOnClickListener {
mainWebView.reload()
}
mainControllerHomeBtn.setOnClickListener {
mainWebView.loadUrl(getString(R.string.url), true)
}
mainControllerForwardBtn.setOnClickListener {
if (mainWebView.canGoForward()) {
mainWebView.goForward()
} else Toast.makeText(this, "Going Forward Is Not Available", Toast.LENGTH_SHORT)
.show()
}
mainSrl.setOnRefreshListener {
mainWebView.reload()
}
mainWebView.setOnScrollChangedCallback { _, t, _, oldt ->
if (t > oldt) {
if (t - oldt >= 60) {
supportActionBar?.hide()
mainControllerContainer.visibility = View.GONE
}
} else if (t < oldt) {
if (oldt - t >= 60) {
supportActionBar?.show()
mainControllerContainer.visibility = View.VISIBLE
}
}
}
}
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
if (event!!.action == KeyEvent.ACTION_DOWN) {
when (keyCode) {
KeyEvent.KEYCODE_BACK -> {
if (mainWebView.canGoBack()) {
mainWebView.goBack()
} else {
AlertDialog.Builder(this)
.setTitle("Confirmation")
.setMessage("Are you sure you want to exit?")
.setPositiveButton("YES") { _, _ ->
finishAffinity()
}
.setNegativeButton("CANCEL", null)
.show()
}
return true
}
}
}
return super.onKeyDown(keyCode, event)
}
override fun onPageFinished(url: String?) {
if (mainSrl.isRefreshing) {
mainSrl.isRefreshing = false
}
}
override fun onPageError(errorCode: Int, description: String?, failingUrl: String?) {
if (mainSrl.isRefreshing) {
mainSrl.isRefreshing = false
}
description?.let {
Toast.makeText(this, it, Toast.LENGTH_LONG).show()
}
}
override fun onDownloadRequested(
url: String?,
suggestedFilename: String?,
mimeType: String?,
contentLength: Long,
contentDisposition: String?,
userAgent: String?
) {
try {
if (AdvancedWebView.handleDownload(this, url, suggestedFilename)) {
Toast.makeText(this, "Download Started", Toast.LENGTH_LONG).show()
} else {
AlertDialog.Builder(this)
.setTitle("Download Error")
.setMessage("Couldn't download ${suggestedFilename}. Make sure your download manager is working properly.")
.setPositiveButton("OK", null)
.show()
}
} catch (e: Exception) {
AlertDialog.Builder(this)
.setTitle("Download Error")
.setMessage(e.message.toString())
.setPositiveButton("OK", null)
.show()
}
}
override fun onExternalPageRequest(url: String?) {
mainWebView.loadUrl(url, true)
}
override fun onPageStarted(url: String?, favicon: Bitmap?) {}
}
CustomChromeClient.java
public class CustomChromeClient extends WebChromeClient {
private Activity activity;
private ProgressBar progressBar;
private View mCustomView;
private WebChromeClient.CustomViewCallback mCustomViewCallback;
private int mOriginalOrientation;
private int mOriginalSystemUiVisibility;
CustomChromeClient(Activity activity, ProgressBar progressBar) {
this.activity = activity;
this.progressBar = progressBar;
}
public Bitmap getDefaultVideoPoster() {
if (mCustomView == null) {
return null;
}
return BitmapFactory.decodeResource(activity.getResources(), 2130837573);
}
@Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
if (newProgress < 100) {
progressBar.setVisibility(View.VISIBLE);
progressBar.setProgress(newProgress);
} else {
progressBar.setVisibility(View.GONE);
progressBar.setProgress(0);
}
}
public void onHideCustomView() {
this.mCustomViewCallback.onCustomViewHidden();
this.mCustomViewCallback = null;
((FrameLayout) activity.getWindow().getDecorView()).removeView(this.mCustomView);
this.mCustomView = null;
activity.getWindow().getDecorView().setSystemUiVisibility(this.mOriginalSystemUiVisibility);
activity.setRequestedOrientation(this.mOriginalOrientation);
activity.getWindow().getDecorView().invalidate();
}
public void onShowCustomView(View paramView, WebChromeClient.CustomViewCallback paramCustomViewCallback) {
if (this.mCustomView != null) {
onHideCustomView();
return;
}
this.mCustomView = paramView;
this.mOriginalSystemUiVisibility = activity.getWindow().getDecorView().getSystemUiVisibility();
this.mOriginalOrientation = activity.getRequestedOrientation();
this.mCustomViewCallback = paramCustomViewCallback;
((FrameLayout) activity.getWindow().getDecorView()).addView(this.mCustomView, new FrameLayout.LayoutParams(-1, -1));
activity.getWindow().getDecorView().setSystemUiVisibility(3846 | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.demo.webapp">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:hardwareAccelerated="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"
android:usesCleartextTraffic="true"
tools:ignore="AllowBackup,UnusedAttribute">
<activity
android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|screenSize|screenLayout|keyboard|layoutDirection|uiMode">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
OvservableWebView.java这个不是感兴趣的主题(如果我没看错的话。这个主要是检测我的 webview 的滚动行为。不过我也发布了它。)
public class ObservableWebView extends AdvancedWebView {
private OnScrollChangedCallback mOnScrollChangedCallback;
public ObservableWebView(final Context context) {
super(context);
}
public ObservableWebView(final Context context, final AttributeSet attrs) {
super(context, attrs);
}
public ObservableWebView(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onScrollChanged(final int l, final int t, final int oldl, final int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
if (mOnScrollChangedCallback != null) mOnScrollChangedCallback.onScroll(l, t, oldl, oldt);
}
public OnScrollChangedCallback getOnScrollChangedCallback() {
return mOnScrollChangedCallback;
}
public void setOnScrollChangedCallback(final OnScrollChangedCallback onScrollChangedCallback) {
mOnScrollChangedCallback = onScrollChangedCallback;
}
public static interface OnScrollChangedCallback {
public void onScroll(int l, int t, int oldl, int oldt);
}
}
请帮我解决这个问题。任何解决方案,想法将不胜感激。提前致谢。
我找到了解决方案。
从您的 RelativeLayout
中删除 android:fitsSystemWindows="true"
,这将删除视图顶部的空白 space。
我找到了解决办法!
您必须使用此存储库中的 类:https://github.com/cprcrack/VideoEnabledWebView.
这是一个由 Stack Overflow 用户创建的存储库,用于帮助和改进在 Android WebView 中全屏播放 HTML 视频。
你可以在another user answer
中看到这是唯一对我有用的解决方案。