Определите, является ли WebView невидимым, используя только JS
У меня есть тестовое приложение для Android с веб-интерфейсом:
<WebView
android:alpha="0"
android:id="@+id/myWebView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Моя основная активность загружает страницу, на которой работает JS-контент. JS разрешен с использованием:
webSettings.setJavaScriptEnabled(true);
В моем приложении есть кнопка, которая переключает значение альфа от 0 до 1 (show/hide webView).
Есть ли "творческий" способ обнаружения изменений на стороне JS?
Вещи, которые я пробовал:
Обновить:
Уточнение, я ищу решение JS Only, фактический JS-код - это SDK, используемый внутри среды WebView.
Я не контролирую приложение Android, полный контроль над содержимым WebView.
Ответы
Ответ 1
Вы можете подклассифицировать android WebView
, переопределить его метод setAlpha
и добавить некоторую логику, чтобы веб-страница знала текущее значение альфа.
Вот упрощенный пример:
import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.webkit.WebView;
public class MyWebView extends WebView {
public MyWebView(Context context) {
super(context);
init();
}
public MyWebView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public MyWebView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
public MyWebView(Context context,
AttributeSet attrs,
int defStyleAttr,
int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
}
@SuppressLint("SetJavaScriptEnabled")
private void init() {
getSettings().setJavaScriptEnabled(true);
}
@Override
public void setAlpha(float alpha) {
super.setAlpha(alpha);
propagateAlphaToWebPage(alpha);
}
private void propagateAlphaToWebPage(float alpha) {
// setWebViewAlpha is a JS function that should be defined in your html js
String jssnippet = "setWebViewAlpha("+alpha+");";
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
evaluateJavascript(jssnippet, null);
} else {
loadUrl("javascript:"+jssnippet);
}
}
}
Другие связанные вопросы, которые могут оказаться полезными:
Ответ 2
Ниже приведен полный код, который будет WebView
в JavaScript
если WebView
будет виден или нет.
Шаги:
- Создайте макет, содержащий ToggleButton и WebView.
- Загрузите html с помощью
htmlWebView.loadUrl("file:///android_asset/index.html");
и связанный код - Создайте функцию
onToggleButtonPressed()
которая будет вызываться onClick
toggle button - В
onToggleButtonPressed()
отображает/скрывает WebView и в то же время передает статус JavaScript с помощью htmlWebView.evaluateJavascript()
. Pass visibilityStatusFromAndroid()
для JavaScript - Получить статус в JavaScript из функции
visibilityStatusFromAndroid()
Android-макет XML-кода:
<ToggleButton
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:background="@color/red"
android:onClick="onToggleButtonPressed"
android:text="Button1"
android:textOn="Show"
android:textOff="Hide"
tools:ignore="MissingConstraints"
tools:layout_editor_absoluteX="148dp"
tools:layout_editor_absoluteY="0dp" />
<WebView
android:id="@+id/webView"
android:layout_width="368dp"
android:layout_height="447dp"
android:layout_alignParentStart="true"
android:layout_below="@+id/button"
tools:ignore="MissingConstraints"
tools:layout_editor_absoluteX="8dp"
tools:layout_editor_absoluteY="56dp"
android:layout_alignParentLeft="true" />
Код Java:
WebView htmlWebView; // put it outside onCreate() to make it accessible in onToggleButtonPressed()
htmlWebView = (WebView)findViewById(R.id.webView);
htmlWebView.setWebViewClient(new WebViewClient());
htmlWebView.loadUrl("file:///android_asset/index.html");
WebSettings webSetting = htmlWebView.getSettings();
webSetting.setJavaScriptEnabled(true);
public void onToggleButtonPressed(View view) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
boolean on = ((ToggleButton) view).isChecked();
String visibility;
if (on) {
htmlWebView.setVisibility(View.GONE);
visibility = "NOT VISIBLE";
htmlWebView.evaluateJavascript("javascript: " +
"visibilityStatusFromAndroid(\"" + visibility + "\")", null);
} else {
htmlWebView.setVisibility(View.VISIBLE);
visibility = "VISIBLE NOW";
htmlWebView.evaluateJavascript("javascript: " +
"visibilityStatusFromAndroid(\"" + visibility + "\")", null);
}
}
}
Файл JavaScript:
function visibilityStatusFromAndroid(message) {
if (message === "NOT VISIBLE") {
console.log("webview is not visible");
// do your stuff here
} else if (message === "VISIBLE NOW") {
console.log("webview is visible now");
// do your stuff here
}
}
Это. Вы сделали!
Вот видео рабочего кода.
Обновить:
Существует один вариант, который можно использовать для обнаружения видимости только с использованием JavaScript - document.hasFocus(), но это не будет работать, если на экране есть какой-либо EditText, и пользователь сосредоточит этот EditText.
На всякий случай ниже приведен код, который вы можете использовать для document.hasFocus()
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>TEST</title>
<style>
#message { font-weight: bold; }
</style>
<script>
setInterval( checkPageFocus, 200 ); // you can change interval time to check more frequently
function checkPageFocus() {
var info = document.getElementById("message");
if ( document.hasFocus() ) {
info.innerHTML = "The document is VISIBLE.";
} else {
info.innerHTML = "The document is INVISIBLE.";
}
}
</script>
</head>
<body>
<h1>JavaScript hasFocus example</h1>
<div id="message">Waiting for user action</div>
</body>
</html>
Ответ 3
В настоящее время нет JS-единственного решения.
Содержимое WebView не должно получать информацию об окружающей среде.
Единственным исключением является информация, которая была вызвана самой средой.
Это будет противоречить базовой песочнице и может привести к проблемам безопасности.
Поскольку нет стандартного API, который предоставит вам необходимую информацию, вам придется самостоятельно изменить среду, чтобы открыть ее в WebView.
Если вы не можете изменить среду, то, что вы запрашиваете, (теоретически) невозможно с текущими браузерами /Android.
@Hack Чтобы найти реальную лазейку, которую мы можем использовать для получения альфа-значения, нам понадобится более подробная информация о JS SDK, об окружающей среде и о том, какое влияние на сторону Android и веб-просмотра приложения у вас есть.
И даже тогда, потратив много усилий, результат, скорее всего, будет таким же.