Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/203.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/87.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android WebView加载位置不正确_Android_Html_Android Layout_Scroll_Android Webview - Fatal编程技术网

Android WebView加载位置不正确

Android WebView加载位置不正确,android,html,android-layout,scroll,android-webview,Android,Html,Android Layout,Scroll,Android Webview,我有一个应用程序可以在三个网络视图中加载HTML内容。为了简单起见,我们将它们称为顶部、中间和底部 用户总是查看中间的WebView。当用户到达页面顶部并向下滑动时,三个Web视图的布局将发生变化,从而使顶部视图可见。相反,当用户到达页面底部并向上滑动时,底部页面进入视图 想象一个100x100的屏幕。坐标0,0是屏幕的左上角,100100是屏幕的右下角。顶视图的布局顶部为-105,因此不可见,中间视图将占据屏幕,底视图的布局顶部为105,因此也不可见 topLayout.topMargin =

我有一个应用程序可以在三个
网络视图中加载HTML内容。为了简单起见,我们将它们称为顶部、中间和底部

用户总是查看中间的
WebView
。当用户到达页面顶部并向下滑动时,三个Web视图的布局将发生变化,从而使顶部视图可见。相反,当用户到达页面底部并向上滑动时,底部页面进入视图

想象一个100x100的屏幕。坐标0,0是屏幕的左上角,100100是屏幕的右下角。顶视图的布局顶部为-105,因此不可见,中间视图将占据屏幕,底视图的布局顶部为105,因此也不可见

topLayout.topMargin = -105;
middleLayout.topMargin = 0;
bottomLayout.topMargin = 105;

top.setLayoutParams(topLayout);
middle.setLayoutParams(middleLayout);
bottom.setLayoutParams(bottomLayout);
内容是书籍,因此当用户更改页面时,内容应按逻辑流动。向后(向上)滚动时,应显示上一页的底部。向前(向下)滚动时,应显示下一页的顶部。这是通过使用
scrollTo(x,y)
设置网络视图的滚动位置来实现的。代码如下所示,
a
表示内容的底部,
b
表示内容的顶部:

top.scrollTo(0, a);
middle.scrollTo(0, {a,b}); // a for previous page; b for next page
bottom.scrollTo(0, b);
当用户滑动到上一页时,top
WebView
的布局更改为top of 0以占据屏幕;中间部分改为105,底部改为-105并加载不同的内容,因此应用程序将为将来的前一次刷卡做好准备。
现在我们来谈谈我的问题。除了Android 4.4(KitKat)之外,它的工作原理与预期完全一致。在KitKat中,它可以在任意方向上进行两次滑动,但在同一方向上进行第三次滑动和后续滑动时,内容加载到错误的位置。当向后滚动时,内容开始加载,显示顶部。向前滚动时,内容开始加载,显示底部

我已经通过调试程序,注意到布局设置正确,滚动位置设置正确。然后,在设置这些值之后,但在实际绘制内容之前,堆栈中会发生一些更改滚动位置的事情

这就是我完全迷路的地方。为什么滚动值设置正确,然后在绘制屏幕之前神奇地改变

我已经尝试使用了一个
onLayoutCompleteListener
,但它不起作用。当我收到答案并尝试建议时,我会更新尝试的事情列表。提前感谢您的帮助


以下是我为更改页面所做工作的摘要:

public class MyWebView extends WebView {

    // Assume this is instantiated; it is by the time it is needed
    private List<MyWebView> viewArray = new List<MyWebView>(3); 

