web-dev-qa-db-fra.com

Android: la barre de progression dans le titre de la fenêtre ne s'affiche pas

J'ai une vue Web pour remplacer le navigateur intégré et je veux afficher un indicateur de progression dans la barre de titre.

Voici le code:

    @Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getWindow().requestFeature(Window.FEATURE_PROGRESS);

    setContentView(R.layout.browser);
    currentURL = BrowserActivity.this.getIntent().getExtras().getString("currentURL");

    try {
        mWebView = (WebView) findViewById(R.id.webview);
        mWebView.getSettings().setJavaScriptEnabled(true);
        mWebView.setWebViewClient(new browserActivityClient());
        setProgressBarIndeterminateVisibility(true);
        mWebView.loadUrl(currentURL);
        setProgressBarIndeterminateVisibility(false);
    } catch (Exception e) {
        Log.e(getClass().getSimpleName(), "Browser: " + e.getMessage());
        Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
    } 
}

Cela devrait fonctionner, je pense, selon Android docs et autres exemples que j'ai vus sur le net. Mais ce n'est pas le cas, pourriez-vous s'il vous plaît me dire où je me trompe?

Et une autre question: si parfois plus tard, je choisirai de déclarer Android:theme="@Android:style/Theme.NoTitleBar" dans le manifeste de l'application, la barre de progression s'affichera-t-elle ou non?

Je vous remercie.

34
Manu

En fait, le bon code est (testé et fonctionne):

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
    requestWindowFeature(Window.FEATURE_PROGRESS);
    currentURL = BrowserActivity.this.getIntent().getExtras().getString("currentURL");

    setContentView(R.layout.browser);

    setProgressBarIndeterminateVisibility(true);
    setProgressBarVisibility(true);

    try {
        mWebView = (WebView) findViewById(R.id.webview);
        mWebView.getSettings().setJavaScriptEnabled(true);
        mWebView.setWebViewClient(new browserActivityClient());

        mWebView.setWebChromeClient(new WebChromeClient() {
           public void onProgressChanged(WebView view, int progress) {
               setProgress(progress * 100);
              if(progress == 100) {
                 setProgressBarIndeterminateVisibility(false);
                 setProgressBarVisibility(false);
              }
           }
        });
        mWebView.loadUrl(currentURL);
    } catch (Exception e) {
        Log.e(getClass().getSimpleName(), "Browser: " + e.getMessage());
        Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
    } 
}
47
Manu

J'ai aussi le même problème.

Parce que j'ai défini le Android: theme = "@ Android: style/Theme.NoTitleBar"

Je le résous en ajoutant un ProgressBar dans le fichier xml de mise en page, tel que:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"  
Android:orientation="vertical"  
Android:layout_width="fill_parent"  
Android:layout_height="fill_parent"  
>

<ProgressBar Android:id="@+id/progressbar"
    style="?android:attr/progressBarStyleHorizontal"
    Android:layout_width="fill_parent"
    Android:layout_height="3px"
    Android:max="100"
    Android:visibility="gone"
/>

<WebView   
    Android:id="@+id/webview"  
    Android:layout_width="fill_parent"  
    Android:layout_height="fill_parent"  
/>  

</LinearLayout>

Dans le code:

// lors du chargement de l'url

progressBar.setProgress(0);
progressBar.setVisible(View.VISIBLE);

...

// chargement ... progression modifiée

progressBar.setProgress(progress);

...

// à la fin de la page

progressBar.setVisible(View.GONE);

C'est fini!

16
univasity

J'ai résolu le problème.

Votre appel à setProgressBarVisibility() doit être dans onStart() ou onResume() car, avant ce point, il semble que vous n'êtes pas assuré d'avoir une vue sur laquelle vous pouvez modifier un visibilité.


Pour cette solution incroyable de Dralangus, voici un code de production entièrement testé. Merci beaucoup, Dralangus! Enfin, un spinner qui ne s'en va pas lors de la rotation de l'appareil.

public class MainActivity extends Activity
{
private static boolean showSpinner; // needs static

public void spinnerOn()
    {
    showSpinner = true;
    setProgressBarIndeterminateVisibility(true);
    }

public void spinnerOff()
    {
    showSpinner = false;
    setProgressBarIndeterminateVisibility(false);
    }

protected void onResume()
    {
    // solved by Dralangus http://stackoverflow.com/a/7414659/294884
    super.onResume();
    if (showSpinner)
        {
        spinnerOn();
        }
    else
        {
        spinnerOff();
        }
    }

protected void onStart()
    {
    super.onStart();
    // note, onResume is called EVEN LATER than onStart,
    // so your most reliable choice is onResume.
    // eternal thanks to Dralangus for this solution
    }

@Override
protected void onCreate(Bundle savedInstanceState)
    {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);

