Qual é a vantagem de usar Fragments no Android, em vez de Views?

102

Ao desenvolver para Android, você pode definir seu sdk de destino (ou mínimo) para 4 (API 1.6) e adicionar o pacote de compatibilidade do Android (v4) para adicionar suporte para Fragments. Ontem fiz isso e implementei Fragmentscom sucesso para visualizar dados de uma classe personalizada.

Minha pergunta é a seguinte: qual é o benefício de usar Fragmentsem vez de simplesmente obter uma visualização de um objeto personalizado e ainda oferecer suporte à API 1.5?

Por exemplo, digamos que eu tenha a classe Foo.java:

public class Foo extends Fragment {

    /** Title of the Foo object*/
    private String title;
    /** A description of Foo */
    private String message;

    /** Create a new Foo
     * @param title
     * @param message */
    public Foo(String title, String message) {
        this.title = title;
        this.message = message;
    }//Foo

    /** Retrieves the View to display (supports API 1.5. To use,
     * remove 'extends Fragment' from the class statement, along with
     * the method {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)}) 
     * @param context Used for retrieving the inflater */
    public View getView(Context context) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View v = inflater.inflate(R.layout.foo, null);
        TextView t = (TextView) v.findViewById(R.id.title);
        t.setText(this.title);
        TextView m = (TextView) v.findViewById(R.id.message);
        m.setText(this.message);
        return v;
    }//getView 

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        if (container == null) {
            return null;
        }
        View v = inflater.inflate(R.layout.foo, null);
        TextView t = (TextView) v.findViewById(R.id.title);
        t.setText(this.title);
        TextView m = (TextView) v.findViewById(R.id.message);
        m.setText(this.message);
        return v;
    }//onCreateView

}//Foo

Ambos os métodos são muito simples de criar e trabalhar em uma Activity que, digamos, tem um List<Foo>para exibir (por exemplo, adicionar programaticamente cada um a um ScrollView), então são Fragmentsrealmente úteis ou são apenas uma simplificação exagerada de obtendo uma visualização, como por meio do código acima?

Phil
fonte
2
Os fragmentos não precisam ter uma IU, eles podem ser apenas um comportamento reutilizável. Uma visualização seria redundante nesse caso.
Philipp Reichart
Eu respondi isso em outra pergunta. Consulte stackoverflow.com/a/14912608/909956 T; dr - às vezes, os fragmentos permitem que você crie mais componentes reutilizáveis ​​do que confiar na implementação de visualização personalizada. veja o link para saber o porquê.
numan salati de

Respostas:

172

O principal motivo para usar Fragments são os recursos de backstack e ciclo de vida. Caso contrário, as visualizações personalizadas são mais leves e mais simples de implementar.

No início, eu realmente tentei construir um aplicativo para telefone / tablet usando visualizações personalizadas. Tudo parecia funcionar em telefones E tablets, até mesmo alternando de painel único para painel dividido. Onde tive problemas foi com o botão Voltar e o ciclo de vida. Como eu estava simplesmente atualizando as visualizações manualmente ... não havia nada rastreando o histórico das visualizações e seus estados. Portanto, o botão Voltar não funcionou como esperado e era difícil recriar até mesmo o estado mais recente durante os eventos do ciclo de vida, como ao girar o aplicativo. Para consertar isso, tive que envolver minhas visualizações personalizadas em fragmentos e usar o FragmentManager para que os estados anteriores fossem salvos e recriados.

Percebi depois de responder que postei uma pergunta semelhante um ano antes: https://stackoverflow.com/a/11126397/618881

Henry
fonte
14
Muito boa resposta. Eu só queria adicionar que os fragmentos podem ser aninhados desde 4.2 ou a biblioteca de suporte rev 11.
kar
2
Obrigado @Karlo pela atualização. Não achei que fosse conceitualmente possível, mas eles contornaram isso usando um FragmentManager privado por meio de getChildFragmentManager (). Ah, e é API 17, não 11, e está disponível na Biblioteca de Suporte.
Henry
2
Eu estava examinando essa questão novamente e minha experiência também mudou. Essa é uma resposta que fornece uma boa compreensão das vantagens e desvantagens e é muito útil. Obrigado!
Phil
2
Quer marcar essa resposta com +1, mas isso arruinaria a pontuação atual. Além disso, 70 não é meu número favorito.
Behnam
1
no ano passado, eu também estava pensando que Fragments não fornecem nenhum recurso extra comum, mas percebi que depois de clicar novamente na atividade eu estava perdendo todas as imagens baixadas nele, então tive que adicionar implementação de cache, agora estou pensando em usar fragmentos pode ser muito fácil
Shirish Herwade
27

