Android — активность onCreate и фрагментация onCreate

Я все еще новичок в программировании для Android, поэтому этот вопрос довольно простой. Я вижу множество примеров кода в Интернете, где компоненты пользовательского интерфейса, такие как TextView, инициализируются и доступны в методе onCreate() Activity.

Когда я использую Android Studio для создания нового проекта — FirstApp — с настройками по умолчанию, пустой Activity под названием MainActivity, включающей в себя activity_main и fragment_main, я могу немедленно скомпилировать это в APK, развернуть на своем устройстве и получить экран с заголовком «FirstApp» и TextView в верхнем левом углу, показывающим «Hello world!».

Если я дам TextView идентификатор textview1 и создам переменную-член TextView myTextView;, то я смогу сослаться на нее в методе onCreate() действия, например так (конечно, без ошибок компилятора):

    @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();
        }
    }

Однако, если я скомпилирую и запущу APK, это приведет к ошибке «К сожалению, FirstApp остановлен». сообщение.

Раньше я обходил эту проблему, перемещая код запуска, который обращается к компонентам пользовательского интерфейса, в метод onStart() действия, например так:

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

В результате будет работать APK с одним TextView в левом верхнем углу, показывающим «Привет, планшет!» - мои простые вопросы двояки...

  1. Если проект использует фрагменты, то должен ли я полностью ожидать, что компоненты пользовательского интерфейса не могут быть доступны в методе onCreate() действия, как это происходит с большим количеством образцов кода в Интернете, вероятно, потому, что они еще не были созданы?
  2. Допустимо ли для меня получать доступ к компонентам пользовательского интерфейса в методе onStart() Activity (который действительно работает) или мне следует делать что-то еще? Ранее я также использовал метод onCreateView фрагмента, но является ли лучшим местом для доступа к компонентам пользовательского интерфейса внутри фрагмента на самом деле в методе onCreate() фрагмента, который я еще не пробовал?

Я также отмечаю, что метод onCreate() фрагмента по умолчанию, который Android Studio создает для вас, когда вы создаете новый проект, не имеет предоставленной заглушки... но onCreateView имеет, и документация жизненного цикла подразумевает (во всяком случае для меня), что этот может быть лучшим местом для таких вещей.

Любое руководство по этому поводу приветствуется.


person Hippogriff    schedule 14.02.2014    source источник
comment
Когда произошел сбой, получите трассировку стека Logcat, чтобы мы могли увидеть, в чем заключается ошибка. Также myTextView настраивается где-то еще, т.е. TextView myTextView;?   -  person TMH    schedule 14.02.2014
comment
Вы должны прочитать о фрагментах в целом. 1. Представление фрагмента еще недоступно там (это не просто представление, которое вы добавляете в макет) 2. Вы можете получить доступ к представлениям из того, какой обратный вызов вы хотите (обычно предпочтительнее onCreate()). Проблема в том, что вы пытаетесь получить доступ к представлению фрагмента, которого следует избегать, и вместо этого позволяете фрагменту обрабатывать это самостоятельно.   -  person user    schedule 14.02.2014
comment
@Tom Hart - да, TextView myTextView; включен как переменная-член. Подразумевает ли ваш ответ, что вы считаете, что этот компонент пользовательского интерфейса должен быть полностью доступен в методе onCreate() самого Activity?   -  person Hippogriff    schedule 14.02.2014


Ответы (2)


Команда фиксации транзакции фрагмента только помещает транзакцию в очередь — транзакция будет обработана через некоторое время в будущем. Вот почему вы не можете использовать его прямо при создании.

Я предлагаю вам использовать фрагменты для инкапсуляции их поведения пользовательского интерфейса — я бы не стал явно менять элементы пользовательского интерфейса фрагмента из действия.

OnCreateView внутри фрагмента — хорошее место для инициализации элементов пользовательского интерфейса фрагмента, поскольку он вызывается при создании представления фрагмента.

Работа с фрагментами поначалу довольно сложна и болезненна, но по моему опыту они помогают создавать гораздо более модульный код.

Я предлагаю вам больше узнать о фрагментах в документации, прежде чем начинать с ними серьезный проект. http://developer.android.com/guide/components/fragments.html

person chipopo    schedule 14.02.2014
comment
Спасибо... да, доступ к компонентам пользовательского интерфейса во фрагменте во время метода onCreateView действительно работает нормально, пока я использую rootView.findViewById - я обнаружил, что не понимаю, как я мог бы даже попытаться получить доступ компонент пользовательского интерфейса в методе onCreate фрагмента, потому что у меня, похоже, нет доступа к container, что-то, что, очевидно, передается onCreateView и легко доступно для метода inflate. - person Hippogriff; 14.02.2014
comment
P.S. - все в порядке, если я просто добавлю, что я не точно выбираю использование фрагментов как таковых, я решил использовать Android Studio, и кажется, что Android Studio хочет попробовать и принудительно< /i> (поощрять) использование фрагментов, предоставляя их при создании нового проекта. В этом нет ничего плохого... Мне просто нужно как следует разобраться, так как многие примеры кода, которые вы видите в Интернете, похоже, не используют фрагменты, поэтому я столкнулся с проблемами с простыми вещами. Спасибо! - person Hippogriff; 14.02.2014
comment
Новая версия Android Studio теперь позволяет вам создавать новый проект без фрагмента по умолчанию, и для приложений, которые я создаю, это кажется мне хорошей вещью, так что это немного упрощает проще. - person Hippogriff; 09.03.2014

@chipopo прав в диагностике и в рекомендациях по инкапсуляции.

Но в случае необходимости вы можете вызвать FarmentManager.executePendingTransactions() после совершения транзакции. Это гарантирует, что операции над очередью фрагментов выполняются синхронно. Я использовал это иногда в фрагментах, не связанных с пользовательским интерфейсом, с сохранением экземпляров.

person lujop    schedule 31.03.2016