简体   繁体   中英

Android ProgressBar disappears

I have an android ProgressBar which is indeterminate so it is simply a revolving circle animation.

It starts off displaying fine, but after I set the visibility of its parent ( overlayLayout ) to either gone or invisible and then set it back to visible later on, the progress bar is unseen?

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/overlayLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff"
    android:gravity="center" >
    <TextView
        android:text=""
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:layout_width="match_parent"
        android:textAlignment="center"
        android:layout_margin="10dp"
        android:layout_height="wrap_content"
        android:id="@+id/overlayLabelText" />
  <ProgressBar
      android:id="@+id/overlayProgressBar"
      android:layout_below="@id/overlayLabelText"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:foregroundGravity="center"
      android:indeterminate="true" />
</RelativeLayout>

EDIT: I'm unsure if the view is included but the progress bar is just not rendered or whether the ProgressBar view itself is completely excluded as I can't access the UI view hierarchy.

So far I have tried:

    ProgressBar.Enabled = true;
    ProgressBar.ForceLayout();
    ProgressBar.Invalidate();
    ProgressBar.SetProgress(0, true);
    ProgressBar.Visibility = ViewStates.Visible;

But have had no breakthroughs yet.

EDIT 2: Thankyou everyone for your help so far. I have switched to creating the layout programatically - this is my full code:

overlay = new RelativeLayout(mainActivity)
{
    LayoutParameters = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent)
};
overlay.SetBackgroundColor(Color.WhiteSmoke);
overlay.SetGravity(GravityFlags.Center);
description = new TextView(mainActivity)
{
    LayoutParameters = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.WrapContent),
    Gravity = GravityFlags.Center,
    TextSize = 18,
    Id = 1523112
};
description.Text = "Waiting for GPS";
description.SetBackgroundColor(Color.Aqua);
progressBar = new ProgressBar(mainActivity)
{
    Indeterminate = true,
};
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.WrapContent);
lp.AddRule(LayoutRules.Below, description.Id);
progressBar.LayoutParameters = lp;
progressBar.SetBackgroundColor(Color.Red);

container.AddView(overlay);
overlay.AddView(description);
overlay.AddView(progressBar);

With the two hiding and showing methods:

private void OnGpsUpdate()
{
    overlay.Visibility = ViewStates.Gone;
}

private void NoGPS()
{
    description.Text = "Waiting for GPS";
    overlay.Visibility = ViewStates.Visible;
}

When the layout is first rendered, before its hidden for the first time:
(I screenshotted at a bad time, but blue drawing shows where the circle is moving around its loading animation) 在此输入图像描述

After its been hidden and shown again, the progressBar loading view is there but there's no loading circle anymore:

在此输入图像描述

I am starting to think it may just be a problem with my android emulator? Nope, same problem when testing on my physical phone. Text view still shows fine, its just the progress bar doesnt show?

SOLUTION I don't fully understand it, seeing as everything else seemed to work except the progressBar, but a solution came from wrapping my visibility calls in a RunOnUIThread() call.

Few points

Based on how the problem was described, there is a need for you to show the code snippet you used for hiding/showing the overlayLayout

Recommendations

If you're only concerned with how the progress bar should behave in terms of hiding/showing, there's no need for this snippet:

ProgressBar.Enabled = true;
ProgressBar.ForceLayout();
ProgressBar.Invalidate();
ProgressBar.SetProgress(0, true);
ProgressBar.Visibility = ViewStates.Visible;

You just need to control the root layout which has the id of overlayLayout

private RelativeLayout overlayLayout;

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

    // Instantiate the layout
    overlayLayout = findViewById(R.id.overlayLayout);

    // Do the logic how you inflate/show the layout
    ... 

    // Hide the overlay layout
    overlayLayout.setVisibility(View.GONE);

    // Show the overlay layout
    overlayLayout.setVisibility(View.VISIBLE);
}

Decide on the visibility value, for this scenario, I'd recommend View.GONE rather than View.INVISIBLE

Read more on:

I wrote a demo based on your code. And to test it, I added a button to control the show and hide of the layout. You may try this:

protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            // Set our view from the "main" layout resource
            SetContentView(Resource.Layout.activity_main);
            // Instantiate the layout
            overlayLayout =  FindViewById<LinearLayout>(Resource.Id.overlayLayout);
            progressBar =  FindViewById<ProgressBar>(Resource.Id.overlayProgressBar);
            description = FindViewById<TextView>(Resource.Id.textView1);
            description.Text = "Waiting for GPS";
            description.SetBackgroundColor(Color.Aqua);
            progressBar.SetBackgroundColor(Color.Red);

            switchBtn = FindViewById<Button>(Resource.Id.switchButton);

            switchBtn.Click += SwitchBtn_Click;
            overlayLayout.Visibility = Android.Views.ViewStates.Visible;
            isShown = true;
        }

        private void SwitchBtn_Click(object sender, System.EventArgs e)
        {
            if (isShown)
            {
                overlayLayout.Visibility = Android.Views.ViewStates.Gone;
                isShown = false;
                switchBtn.Text = "Show";
            }
            else {
                overlayLayout.Visibility = Android.Views.ViewStates.Visible;
                isShown = true;
                switchBtn.Text = "Hide";
            }

You can download the demo from this

The solution was to add a RunOnUIThread like so:

private void OnNewGPS()
{
    mainActivity.RunOnUiThread(() =>
    {
        overlay.Visibility = ViewStates.Gone;     });
}

private void NoGPS()
{
    mainActivity.RunOnUiThread(() =>
    {
        overlay.Visibility = ViewStates.Visible;
    });
}

Where mainActivity is a reference to the Activity the views are running in.

to hide layout:

findViewById(R.id.overlayLayout).setVisibility(View.GONE);

to display it again :

findViewById(R.id.overlayLayout).setVisibility(View.VISIBLE);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM