Android:窗口标题中的进度条不显示

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3092291/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 08:39:38  来源:igfitidea点击:

Android: The progress bar in the window's title does not display

androidprogress-bartitlebar

提问by Manu

I have a web view to override the built-in browser and I want to show a progress indicator on the title bar.

我有一个 web 视图来覆盖内置浏览器,我想在标题栏上显示一个进度指示器。

This is the 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();
    } 
}

It should work, I think, according to Android docs and other samples I saw on the net. But it doesn't, could you please tell me where am I wrong?

根据我在网上看到的 Android 文档和其他示例,我认为它应该可以工作。但它没有,你能告诉我我哪里错了吗?

And another question: if sometimes later I'll choose to declare android:theme="@android:style/Theme.NoTitleBar"in the application manifest, will the progress bar show anymore or not?

还有一个问题:如果以后有时我会选择android:theme="@android:style/Theme.NoTitleBar"在应用程序清单中声明,进度条会不会再显示?

Thank you.

谢谢你。

回答by Manu

In fact the correct code is (tested and working):

事实上,正确的代码是(经过测试和工作):

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

回答by univasity

I got the same problem too.

我也遇到了同样的问题。

Because i set the android:theme="@android:style/Theme.NoTitleBar"

因为我设置了android:theme="@android:style/Theme.NoTitleBar"

I solve it by add a ProgressBar in the layout xml file, such as:

我是通过在layout xml文件中添加一个ProgressBar来解决的,比如:

<?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>

In code:

在代码中:

// when load url

// 加载 url 时

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

...

...

// loading...progress changed

// 加载...进度已更改

progressBar.setProgress(progress);

...

...

// when page finish

// 当页面完成时

progressBar.setVisible(View.GONE);

C'est finish!

C'est完成!

回答by Dralangus

I have solved the issue.

我已经解决了这个问题。

Your call to setProgressBarVisibility()must be in onStart()or onResume()because, before that point, it seems you are not guaranteed to have any view on which you can change a visibility.

setProgressBarVisibility()必须调用 to ,onStart()或者onResume()因为在此之前,似乎不能保证您有任何可以更改可见性的视图。



For this incredible solution by Dralangus, here's some fully tested production code. Thank you so much, Dralangus! Finally, a spinner that does not go away upon device rotation.

对于 Dralangus 的这个令人难以置信的解决方案,这里有一些经过全面测试的生产代码。非常感谢,德拉兰古斯!最后,在设备旋转时不会消失的微调器。

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
    }

回答by Ivan Bartsov

Seeing how some answers mix up the two progress bars, decided to add another answer

看到一些答案如何混淆了两个进度条,决定添加另一个答案

These are for the horizontal progress bar at the top

这些用于顶部的水平进度条

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

these are for the spinner-style progress bar in the actionbar

这些用于操作栏中的微调样式进度条

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

You don't need to request both window features, just the one for the progress type you need.

您不需要请求这两种窗口功能,只需请求您需要的进度类型之一即可。

The mistake in OP's code is caling setProgressBarIndeterminateVisibility(true)having not requested Window.FEATURE_INDETERMINATE_PROGRESS(or vice versa: calling setProgressBarIndeterminateVisibility()instead of setProgressBarVisibility())

OP 代码中的错误是 calingsetProgressBarIndeterminateVisibility(true)没有请求Window.FEATURE_INDETERMINATE_PROGRESS(反之亦然:调用setProgressBarIndeterminateVisibility()而不是setProgressBarVisibility()

回答by Soren Stoutner

It appears that with Android 5.0 (API 21) and above Windows.FEATURE_PROGRESSno longer works. Taking some hints from the response by univasity, I was able to build a progress bar similar to those in other browsers.

看来,Android 5.0 (API 21) 及更高版本Windows.FEATURE_PROGRESS不再有效。从 univasity 的响应中得到一些提示,我能够构建一个类似于其他浏览器中的进度条。

activity_main.xml"

活动_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>

The FrameLayoutallows the progress bar to float above the webview. Setting android:maxto 100 makes it align with the default range in the activity, so the values don't have to be converted to the default of 0-10000 otherwise used by the progress bar. android:visibility="gone"makes the progress bar invisible by default.

FrameLayout允许浮在网页视图上方的进度条。设置android:max为 100 使其与活动中的默认范围对齐,因此这些值不必转换为默认值 0-10000,否则进度条会使用这些值。 android:visibility="gone"默认情况下使进度条不可见。

MainActivty.java:

主活动.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/");
}

回答by Robby Pond

WebView.loadUrl is run in a native thread so setProgressBarIndeterminateVisibility(false) gets called immediately pretty much. Also if you use Theme.NoTitleBar the title bar will not be shown and since the progress bar is in the title bar it won't be shown either.

WebView.loadUrl 在本机线程中运行,因此 setProgressBarIndeterminateVisibility(false) 几乎立即被调用。此外,如果您使用 Theme.NoTitleBar,则不会显示标题栏,并且由于进度条位于标题栏中,因此也不会显示。

Something like this should work.

像这样的事情应该有效。

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