Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
I am perplexed by how Fragment.isVisible() is supposed to work. Even though I have a fragment added in
Activity.create()
,
Fragment.isVisible()
returns false even when
FragmentManager.commitNow()
is used.
Fragment.isVisible()
returns false even in
onResume()
. However, when a UI button gets clicked the returned value is correct.
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
public final static String TAG = "HideFragmentOnChange";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
((Button)findViewById(R.id.my_button)).setOnClickListener(this);
if(savedInstanceState == null){
Fragment fragmentA = new FragmentA();
Log.d(TAG, "onCreate: Before FragmentTransaction FragA: " + (fragmentA.isVisible() ? "visible" : "not visible"));
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, fragmentA, "fragA")
.commitNow();
Log.d(TAG, "onCreate: After FragmentTransaction FragA: " + (fragmentA.isVisible() ? "visible" : "not visible"));
this.runOnUiThread(new Runnable(){
@Override
public void run() {
Fragment fragA = getSupportFragmentManager().findFragmentByTag("fragA");
Log.d(TAG, "runOnUiThread after onCreate(): FragA: " + (fragA.isVisible() ? "visible" : "not visible"));
@Override
protected void onResume() {
super.onResume();
Fragment fragA = getSupportFragmentManager().findFragmentByTag("fragA");
Log.d(TAG, "onResume: FragA: " + (fragA.isVisible() ? "visible" : "not visible"));
this.runOnUiThread(new Runnable(){
@Override
public void run() {
Fragment fragA = getSupportFragmentManager().findFragmentByTag("fragA");
Log.d(TAG, "runOnUiThread after onResume(): FragA: " + (fragA.isVisible() ? "visible" : "not visible"));
@Override
public void onClick(View v) {
Fragment fragmentA = getSupportFragmentManager().findFragmentByTag("fragA");
Log.d(TAG, "onClick(): FragA: " + (fragmentA.isVisible() ? "visible" : "not visible"));
I initially thought that perhaps it is because the main thread has not had the chance to run yet and the FragmentTransaction
does not fully and properly commit until a later point. However, calling runOnUiThread
does not change the return value of isVisible()
.
I am attaching the log for reference.
03-15 17:22:34.978 14094-14094/ D/HideFragmentOnChange: onCreate: Before FragmentTransaction FragA: not visible
03-15 17:22:34.990 14094-14094/ D/HideFragmentOnChange: onCreate: After FragmentTransaction FragA: not visible
03-15 17:22:34.991 14094-14094/ D/HideFragmentOnChange: runOnUiThread after onCreate(): FragA: not visible
03-15 17:22:34.996 14094-14094/ D/HideFragmentOnChange: onResume: FragA: not visible
03-15 17:22:34.996 14094-14094/ D/HideFragmentOnChange: runOnUiThread after onResume(): FragA: not visible
03-15 17:22:56.683 14094-14094/ D/HideFragmentOnChange: onClick(): FragA: visible
Why does Fragment.isVisible()
seem to return the correct value with such a big delay?
I am using support library 25.2 and support library Fragments although native fragments produced the same behavior.
You can find more information in official document.
It gives "true" when fragment is visible to user and "false" when it is invisible.
Enjoy!
Set a hint to the system about whether this fragment's UI is currently
visible to the user. This hint defaults to true and is persistent
across fragment instance state save and restore.
To use it:
private static boolean isVisible;
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
isVisible = isVisibleToUser;
if (isVisible) {
Log.d("TAG", "this fragment is visible");
} else {
Log.d("TAG", "this fragment is invisible");
You have to keep in mind that the Fragment also has his own lifecycle. You are basically calling it way too early. A Fragment is deemed visible if
Fragment#isVisible
Return true if the fragment is currently visible to the user. This means it: (1) has been added, (2) has its view attached to the window, and (3) is not hidden.
See this SO post about the lifecycle of the Activity/Fragment
When is onAttach called during the Fragment LifeCycle?
I noticed that on opening a fragment and going through all the lifecycle
(onAttach, onCreate, onStart etc..), calling isVisible() from onResume() will return false. However, if you only stop the fragment (i.e pressing the home button), isVisible() will return true.
Conclusion: Keep a class boolean flag:
private mFirstTimeVisible = true;
and use it in the following onResume check:
@Override
public void onResume() {
super.onResume();
if (mFistTimeVisible || isVisible()) {
//your code...
mFistTimeVisible = false;
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.