Diferença entre onCreateView e onViewCreated in Fragment

118

Qual é a diferença essencial entre esses dois métodos? Quando eu crio um TextView, devo usar um sobre o outro para desempenho?

Edit: Qual é a diferença de

onCreateView() {
  root = some view
  View v = new View(some context);
  root.add(v);
  return root;
}


onViewCreated() {
  View v = new View(some context);
  getView().add(v);
}
Smith
fonte
Eu adicionei uma edição para explicar minha confusão. Se um método vem logo após o outro, por que existem dois? Não pode toda a criação de visualização ser feita dentro de um único método, como acima?
Smith
7
Se você tiver que pesquisar no Google e adivinhar, provavelmente há métodos com nomes incorretos.
Balázs Németh

Respostas:

85

Enfrentamos algumas falhas ao inicializar o modo de exibição em onCreateView.

Você deve aumentar seu layout em, onCreateViewmas não deve inicializar outras visualizações usando findViewByIdem onCreateView.

Porque às vezes o modo de exibição não é inicializado corretamente. Portanto, sempre use findViewByIdin onViewCreated(quando a visão estiver totalmente criada) e também passa a visão como parâmetro.

onViewCreated é uma garantia de que a visualização foi totalmente criada.

Documentação onViewCreated android

Chamado imediatamente após onCreateView( android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle) ter retornado, mas antes que qualquer estado salvo tenha sido restaurado na visualização. Isso dá às subclasses a chance de se inicializarem, uma vez que saibam que sua hierarquia de visualização foi completamente criada. A hierarquia de visão do fragmento, entretanto, não está anexada a seu pai neste ponto.

Zar E Ahmer
fonte
4
Obrigado. Eu também enfrentei esse problema e usei o componente. post(...) método para esperar até que seja mostrado. Provavelmente fará findViewById e outra inicialização em onViewCreated.
CoolMind
22
De onde esse texto foi citado? Não consegui encontrar na documentação oficial.
Daniel
Você pode postar a referência do site do desenvolvedor da declaração aqui citada?
Namrata Bagerwal
4
Isso não é realmente correto. Você pode encontrar uma visualização em onCreateView, mas somente depois de tê-la inflado e somente a partir da visualização que você já inflou. Fragment.findViewById () não é seguro, mas View.findViewById () é seguro se você já aumentou a visualização do fragmento.
colintheshots
46

onViewCreatedé chamado imediatamente após onCreateView(o método que você inicializa e cria todos os seus objetos, incluindo o seuTextView ), portanto, não é uma questão de desempenho.

Do site do desenvolvedor:

onViewCreated (visualização da vista, Bundle savedInstanceState)

Chamado imediatamente após o retorno de onCreateView (LayoutInflater, ViewGroup, Bundle), mas antes que qualquer estado salvo seja restaurado na visualização. Isso dá às subclasses a chance de se inicializarem, uma vez que saibam que sua hierarquia de visualização foi completamente criada. A hierarquia de visão do fragmento, entretanto, não está anexada a seu pai neste ponto.

Fonte: Fragmento # onViewCreated

u3l
fonte
28

É melhor fazer qualquer atribuição de subvisualizações aos campos em onViewCreated. Isso ocorre porque a estrutura faz uma verificação nula automática para você para garantir que a hierarquia de visualização do seu Fragment foi criada e aumentada (se estiver usando um arquivo de layout XML) corretamente.

Snippet de código de: FragmentManger.java

// This calls onCreateView()
f.mView = f.performCreateView(f.getLayoutInflater(f.mSavedFragmentState), null, f.mSavedFragmentState);

// Null check avoids possible NPEs in onViewCreated
// It's also safe to call getView() during or after onViewCreated()
if (f.mView != null) {
    f.mView.setSaveFromParentEnabled(false);
    if (f.mHidden) f.mView.setVisibility(View.GONE);
    f.onViewCreated(f.mView, f.mSavedFragmentState);
}
Orangemako
fonte
6
também separa qualquer lógica de inicialização da lógica de criação / inflação de hierarquia de visualização
orangemako
1
Isso é interessante, você tem recursos adicionais sobre por que essa abordagem é melhor? Isso significa que cada método onCreateView deve consistir apenas em um "return inflater.inflate (R.layout.layout_file, container, false);" e onviewcreated deve ter todos os métodos "findViewById"? Que aumento de desempenho isso cria? Isso tornaria as transições mais rápidas?
android_student
Para responder à sua primeira pergunta, onCreateViewé usado para criar a hierarquia de visualização do fragmento. Isso pode ser via inflação XML ou criação dinâmica (ou seja, criando visualizações Java de maneira programática). Portanto, você pode nem ligar inflate. Mas você deve retornar alguma visão pai se o fragmento precisar ter um elemento de IU. Caso contrário, volte null.
orangemako de
Não há nenhum aumento de desempenho. Olhando para o FragmentManagercódigo do fragmento e performCreateView, que chama onCreateView github.com/android/platform_frameworks_base/blob/… , você tem algumas coisas garantidas para o onViewCreatedretorno de chamada do ciclo de vida:
orangemako
1. A hierarquia de visualização será anexada ao contêiner se o fragmento tiver sido adicionado dinamicamente à sua atividade pai. 2. Você pode exibir pesquisas com segurança, sem se preocupar com NPEs. 3. Não estou familiarizado com animações, mas a transição do fragmento já terá sido iniciada (ou seja, enviada para a fila de mensagens do thread de IU).
orangemako de
13

