Android:在webview完成滚动后使按钮可见

Android:在webview完成滚动后使按钮可见,android,delegates,scroll,android-webview,Android,Delegates,Scroll,Android Webview,我有一个显示html文件的webview。当用户在webview中滚动到此文件的底部时,我希望显示一个以前隐藏的按钮,然后用户可以按下该按钮进行一些活动 我在iOS中做了类似的事情,我只是将代理设置为ViewController,并将按钮设置为可见。我如何在Android上做类似的事情?我注意到没有像iOS中那样的回调方法 编辑:现在,我有一个包含两个对象的活动:一个包含我的文本的webview和一个当前不可见的按钮。我希望我的活动在webview文本滚动到底部时收到一条消息,并使按钮可见尝试以

我有一个显示html文件的webview。当用户在webview中滚动到此文件的底部时,我希望显示一个以前隐藏的按钮,然后用户可以按下该按钮进行一些活动

我在iOS中做了类似的事情,我只是将代理设置为ViewController,并将按钮设置为可见。我如何在Android上做类似的事情?我注意到没有像iOS中那样的回调方法

编辑:现在,我有一个包含两个对象的活动:一个包含我的文本的webview和一个当前不可见的按钮。我希望我的活动在webview文本滚动到底部时收到一条消息,并使按钮可见

尝试以下操作:

@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        View view = (View) getChildAt(getChildCount()-1);
        int diff = (view.getBottom()-(getHeight()+getScrollY()));// Calculate the scrolldiff
        if( diff == 0 ){  // if diff is zero, then the bottom has been reached
            Log.d(ScrollTest.LOG_TAG, "MyScrollView: Bottom has been reached" );
            yourButton.setVisible(true);
        }
        super.onScrollChanged(l, t, oldl, oldt);
}

要实现这一点,请扩展ScrollView,然后覆盖onScrollChanged方法(从View继承)。

我必须自己这样做,以便在用户滚动到EULA底部后显示“我同意”按钮。律师,嗯

事实上,当您重写WebView(而不是@JackTurky的答案中的ScrollView)时,您可以调用computeVerticalScrollRange()来获取内容的高度,而不是getBottom(),后者返回可见的底部,并且没有用

这是我的综合解决方案。据我所知,这是所有API级别1的东西,所以它应该在任何地方都能工作

public class EulaWebView extends WebView {
    public EulaWebView(Context context) 
    {
        this(context, null);
    }

    public EulaWebView(Context context, AttributeSet attrs) 
    {
        this(context, attrs, 0);
    }

    public EulaWebView(Context context, AttributeSet attrs, int defStyle) 
    {
        super(context, attrs, defStyle);
    }

    public OnBottomReachedListener mOnBottomReachedListener = null;
    private int mMinDistance = 0;

    /**
     * Set the listener which will be called when the WebView is scrolled to within some
     * margin of the bottom.
     * @param bottomReachedListener
     * @param allowedDifference
     */
    public void setOnBottomReachedListener(OnBottomReachedListener bottomReachedListener, int allowedDifference ) {
        mOnBottomReachedListener = bottomReachedListener;
        mMinDistance = allowedDifference;
    }

    /**
     * Implement this interface if you want to be notified when the WebView has scrolled to the bottom.
     */
    public interface OnBottomReachedListener {
        void onBottomReached(View v);
    }

    @Override
    protected void onScrollChanged(int left, int top, int oldLeft, int oldTop) {
        if ( mOnBottomReachedListener != null ) {
            if ( (computeVerticalScrollRange() - (top + getHeight())) <= mMinDistance )
                mOnBottomReachedListener.onBottomReached(this);
        }
        super.onScrollChanged(left, top, oldLeft, oldTop);
    }

}

因此,当到达底部时(或者在本例中,当它们距离底部不超过50像素时),会出现“我同意”按钮。

对于类似的问题,上面的解决方案对我来说并不完全有效(滚动webView时隐藏按钮,滚动结束后显示)。我之所以想在滚动时隐藏它,是因为我想隐藏的按钮是为了跳转到webview的最底部,当webview是静态的时候它才对我起作用,但当视图仍在滚动时它没有跳转到底部。 因此,我做了以下工作:

向覆盖的webView添加了onScrollChanged回调,如:

private OnScrollChangedCallback mOnScrollChangedCallback;

