【问题标题】:infinite scroll in android webviewandroid webview中的无限滚动
【发布时间】:2014-03-01 11:48:36
【问题描述】:

我有一些本地 html 文件,我想用无限滚动方法显示它们。

注意:我无法更改 html 内容,因此请不要建议向其中添加 javascript。我必须在运行时完成。

所以,我发现我可以在运行时通过loadUrl("javascript: ....") 执行javascript

我重写了webViewonOverScrolled() 方法以找出用户何时到达webView 的末尾。 (它小心行事,所以问题不在这里)

问题是有时新内容附加成功,有时没有附加。

在日志中我可以看到页面结束方法被触发,检索新的 html 正文被调用,执行 javascript 代码被调用,但它没有影响。

这是我的代码,可能出了点问题,我看不到它:

@Override
protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY)
{
    super.onOverScrolled(scrollX, scrollY, clampedX, clampedY);
    if(clampedY & reloadFlag) //for first time realodFlag is false, when the WebViewClient.onPageFinished() get called it turn to ture
    {
        if (!(isVerticalScrollPossible(SCROLL_DOWN)))
        {
            reloadFlag = false; 
            currUri = nextResource(currUri); //findout next page
            appendNextPage();
        }

    }
}

private final int SCROLL_DOWN = 1;
private final int SCROLL_UP = -1;

private boolean isVerticalScrollPossible(int direction)
{
    final int offset = computeVerticalScrollOffset();
    final int range = computeVerticalScrollRange() - computeVerticalScrollExtent();
    if (range == 0) return false;
    if (direction < 0) {
        return offset > 0;
    } else {
        return offset < range - 1;
    }
}

public String getNextPageJS(Uri currPage)
{
    String body = getNextPageBody(currPage);
    //Log.d("myTAG", body);
    String jsResult = "javascript:(function() { document.body.innerHTML += '<div id=\"separator\" style=\"height:10px; margin-top:10px; margin-bottom:10px; background-color:#000000;\"></div>" + body + "';})()";
    return jsResult;
}

private void appendNextPage()
{
    reloadFlag = false;
    Thread appendThread = new Thread(null, doAppend, "backgroundAppend");
    appendThread.start();
    Log.i("appendNextPage", "get called");
}

public String rs = "";
private Runnable doAppend = new Runnable()
{
    @Override
    public void run() 
    {
        Log.i("doAppend", "get called + currUri: " + currUri);
        rs = getNextPageJS(currUri);
        //loadUrl(rs);
        appendHandler.sendEmptyMessage(0);
    }       
};

private Handler appendHandler = new Handler()
{
    public void handleMessage(Message msg)
    {
        loadUrl(rs);
        reloadFlag = true;
        Log.i("appendHandler", "get called");       
    }
};

注意:有时我会在模拟器日志中得到这个(不是在真实设备中):

I/chromium(1339): [INFO:CONSOLE(1)] "Uncaught SyntaxError: An invalid or illegal string was specified.", source: http://localhost:1025/OEBPS/Text/Section0042.xhtml (1)

页面的数量有时会有所不同,可能是因为javascript代码不好,我不知道。

提示:

1) 我不是 javascript 编码器,所以可能是 javascript 代码不好

2) 或者多次调用javascript代码会导致这个问题

3) 我知道 javascript 代码必须在页面完全加载后执行,所以可能代码调用得太快了,问题是 onPageFinished() 仅在第一页被调用,并且在通过附加新内容时不会调用javascript代码,我尝试使用线程解决这个问题,我认为它有效。

更新:我发现当 html 正文较小时,此代码可以正常工作,但是当我尝试附加较大的正文时,它不起作用。 loadUrl() 方法是否有字符限制?或任何其他想法?

【问题讨论】:

    标签: javascript android android-webview infinite-scroll


    【解决方案1】:

    好的,我找到了问题,如果有人想知道的话。

    问题是loadUri()(至少在我的情况下)不能一次加载太多的html标签(在我编写的javascript代码中)

    所以,解决方法很简单,一一加载标签。

    这是我使用的代码:

    public ArrayList<String> getNextPageBody(Uri currAddress)
    {
        String html = getHtml(currAddress); // this is the all html tags in the next file
    
        //get body elements as arrayList, using jsoup
        Document doc = Jsoup.parse(html);
        Elements elements = doc.select("body").first().children();
        ArrayList<String> chuncks = new ArrayList<String>();
        for (org.jsoup.nodes.Element el : elements)
        {
            chuncks.add(el.toString());
        }
    
        return chuncks;
    }
    
    public void loadBodyChunk(ArrayList<String> bodyChunks)
    {    
        //show a separator for each page
        bodyChunks.add(0, "javascript:(function() { document.body.innerHTML += '<div id=\"separator\" style=\"height:10px; margin-top:10px; margin-bottom:10px; background-color:#000000;\"></div>';}())");
        loadUrl(bodyChunks.get(0));
    
        for(int i = 1; i < bodyChunks.size(); i++)
        {   
            String jsResult = "javascript:(function() { document.body.innerHTML += '" +  bodyChunks.get(i) + "';}())";
            loadUrl(jsResult);
        }
    
        reloadFlag = true;
    }
    

    编辑:

    还有: 首先 String 中的 's 应该替换为 \'

    body = body.replace("'", "\\'");
    

    那么所有换行符都应该被删除:

    body = body.replaceAll(System.getProperty("line.separator"), " ");
    

    所有问题都解决了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多