2

Splash

I have main activity UI startup operations that take between 5-10 seconds (that need to be handled on the main UI thread) - so I would like to use a splash screen rather than the default black or non-responsive main UI.

A good solution to the splash screen is provided below

  • which is to first set setContentView(R.layout.splash),
  • then do the necessary main UI processing (on UI thread but with main view that is not visible)
  • and when that is ready show setContentView(R.layout.main)

Android Splash Screen before black screen


Splash with Fragments

I'm also using fragments, which normally require setContentView(R.layout.main) to be called before fragment instantiation - so that the fragment manager could find the view stubs in R.layout.main to inflate the fragments into (strictly speaking view stubs are a different thing).

  • But I cannot call setContentView(R.layout.main) before creating the fragments, because that replaces the splash screen with the (not-yet-ready) main screen.
  • My fear is that what I want to do cannot be done?
  • Unfortunately, there is no overload like fragmentTransaction.add(viewNotViewId, fragment);

Almost-Answer

Here's all but the key, which is that setContentView is called before the fragment transactions: How do I add a Fragment to an Activity with a programmatically created content view

Community
  • 1
  • 1
Cel
  • 6,467
  • 8
  • 75
  • 110
  • Just out of curiousity: what exactly is it you think you really need to do on the UI thread that may take up to 10 seconds? This is definitely ANR prone and bad for user experience. Adding a splash screen will not suddenly make your app 'responsive' if you don't move the heavy lifting into the background. – MH. Jul 02 '12 at 19:23
  • @MH maybe it is closer to 5 seconds, because i dont see ANR, but the wait is still too long for the user to stare at a blank; the ui is rather custom made out of a lot of data-bound view objects (that once instantiated perform fine) – Cel Jul 02 '12 at 19:36

2 Answers2

1

Try this code without calling any setContentView

fragmentTransaction.add(android.R.id.content, Fragment.instantiate(MainActivity.this, SplashFragment.class.getName()));

The main approach here is placing fragment in view with id android.R.id.content which is always present before any layout is inflated via setContentView

vasart
  • 6,692
  • 38
  • 39
  • the trouble is i have not one but multiple fragments that will occupy different placeholders within the same main layout (at least on tablets where there is more screen estate).. – Cel Jul 03 '12 at 08:54
1

You could try replacing your fragments in your FragmentActivity, here is the idea partially coded: Suppose you have your fragments layout like this (main.xml):

<LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal">

    <LinearLayout android:id="@+id/waiting" ...>
    </LinearLayout>

    <!-- hidden layout -->
    <LinearLayout>
        <LinearLayout android:id="@+id/layout_list_items" ...>
        </LinearLayout>
        <LinearLayout android:id="@+id/layout_detail" ...>
        </LinearLayout>
    </LinearLayout>

</LinearLayout>

And your FragmentActivity like this:

public class FragmentsActivity extends FragmentActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        this.setContentView(R.layout.main);

        Fragment fragA = new WaitingTransaction();

        FragmentTransaction fragTrans = this.getSupportFragmentManager().beginTransaction();
        fragTrans.add(R.main.waiting, fragA);
        fragTrans.commit();
    }

    private void afterProcessing(){

                //show hidden layout and make the waiting hidden through visibility, then add the fragment bellow...
        FragmentTransaction fragTrans = this.getSupportFragmentManager().beginTransaction();
        fragTrans.add(R.main.layout_list_items,
                          new FragmentList());
        fragTrans.replace(R.main.layout_detail,
                          new FragmentB());
        fragTrans.commit();
    }

}
StarsSky
  • 6,721
  • 6
  • 38
  • 63
mrcaramori
  • 2,503
  • 4
  • 29
  • 47
  • im not sure if i understood correctly, but i now used `setContentView(R.layout.main)` from the start but embedded the splash (visibly) into the main layout while keeping the fragment placeholders hidden - and when the fragments were all ready, i hid the splash layout and set the fragment layouts as visible - worked a treat! – Cel Jul 03 '12 at 08:57
  • @Cel that's right. you could either replace the fragment in the same container, or use different containers like the answer (which in this case would be more clear to understand). – mrcaramori Jul 03 '12 at 11:46