Android - Activity onCreate and Fragment onCreate
Asked Answered
M

2

7

I'm still new to Android programming, so this question is rather basic. I see lots of code samples on the Internet where UI components, like a TextView, are being initialised and accessed in the onCreate() method of an Activity.

When I use Android Studio to create a new project - FirstApp - with default settings, a blank Activity called MainActivity bringing along with it activity_main and fragment_main, I can immediately compile this into an APK, deploy it on my device, and I get a screen with a header "FirstApp" and a TextView in the top left showing "Hello world!".

If I give the TextView an ID of textview1, and create a member variable, TextView myTextView;, then I can reference it in the onCreate() method of the Activity, like so (no compiler errors, of course):

    @Override
    protected void onCreate (Bundle savedInstanceState)
    {
        super.onCreate (savedInstanceState);
        setContentView (R.layout.activity_main);
        myTextView = (TextView) findViewById (R.id.textview1);
        myTextView.setText ("Hello tablet!");

        if (savedInstanceState == null)
        {
            getSupportFragmentManager().beginTransaction().add (R.id.container,new PlaceholderFragment()).commit();
        }
    }

However, if I compile and run the APK it results in an "Unfortunately, FirstApp has stopped." message.

I have previously got around this issue by moving startup code that accesses UI components into the onStart() method of the Activity, like so:

    @Override
    protected void onStart()
    {
        super.onStart();
        myTextView = (TextView) findViewById (R.id.textview1);
        myTextView.setText ("Hello tablet!");
    }

Which would result in a working APK with a single TextView in the top left showing "Hello tablet!" - my simple questions are two-fold...

  1. If the project uses Fragments then should I fully expect that the UI components cannot be accessed in the onCreate() method of the Activity, as I see happening with lots of sample code on the Internet, probably because they've not been created yet?
  2. Is it acceptable for me to be accessing UI components within the onStart() method of the Activity (which does work) - or should I be doing something else? Previously I have also used the onCreateView method of the Fragment, but is the best place to access UI components inside a Fragment actually in the onCreate() method of the Fragment, which I have not yet tried?

I also note that the onCreate() method of the default Fragment Android Studio creates for you when you create a new project does not have a stub provided... but onCreateView does, and the lifecycle documentation implies (to me, anyway) that this might be the best place to be doing things like this.

Any guidance on this is appreciated.

Marge answered 14/2, 2014 at 11:23 Comment(3)
When it crashed, get the Logcat Stacktrace so we can see where the error lies. Also is myTextView being setup somewhere else ie TextView myTextView;?Neckpiece
You should read about fragments in general. 1. The fragment's view is not yet available there(it's not a simple view that you add to the layout) 2. You can access the views from what callback you want(onCreate() is generally preferred). The problem is that you try to access the fragment's view which you should avoid and instead let the fragment handle this on its own.Nonaligned
@Tom Hart - yes, TextView myTextView; is included as a member variable. Is your response implying that you think this UI component should be perfectly accessible in the onCreate() method of the Activity itself?Marge
F
7

The fragment transaction commit command only puts the transaction in Que - the transaction will be processed some time in the future. This is why you couldnt use it straight from on create.

I suggest you to use fragments to encapsulate their Ui behavior - I wouldn't change a fragment's Ui elements explicitly from the activity.

OnCreateView inside a fragment is a good place to init the fragment's Ui elements since it is called when the fragment view is created.

Working with fragments is quite tricky and painful at start but From my experiance they do help to create a much more modular code.

I suggest you read more about fragments in the docs before starting a serious project with them. http://developer.android.com/guide/components/fragments.html

Fluent answered 14/2, 2014 at 11:42 Comment(3)
Thank you... yes, accessing UI components in a Fragment during the onCreateView method does work fine, as long as I use rootView.findViewById - I have discovered that I do not understand how I would even try and access a UI component in the onCreate method of a Fragment, because I don't seem to have access to a container, something which is obviously passed down to onCreateView and is readily available for the inflate method.Marge
P.S. - is it OK if I just add that I'm not exactly choosing to use Fragments per se, I have chosen to use Android Studio and it seems that Android Studio wants to try and enforce (encourage) the use of Fragments, by providing one when you create a new project. This is no bad thing... I just need to get my head around things properly, as a lot of code samples that you see on the Internet seem to not use Fragments, therefore I was running into issues with simple things. Thanks!Marge
The new release of Android Studio now allows you to create a new project without a default Fragment and, for the apps I am creating, this appears to be a good thing for me, so it makes things a bit simpler.Marge
S
0

@chipopo is right in the diagnostics and in the encapsulation recommendations.

But in case you need you can call FarmentManager.executePendingTransactions() after commiting the transaction. This ensures that the operations on fragments queue are execute synchronously. I used that sometimes in non UI retainedInstance fragments.

Sining answered 31/3, 2016 at 20:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.