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);
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);
}
}
To create a smooth ui-experience, your 'loading wheel' animation should probably start when the user clicks the link - rather than when the new page starts loading - and end when the new page has loaded. This makes the app seem more responsive to the user, and is the behaviour implemented in Dolphin Browser, as an example.
To implement this, you need to listen for the user's link clicks in the WebView. How to do this has already been covered in this answer here on SO:
Detect click on HTML button through javascript in Android WebView
You have to validate that the click is in fact on a link to a new page. You can find the clicked HTML element via WebView's HitTestResult class. This answer on SO gives you the details on how to validate the HitTestResult value:
Get the click event from webpage in my android application
You start your animation from your onClick() method and end it from your WebViewClient's onPageFinished() method and, in case the new page doesn't load, also in onReceivedError().
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With