Como rolar programaticamente o Android WebView
Pergunta
Estou tentando rolar programaticamente uma visualização da Web para o local de um elemento específico na árvore Dom. Mas até agora não consegui fazer com que o WebView responda às solicitações de rolagem. Eu tentei ligar para JavaScript que usa window.scrollTo(...)
, mas o WebView não responde. No lado Java, tentei ligar para o WebView.flingScroll(...)
método. WebView responderá a flingScroll
, mas o que eu preciso é um scrollTo(...)
capacidade. Alguma ideia?
Solução
Encontrei uma resposta melhor para esse problema. Acontece que WebView
tem scrollTo()
, getScrollX()
e getScrollY()
Métodos como você esperaria. Eles estão um pouco escondidos na documentação porque são herdados de View
(através da AbsoluteLayout
-> ViewGroup
-> View
). Esta é obviamente uma maneira melhor de manipular o WebView
Posição de rolagem do que a interface JavaScript um pouco complicada.
Outras dicas
Acontece que o window.scrollTo()
Funciona, você simplesmente não pode adicionar seu próprio método chamado scrollTo()
. Por algum motivo meu próprio scrollTo()
o método estava sendo invocado quando liguei window.scrollTo()
.
Então, em resumo, para rolar uma visualização da web para um determinado elemento DOM, escreva um JavaScript
função para fazer a rolagem:
function scrollToElement(id) {
var elem = document.getElementById(id);
var x = 0;
var y = 0;
while (elem != null) {
x += elem.offsetLeft;
y += elem.offsetTop;
elem = elem.offsetParent;
}
window.scrollTo(x, y);
}
E depois, no seu aplicativo Android (código Java), diga ao seu WebView para carregar um URL:
webView.loadUrl("javascript:scrollToElement('" + elemId + "')");
Existem alguns problemas com essa abordagem, como o pergaminho não será bem animado, mas o mecanismo geral funciona.
O objeto Dom Window relata a posição de rolagem atual da WebView corretamente (veja window.pageXOffset
, window.pageYOffset
ou window.scrollX
, window.scrollY)
. Se você deseja apenas saber a posição de rolagem atual da WebView, escreva algum JavaScript para ligar para o seu código Java e passar pelas compensações X/Y.
Você não pode fazer isso usando o código Java.
Para todos que estão presos a esse problema, tenho alguma conclusão sobre a rolagem de uma Webview no Android.
- Você não pode rolar um WebView ou obter a posição de rolagem usando o código Java.
- Você só pode obter o peso -peso, medido, medido e conteúdo de uma visualização da web, nada mais. Essas são todas as APIs Android, permitindo que você obtenha e definir status de rolagem.
- Porém, você pode substituir o OnScorllChanged para adicionar um evento de ouvinte autodefinido para rolagem da WebView (ou evento de fling), você será notificado a posição de origem e a nova posição.
- Bem, você pode rolar para uma posição usando o código JavaScript, como o seguinte, mas o desempenho é realmente ruim. Se você quiser rolar com frequência, pense em segundo.
Window.Scrollto (100.500)
Considere sua situação e escolha uma solução adequada. Observe também que a queda e a rolagem são coisas diferentes.
@Override
public void onPageFinished(final WebView view, String url) {
super.onPageFinished(view, url);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
if (app.scrollCache.containsKey(app.srctid))
{
app.scrollSpot=app.scrollCache.get(app.srctid);
view.scrollTo(0,(int)app.scrollSpot);
}
pageFinished=true;
}
}, 200);
}