onCreateViewretorna a visão inflada. OnViewCreatedé chamado logo após onCreateViewe get tem o parâmetro de visualização inflada. Seu tipo de retorno évoid

Cinto preto
fonte
1
Eu adicionei uma edição para explicar minha confusão. Se um método vem logo após o outro, por que existem dois? Não pode toda a criação de visualização ser feita dentro de um único método, como acima?
Smith
3
onCreateView deve retornar rapidamente. OnViewCreate pode ser usado para executar coisas de inicialização, por exemplo. Como eu disse, onViewCreated tem como parâmetro a View que você inflou dentro de onCreateView. Portanto, você pode evitar a getViewchamada
Blackbelt
8

onCreateView()é o Fragment equivalente a onCreate()for Activities e é executado durante a criação da Visualização.
onViewCreated()é executado após a visualização ser criada.

should I use one over the other for performance? NO . Não há evidência de aumento de desempenho.

Na verdade, há um onCreate()método em Fragments também, mas raramente é usado (eu nunca o uso, nem acho um bom caso de uso para ele).

Eu sempre uso onCreateView()em Fragments como um substituto para onCreate().
E estou feliz com isso.

Phantômaxx
fonte
2
@npace, por quê? Eu também acho que onCreateViewé um equivalente do Activity onCreate.
CoolMind
2
@CoolMind Bem, nPace não está totalmente errado, já que há um onCreate()método em Framents também. Mas nunca é usado (ou, pelo menos, eu nunca uso). Eu sempre uso onCreateView()em Fragments como um substituto.
Phantômaxx
1
@Rotwang, concordo com você! Alguns tutoriais usam onCreate para colocar setHasOptionsMenu (true), mas acho melhor fazer em onCreateView ou onViewCreated.
CoolMind
1
@CoolMind Concordo totalmente. Talvez eu tenha usado as palavras erradas em minha resposta.
Phantômaxx
1
@Rotwang, você disse certo. Quando usei fragmentos pela primeira vez, também não sabia por que onCreate não era usado.
CoolMind
4

A documentação porFragment.onCreateView() enquanto diz:

Recomenda-se apenas aumentar o layout neste método e mover a lógica que opera na View retornada para onViewCreated (View, Bundle).

Não há necessidade de entendermos o porquê; precisamos apenas fazer o que a documentação diz, mas seria interessante saber por que existe essa recomendação. Meu melhor palpite é separação de interesses , mas IMHO isso torna um pouco mais complicado do que deveria ser.

Peppe LG
fonte
Se o motivo for separação de interesses, por que Activity aumenta seu layout setContentView()em onCreate()?
Minh Nghĩa
@ MinhNghĩa Bom ponto. A resposta a essas perguntas pode ser simplesmente que ele foi projetado por um programador diferente pensando de forma diferente (fragmentos foram introduzidos alguns anos depois de termos o Android), mas quem sabe.
Peppe LG
2

O principal motivo que eu usaria onViewCreatedé porque ele separa qualquer lógica de inicialização da lógica de criação / inflação de hierarquia de exibição que deve ir no onViewCreate. Todas as outras características de desempenho parecem iguais.

AmeyaB
fonte
2

Acho que a principal diferença entre eles é quando você usa kotlin.in onCreateView () toda vez que deseja acessar para visualizar em seu arquivo xml, você deve usar findViewById, mas em onViewCreated você pode simplesmente acessar sua visualização apenas chamando o id dela .

Shahriar enayaty
fonte
Isso é verdade? Estou obtendo null para o modo de exibição se eu apenas usar o id no código de qualquer maneira. Preciso sempre usar o findViewById.
Jim Leask
1
Não, não é .. oncreate view instancia a visualização, onviewcreated é chamado após oncreateview e antes que os estados salvos sejam restaurados ... é mais um problema de tempo no ciclo de vida do fragmento
me_
1

onCreateView é usado no fragmento para criar o layout e aumentar a visualização. onViewCreated é usado para fazer referência à visualização criada pelo método acima. Por fim, é uma boa prática definir o ouvinte de ação em onActivityCreated.

Salu Khadka
fonte