Eu diria que os fragmentos são úteis em dois cenários: se você dividir as visualizações em alguns dispositivos / orientações e mostrá-los em duas atividades e mostrar todo o conteúdo em um em outros dispositivos. Esse seria um caso de uso se você fosse em um tablet ou talvez até no modo paisagem em um telefone: por exemplo, você mostra a lista de itens e os detalhes em uma tela. em um telefone ou no modo retrato, você apenas mostra uma parte.

Outro caso de uso são as visualizações reutilizáveis. Portanto, se você tiver algumas visualizações que são visíveis em diferentes atividades e também executar algumas ações, poderá colocar esse comportamento em um fragmento e reutilizá-lo. Obviamente, você provavelmente também poderia fazer isso com widgets personalizados.

Não vejo razão para usar Fragments para cada View e acho que seria apenas uma sobrecarga. Estou usando-os apenas no primeiro caso de uso e diria que aqui é uma simplificação.

Maria Neumayer
fonte
Obrigado, isso foi definitivamente útil. Acho que vou ficar com as visualizações e fazer minha própria 'pilha de retorno' para torná-las reutilizáveis.
Phil
3

O Android introduziu fragmentos no Android 3.0 (API de nível 11), principalmente para oferecer suporte a designs de IU mais dinâmicos e flexíveis em telas grandes, como tablets. Como a tela de um tablet é muito maior do que a de um aparelho, há mais espaço para combinar e trocar os componentes da IU. Os fragmentos permitem tais designs sem a necessidade de você gerenciar mudanças complexas na hierarquia da visualização. Ao dividir o layout de uma atividade em fragmentos, você pode modificar a aparência da atividade em tempo de execução e preservar essas alterações em uma pilha de retorno que é gerenciada pela atividade.

Aqui você pode ler mais.

Yury
fonte
Eu li toda a documentação, no entanto, estava procurando por algo que explica melhor seus benefícios, como para tablets ou backstack
Fil
3
  1. Tela de divisão da atividade do cenário - Temos um layout e uma atividade que manipula a parte esquerda direita da tela
  2. Scenario FragmentActivity, temos Um layout para a tela principal, um para a esquerda e outro para a direita

O cenário um é bom se você tiver uma aplicação simples.

O cenário dois é bom se você deseja ter vários fragmentos e várias FragmentActivities e pode combinar cada um deles. Além disso, você pode fazer interação entre fragmentos.

Eu dividi a tela Fragmentactivity, posso chamá-la com 'Intent Extras' e dizer a fragmentActivity qual fragmento deve ser carregado. Os fragmentos são bons porque não estão manifestos, então você pode fazer fragmentos reutilizáveis ​​e FragmentActvity.

Mas isso torna seu projeto maior. Mas se você fizer um projeto grande, poderá salvar muitos. Porque você pode usar os mesmos fragmentos ou a mesma atividade de fragmento.

E eu acho que esses fragmentos chegam um pouco tarde, então você deve tentar pensar de uma nova maneira. Talvez apenas tente converter sua atividade para FragmentActivity. Mais tarde, tente encontrar o código reutilizável e faça Fragment a partir dele.

É útil, mas eu não sei como agora. Mas eu tenho algumas idéias.

Isso sempre é um problema. A equipe Android fez algo e ninguém sabe para que serve. Porque dificilmente aprendemos como antes e aí vem algumas coisas novas.

Na minha opinião é bom mas não pelo motivo que o google nos diz.

Mertuarez
fonte
0

Adicione um caso ao usar Fragment ou Activity em CustomView:

Quando você está usando CursorLoader para observar certas visualizações, ListView ou TextView e deseja atualizar seu valor de exibição sempre que os dados do seu ContentProvider forem atualizados no back end (o caso mais comum, você tem um serviço que atualiza seu banco de dados local por meio de pesquisa de dados do banco de dados / nuvem remoto periodicamente )

macio.Jun
fonte
-2

Uma coisa importante que todos os comentários acima não mencionam é que um fragmento permanece residente na memória mesmo se o Android interromper a atividade e reiniciá-la quando você fizer algo como alterar a orientação do seu dispositivo. Isso é feito por motivos de desempenho, mas também pode levar a resultados inesperados se você esperava que os fragmentos fossem destruídos apenas para descobrir que eles estão sendo recriados do nada.

AndroidDev
fonte