8

I have a MenuItem in my ActionBar that is a "reload" icon. My Activity has a WebView and I'd like the icon to start animating when the WebView starts loading a webpage and stop when it's finished. This includes when clicking on links in the site that is loaded. What I have so far, works the first time I bring up a webpage, but if I leave the Activity and load another webpage, the "reload" icon seems to double up, or I will get NullReference exception thrown on refreshItem.setActionView(ivRefresh);

enter image description here

Here is my code:

public class Browser extends SherlockFragmentActivity {

    private MenuItem refreshItem;
    private WebView mWebView;

    @Override
    public void onCreate(final Bundle icicle) 
    {
        super.onCreate(icicle);
        setContentView(R.layout.browser);

        mWebView = (WebView)findViewById(R.id.webview);
        mWebView.getSettings().setSupportZoom(true);  
        mWebView.getSettings().setBuiltInZoomControls(true);

        mWebView.loadUrl("http://www.google.com");

        mWebView.setWebViewClient(new WebBrowserClient());

        mWebView.setWebChromeClient(new WebChromeClient() {
            public void onProgressChanged(WebView view, int progress) {

                //if (!isFinishing() && progress == 100 && refreshItem != null && refreshItem.getActionView() != null)
                //{
                //refreshItem.getActionView().clearAnimation();
                //refreshItem.setActionView(null);
                //}
            }
        });         
    }

    private class WebBrowserClient extends WebViewClient {

          @Override
          public void onLoadResource(WebView view, String url) {
              //StartAnimation();
          }

          @Override
          public void onPageStarted(WebView view, String url, Bitmap favicon) {
              StartAnimation();
          }

          @Override
          public void onPageFinished(WebView view, String url) {
            if (refreshItem != null && refreshItem.getActionView() != null)
            {
                refreshItem.getActionView().clearAnimation();
                refreshItem.setActionView(null);
            }
          }

         @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            view.loadUrl(url);
            return true;
        }
    }

    private void StartAnimation() {
        final LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        final ImageView ivRefresh = (ImageView)inflater.inflate(R.layout.refresh_view, null);

        final Animation rotation = AnimationUtils.loadAnimation(this, R.anim.refresh);
        ivRefresh.startAnimation(rotation);
        refreshItem.setActionView(ivRefresh);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getSupportMenuInflater().inflate(R.menu.menu, menu);

        refreshItem = menu.findItem(R.id.refresh);

        return super.onCreateOptionsMenu(menu);
    }
}

The commented out code is different ways I tried to get it to work.

UPDATE:

After debugging this more, I put a breakpoint in the StartAnimation function and sometimes it's hit up to 7 times in a row and other times it's not. This makes no sense, as, to me, this should be working. Perplexing...

SOLUTION (SORT OF):

Updating the StartAnimation() function to this, seems to fix this issue, but seems more of a duct tape solution:

private void StartAnimation() {
    if (refreshItem != null && refreshItem.getActionView() == null)
    {
        final LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        final ImageView ivRefresh = (ImageView)inflater.inflate(R.layout.refresh_view, null);

        final Animation rotation = AnimationUtils.loadAnimation(this, R.anim.refresh);
        ivRefresh.startAnimation(rotation);
        refreshItem.setActionView(ivRefresh);
    }
}
4

3 回答 3

2

要创建流畅的用户界面体验,您的“加载轮”动画可能应该在用户单击链接时开始 - 而不是在新页面开始加载时 - 并在新页面加载时结束。这使得应用程序看起来对用户响应更快,并且是在Dolphin Browser中实现的行为,例如。

要实现这一点,您需要在 WebView 中监听用户的链接点击。如何做到这一点已经在这个答案中介绍过:

通过Android WebView中的javascript检测点击HTML按钮

您必须验证点击实际上是在指向新页面的链接上。您可以通过 WebView 的HitTestResult类找到单击的 HTML 元素。SO上的这个答案为您提供了有关如何验证 HitTestResult 值的详细信息:

从我的 android 应用程序中的网页获取点击事件

您从 onClick() 方法开始动画并从 WebViewClient 的 onPageFinished() 方法结束动画,如果新页面未加载,也会在 onReceivedError() 中结束。

于 2012-05-11T10:03:13.170 回答
0

您可以使用线程的概念。

直到 Web 视图中的 URL 加载,您显示加载动画,当 URL 加载时停止动画。

您需要使用两个线程,一个用于进度指示器(即 URL 加载),另一个用于动画的 UI 线程。

搜索它!

于 2012-05-18T06:40:55.293 回答
0

使Animation变量成为Browser类的成员,并确保在离开活动之前停止动画。

于 2012-05-12T16:45:11.593 回答