    setContentView(R.layout.activity_main);

    ... // Your code
    }
10
Dralangus

Voyant comment certaines réponses mélangent les deux barres de progression, a décidé d'ajouter une autre réponse

Ce sont pour la barre de progression horizontale en haut

requestWindowFeature(Window.FEATURE_PROGRESS);
setProgressBarIndeterminate(true);
setProgress(intVal);
setProgressBarVisibility(true);

ce sont pour la barre de progression de style spinner dans la barre d'action

requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setProgressBarIndeterminateVisibility(true);

Vous n'avez pas besoin de demander les deux fonctionnalités de la fenêtre, juste celle du type de progression dont vous avez besoin.

L'erreur dans le code OP est de caler setProgressBarIndeterminateVisibility(true) n'ayant pas demandé Window.FEATURE_INDETERMINATE_PROGRESS (Ou vice versa: appeler setProgressBarIndeterminateVisibility() au lieu de setProgressBarVisibility())

8
Ivan Bartsov

Il semble qu'avec Android 5.0 (API 21) et au-dessus Windows.FEATURE_PROGRESS ne fonctionne plus. En prenant quelques indices de la réponse par univasité, j'ai pu construire une barre de progression similaire à celles des autres navigateurs.

activity_main.xml "

<FrameLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:tools="http://schemas.Android.com/tools"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
tools:context=".MainActivity"
Android:id="@+id/relativeLayout">

<WebView
    Android:layout_width="fill_parent"
    Android:layout_height="fill_parent"
    Android:id="@+id/webView" />

<ProgressBar
    Android:id="@+id/progressBar"
    style="?android:attr/progressBarStyleHorizontal"
    Android:layout_width="fill_parent"
    Android:layout_height="8dp"
    Android:max="100"
    Android:progressTint="#FF29A8FF"
    Android:progressBackgroundTint="#FFFFFFFF"
    Android:visibility="gone" />
</FrameLayout>

FrameLayout permet à la barre de progression de flotter au-dessus de la vue Web. Réglage Android:max à 100 l'aligne sur la plage par défaut de l'activité, de sorte que les valeurs n'ont pas à être converties à la valeur par défaut 0-10000, sinon utilisée par la barre de progression. Android:visibility="gone" rend la barre de progression invisible par défaut.

MainActivty.Java:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Get the WebView and the ProgressBar from activity_main.xml.
    final WebView mainWebView = (WebView) findViewById(R.id.webView);
    final ProgressBar progressBar = (ProgressBar) findViewById(R.id.progressBar);

    // Enables JavaScript.
    mainWebView.getSettings().setJavaScriptEnabled(true);

    // Updates the progress bar whenever there are changes and hides it again when it completes.
    mainWebView.setWebChromeClient(new WebChromeClient() {
        public void onProgressChanged(WebView view, int progress) {
            if (progress < 100) {
                    progressBar.setVisibility(View.VISIBLE);
                } else {
                    progressBar.setVisibility(View.GONE);
                }
            progressBar.setProgress(progress);
        }
    });

    // Makes the mainWebView handle all URLs internally instead of calling the default browser.
    mainWebView.setWebViewClient(new WebViewClient());

    // Load a sample URL.
    mainWebView.loadUrl("http://developer.Android.com/");
}
7
Soren Stoutner

WebView.loadUrl est exécuté dans un thread natif, donc setProgressBarIndeterminateVisibility (false) est appelé immédiatement à peu près. De plus, si vous utilisez Theme.NoTitleBar, la barre de titre ne sera pas affichée et puisque la barre de progression est dans la barre de titre, elle ne sera pas non plus affichée.

Quelque chose comme ça devrait fonctionner.

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getWindow().requestFeature(Window.FEATURE_PROGRESS);

    setContentView(R.layout.browser);
    currentURL = BrowserActivity.this.getIntent().getExtras().getString("currentURL");

    try {
        mWebView = (WebView) findViewById(R.id.webview);
        mWebView.getSettings().setJavaScriptEnabled(true);
        mWebView.setWebViewClient(new browserActivityClient());
        setProgressBarIndeterminateVisibility(true);
        mWebview.setWebChromeClient(new WebChromeClient() {
           public void onProgressChanged(WebView view, int progress) {
              if(progress == 100) {
                 setProgressBarIndeterminateVisibility(false);
              }
           }
        });
        mWebView.loadUrl(currentURL);
    } catch (Exception e) {
        Log.e(getClass().getSimpleName(), "Browser: " + e.getMessage());
        Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
    } 
}
3
Robby Pond