The Nomad
The Nomad

Reputation: 7425

Android View.isShown() is returning false when the View is showing

I have a TextView named tvCallToActionBanner that is shown depending on certain events. This method below controls whether said TextView gets shown. This method gets called in the Activity's onResume() and a couple of other methods call it as well.

public void showCallToActionBanner() {
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            if (!mPrefs.getCurrentLiveGameDateId().isEmpty()) {
                mPrefs.setCallToActionType(GlobalVars.CTA_IN_GAME);
                tvCallToActionBanner.setText(R.string.cta_game_in_progress);
                if (!tvCallToActionBanner.isShown()) showCallToActionBanner(true);
            }
            else if (mPrefs.getLiveGameDateStatus().equals(GlobalVars.LIVE_GAME_DATE_SEARCHING)) {
                mPrefs.setCallToActionType(GlobalVars.CTA_LIVE_GAME_DATE_SEARCHING);
                tvCallToActionBanner.setText(R.string.cta_live_game_date_searching);
                if (!tvCallToActionBanner.isShown()) showCallToActionBanner(true);
            }
            else if (!mPrefs.getUnratedGameDateIds().isEmpty()) {
                mPrefs.setCallToActionType(GlobalVars.CTA_RATE_MATCH);
                mPrefs.setCallToActionId(mPrefs.getUnratedGameDateIds().iterator().next());
                tvCallToActionBanner.setText(R.string.cta_unrated_match);
                if (!tvCallToActionBanner.isShown()) showCallToActionBanner(true);
            }
            else if (tvCallToActionBanner.isShown()) {
                showCallToActionBanner(false);
            }
        }
    });
}

public void showCallToActionBanner(final boolean shouldShow) {
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            if (shouldShow) {
                Animation enterAnim = AnimationUtils.loadAnimation(MainActivity.this, R.anim
                        .banner_slide_down);
                enterAnim.setAnimationListener(new Animation.AnimationListener() {
                    @Override
                    public void onAnimationStart(Animation animation) {
                    }

                    @Override
                    public void onAnimationEnd(Animation animation) {
                        int paddingTop = (int) getResources().getDimension(R.dimen
                                .main_container_top_spacing_for_banner);
                        mainContainer.setPadding(0, paddingTop, 0, 0);
                    }

                    @Override
                    public void onAnimationRepeat(Animation animation) {
                    }
                });

                tvCallToActionBanner.startAnimation(enterAnim);
                tvCallToActionBanner.setVisibility(View.VISIBLE);
            }
            else {
                Animation exitAnim = AnimationUtils.loadAnimation(MainActivity.this, R.anim
                        .banner_slide_up);
                exitAnim.setAnimationListener(new Animation.AnimationListener() {
                    @Override
                    public void onAnimationStart(Animation animation) {
                    }

                    @Override
                    public void onAnimationEnd(Animation animation) {
                        mainContainer.setPadding(0, 0, 0, 0);
                    }

                    @Override
                    public void onAnimationRepeat(Animation animation) {
                    }
                });

                tvCallToActionBanner.startAnimation(exitAnim);
                tvCallToActionBanner.setVisibility(View.GONE);
            }
        }
    });
}

So when I trigger the tvCallToActionBanner to show in Activity A, it shows with no issues.

I create Activity B, and the onResume() gets called and it shows it with no problems.

And then I create Activity C, onResume() gets called and shows tvCallToActionBanner. I call a method which now hides tvCallToActionBanner and it hides with no issues.

I press the back button and it goes back to Activity B, which calls the onResume() and should be hiding the tvCallToActionBanner but it isn't.

I checked the tvCallToActionBanner.isShown() and it is returning false in Activity B after I press the back button from C. But the view is clearly showing and should be returning true.

Is it because the way the order of the Views are drawn? I have tried to move the method call to onPostResume() but that did nothing. How do I get the tvCallToActionBanner.isShown() to return true when it is showing?

Upvotes: 2

Views: 5296

Answers (3)

    textview.viewTreeObserver.addOnGlobalLayoutListener {
        Toast.makeText(this,"layout changed "
                +textview.isShown
            ,Toast.LENGTH_LONG)
            .show()

        Toast.makeText(this,"visible "+
                (textView.visibility==View.VISIBLE)
            ,Toast.LENGTH_LONG)
            .show()

    }

Upvotes: 0

Mark P.
Mark P.

Reputation: 56

isShown() checks also the visibility of its ancestors - so the view itself could be visible but one of its parents isn't (@see here)

Upvotes: 2

Sergey Shustikov
Sergey Shustikov

Reputation: 15821

Just use a View.getVisibility() method.

if(textView.getVisibility == View.VISIBLE) {
    // do stuff
}   

Upvotes: 2

Related Questions