    private class CustomGestureListener extends 
        GestureDetector.SimpleOnGestureListener {

        private static final String DEBUG_TAG = "Gestures";
        private int scrollYOnTouch;
        private int scrollYOnRelease;

        @Override
        public boolean onFling(MotionEvent event1, MotionEvent event2, 
                float velocityX, float velocityY) {
            Log.d(DEBUG_TAG, "onFling: " + event1.toString() 
                + event2.toString());
            Log.i(DEBUG_TAG, "onFling: vX[" + velocityX 
                + "], vY[" + velocityY + "]");

            scrollYOnRelease = getScrollY();
            int bottomOfPage = scrollYOnTouch + getMeasuredHeight();
            int endOfContent = (int) Math.floor(getContentHeight() * getScale());
            int proximity = endOfContent - bottomOfPage;
            boolean atBottom = proximity <= 1;
            Log.i(DEBUG_TAG, "atBottom = (" + proximity + " <= 1)");

            if ((velocityY > VELOCITY_THRESHOLD) 
                && (scrollYOnRelease <= 0) && (scrollYOnTouch == 0)) {
                // User flung down while at the top of the page.
                // Go to the previous page.
                changePages(PREVIOUS_PAGE);
            } else if ((velocityY < -VELOCITY_THRESHOLD) 
                && (scrollYOnRelease >= scrollYOnTouch) && atBottom) {
                // User flung up while at the bottom of the page.
                // Go to the next page.
                changePages(NEXT_PAGE);
            }
            return true;
        }
    } // end of CustomGestureListener

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // Send the event to our gesture detector
        // If it is implemented, there will be a return value
        this.mDetector.onTouchEvent(event);
        // If the detected gesture is unimplemented, send it to the superclass
        return super.onTouchEvent(event);
    }

    @Override
    public void changePages(int direction) {

        int screenWidth = getScreenWidth();
        int screenHeight = getScreenHeight();

        VerticalPagingWebView previous;
        VerticalPagingWebView current;
        VerticalPagingWebView next;

        if (direction == NEXT_PAGE) {
            // Rearrange elements in webview array
            // Next page becomes current page,
            // current becomes previous,
            // previous becomes next.
            Collections.swap(viewArray, 0, 1);
            Collections.swap(viewArray, 1, 2);

            previous = viewArray.get(0);
            current = viewArray.get(1);
            next = viewArray.get(2);

            // Prepare the next page
            next.loadData(htmlContent, "text/html", null);

        } else if (direction == PREVIOUS_PAGE) {
            // Rearrange elements in webview array
            // Previous page becomes current page,
            // current becomes next,
            // next becomes previous.
            Collections.swap(viewArray, 1, 2);
            Collections.swap(viewArray, 0, 1);

            previous = viewArray.get(0);
            current = viewArray.get(1);
            next = viewArray.get(2);

            // Prepare the previous page
            previous.loadData(htmlContent, "text/html", null);
        }

        LayoutParams previousLayout = (LayoutParams) previous.getLayoutParams();
        previousLayout.leftMargin = LEFT_MARGIN;
        previousLayout.topMargin = -screenHeight - TOP_MARGIN;
        previous.setLayoutParams(previousLayout);

        LayoutParams currentLayout = (LayoutParams) current.getLayoutParams();
        currentLayout.leftMargin = LEFT_MARGIN;
        currentLayout.topMargin = 0;
        current.setLayoutParams(currentLayout);

        LayoutParams nextLayout = (LayoutParams) next.getLayoutParams();
        nextLayout.leftMargin = LEFT_MARGIN;
        nextLayout.topMargin = screenHeight + TOP_MARGIN;
        next.setLayoutParams(nextLayout);

        previous.scrollToBottom();
        next.scrollToTop();

        // I'm unsure if this is needed, but it works on everything but KitKat
        if (direction == NEXT_PAGE) {
            current.scrollToTop();
        } else {
            current.scrollToBottom();
        }
    } // end of changePages

    public void scrollToPageStart() {
        scrollTo(0,0);
    }

    public void scrollToPageBottom() { 
        // I know getScale() is deprecated; I take care of it.
        // This method works fine.
        int endOfContent = (int) Math.floor(getContentHeight() * getScale());
        int webViewHeight = getMeasuredHeight();
        scrollTo(0, endOfContent - webViewHeight);
    }
}
公共类MyWebView扩展了WebView{
//假设这是实例化的;在需要它的时候是实例化的
私有列表视图数组=新列表(3);
私有类CustomGestureListener扩展
GestureDetector.SimpleOnGestureListener{
私有静态最终字符串调试_TAG=“手势”;
私人触摸屏;
私隐释放;
@凌驾
公共布尔onFling(MotionEvent1、MotionEvent2、,
浮动速度x,浮动速度y){
Log.d(DEBUG_标记,“onFling:+event1.toString()
+事件2.toString());
Log.i(调试标签,“onFling:vX[”+velocityX
+“],vY[“+velocityY+””);
scrollYOnRelease=getScrollY();
int bottomOfPage=scrollYOnTouch+getMeasuredHeight();
int endOfContent=(int)Math.floor(getContentHeight()*getScale());
int接近度=endOfContent-页面底部;
底部布尔值=接近速度(阈值)
&&(scrollYOnRelease=scrollYOnTouch)和底部(&A){
//用户在页面底部时猛然向上移动。
//转到下一页。
更改页面(下一页);
}
返回true;
}
}//CustomGestureListener结束
@凌驾
公共布尔onTouchEvent(运动事件){
//将事件发送到我们的手势检测器
//如果它被实现,将有一个返回值
this.mDetector.onTouchEvent(事件);
//如果检测到的手势未实现,则将其发送到超类
返回super.onTouchEvent(事件);
}
@凌驾
公共无效更改页(int方向){
int screenWidth=getScreenWidth();
int screenHeight=getScreenHeight();
垂直分页WebView上一页;
垂直分页网络视图当前;
垂直分页网络视图下一步;
如果(方向==下一页){
//重新排列webview数组中的元素
//下一页变为当前页,
//当前变为先前,
//上一个变成下一个。
集合交换(viewArray,0,1);
集合交换(viewArray,1,2);
previous=viewArray.get(0);
当前=viewArray.get(1);
next=viewArray.get(2);
//准备下一页
loadData(htmlContent,“text/html”,null);
}else if(方向==上一页){
//重新排列webview数组中的元素
//上一页变为当前页,
//当前成为下一个,
//下一个变成上一个。
集合交换(viewArray,1,2);
集合交换(viewArray,0,1);
previous=viewArray.get(0);
当前=viewArray.get(1);
next=viewArray.get(2);
//准备上一页
loadData(htmlContent,“text/html”,null);
}
LayoutParams previousLayout=(LayoutParams)previous.getLayoutParams();
previousLayout.leftMargin=左对齐;
previousLayout.topMargin=-屏幕高度-顶部空白;
previous.setLayoutParams(previousLayout