2012-05-08 6 views
8

Mam MenuItem w mojej ActionBar, która jest ikoną "przeładowania". Moje Activity ma WebView i chciałbym, aby ikona zaczęła animować, gdy WebView rozpoczyna ładowanie strony internetowej i zatrzymuje się po jej zakończeniu. Obejmuje to kliknięcie na linki w załadowanej witrynie. To, co mam do tej pory, działa pierwszy raz przywołać stronę internetową, ale jeśli mogę zostawić Activity i załadować inną stronę internetową, ikona „reload” wydaje się podwoić, czy będę się NullReference wyjątek rzucony na refreshItem.setActionView(ivRefresh);Rozpocznij animację po wczytaniu strony, zatrzymaj na stronie załadowanej

enter image description here

Oto mój kod:

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); 
    } 
} 

zakomentowanym kod jest różne sposoby próbowałem zmusić go do pracy.

UPDATE:

Po debugowania tym bardziej, umieścić punkt przerwania w funkcji StartAnimation i czasami to trafić do 7 razy z rzędu, a innym razem nie. To nie ma sensu, ponieważ dla mnie powinno to działać. Kłopotliwy ...

ROZWIĄZANIE (rodzaj):

Aktualizacja funkcji StartAnimation() do tego, wydaje się rozwiązać ten problem, ale wydaje się bardziej roztworu taśmą klejącą:

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); 
    } 
} 
+0

Czy to działa? w jaki sposób? – Ronnie

+0

Dodałem moje rozwiązanie do PO. Sprawdzanie, czy jest to wartość pusta lub nie rozwiązało problemu. –

+0

Czy próbowałeś uczynić animację jako członka swojej klasy? – Ronnie

Odpowiedz

2

Aby uzyskać płynne wrażenia z ui, animacja "ładującego się koła" powinna zacząć się, gdy użytkownik kliknie link - a nie kiedy nowa strona rozpocznie ładowanie - i kończy się po załadowaniu nowej strony. To sprawia, że ​​aplikacja wydaje się bardziej responsywna dla użytkownika i jest przykładem zachowania zaimplementowanego w Dolphin Browser.

Aby to zaimplementować, musisz posłuchać kliknięć linków użytkownika w WebView. Jak zrobić to już zostało omówione w tej odpowiedzi tutaj na SO:

Detect click on HTML button through javascript in Android WebView

Musisz potwierdzić, że w rzeczywistości jest kliknięcie na link do nowej strony. Kliknięty element HTML można znaleźć za pośrednictwem klasy WebView o nazwie HitTestResult. To odpowiedź na SO daje szczegóły dotyczące sposobu sprawdzania wartości HitTestResult:

Get the click event from webpage in my android application

uruchomieniu animacji z metodą swojej onClick(), a zakończyć go z metodą Twojego WebViewClient za onPageFinished() oraz, w przypadku gdy nowa strona nie ładuje się, również w onReceivedError().

+0

Ok, dobrze, gładkie doświadczenie ui na bok, wciąż jestem zdezorientowany, dlaczego uruchomienie animacji w 'onPageStarted' i zatrzymanie jej w' onPageFinished' nie działa? –

0

Zmodyfikuj zmienną Animation jako członka klasy Browser i zatrzymaj animację przed zakończeniem działania.

0

Możesz użyć pojęcia wątków.

Do momentu załadowania adresu URL w widoku sieci Web wyświetlana jest animacja ładowania , a po załadowaniu adresu URL zatrzymaj animację.

Należy użyć dwóch wątków, jednego dla wskaźnika postępu (tj. Ładowania adresu URL) i innego wątku interfejsu użytkownika dla animacji.

Wyszukaj!