public OnScrollChangedCallback getOnScrollChangedCallback() {
    return mOnScrollChangedCallback;
}

public void setOnScrollChangedCallback(
        final OnScrollChangedCallback onScrollChangedCallback) {
    mOnScrollChangedCallback = onScrollChangedCallback;
}

@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.onScrollChanged(l, t);
    }
}

/**
 * Implement in the activity/fragment/view that you want to listen to the
 * webview
 */
public static interface OnScrollChangedCallback {
    public void onScrollChanged(int l, int t);
}
在实现OnScrollChangedCallback的活动类中

更新:

Timer timer2showJumpButton;
private long lastScrollEventTimestamp;
public final static int HIDING_JUMP_BUTTON_ON_SCROLL_DELAY  = 500;

    public void onScrollChanged(int l, int t) {

    // showing button when scrolling starts
    if (btnJumpToBottom != null) {
        btnJumpToBottom.setVisibility(View.VISIBLE);
    }

    if (btnJumpToTop!= null) {
        btnJumpToTop.setVisibility(View.VISIBLE);
    }


    if (timer2showJumpButton == null) {

        final Runnable r2 = new Runnable() {

            @Override
            public void run() {
                if (btnJumpToBottom != null) {
                    btnJumpToBottom.setVisibility(View.GONE);
                }
                if (btnJumpToTop!= null) {
                    btnJumpToTop.setVisibility(View.GONE);
                }

            }
        };

        TimerTask timerTask = new TimerTask() {
            @Override
            public void run() {
                if (btnJumpToTop.getVisibility() == View.VISIBLE || btnJumpToBottom.getVisibility() == View.VISIBLE){
                    long currentTimestamp = System.currentTimeMillis();

                    if (currentTimestamp - lastScrollEventTimestamp > HIDING_JUMP_BUTTON_ON_SCROLL_DELAY1 ){                        
                        webView.postDelayed(r2, HIDING_JUMP_BUTTON_ON_SCROLL_DELAY);
                    }else{
                        //too soon
                    }
                }
            }
        };

        try {
            timer2showJumpButton = new Timer();
            timer2showJumpButton.schedule(timerTask, 500, 500);
        } catch (IllegalStateException e) {
            logger.warn(TAG + "/onScrollChanged/" + e.getMessage());

        }   
    }

    // adding runnable which will hide button back
    long currentTimestamp = System.currentTimeMillis();

    lastScrollEventTimestamp = currentTimestamp;
}

仅当webview到达/滚动到底部时,才加载/可见按钮

创建JavaScript类:

public class JavaScriptInterface {

  @android.webkit.JavascriptInterface
  public void didScrollToBottom() {
    Log.d(TAG, "Scroll to Bottom");
    myHandler.post(new Runnable() {
      @Override
      public void run() {
         btnAccept.setVisibility(View.VISIBLE);

          }
       });
      }
    }
在onCreate()中:

[我无法对答案发表评论,因此将我的评论作为新答案留在这里]

卡罗拉的答案(第一个)非常有效,除了

protected void onScrollChanged(int left, int top, int oldLeft, int oldTop)
方法,调用

getContentHeight()
对我来说太不准确了。它报告了一个太小的值,所以当用户只在WebView上滚动了大概三分之一的时候调用了我的侦听器。我曾经

computeVerticalScrollRange()

相反,这是完美的。感谢您的帮助提示。

但是webview没有对按钮的引用。您好,您能告诉我声明了
StaticHelpers
的位置吗?StaticHelpers是一个内部类,有一些通用方法-在本例中用于加载webview,对于从文件系统读取文本文件,没有什么特别令人吃惊的。很好!我只是使用computeVerticalScrollRange()而不是getContentHeight()使其工作。我发现“web.pageDown(true);”在滚动过程中有效,但“web.scrollTo(0,scrollTo);”被忽略。滚动页面时,您将得到数百个onScrollChanged回调,这将分配大量的计时器对象:)一种方法是使用一个计时器/线程,它将以固定的间隔(~500ms)运行。然后,您将在onScrollChanged上记录最后一个滚动时间戳,并根据最后一个滚动时间戳禁用/启用计时器上的按钮。computeVerticalScrollRange()似乎已更改为受保护的访问,因此这将不再起作用。
getContentHeight()
computeVerticalScrollRange()