Fragments no Android, Trabalhando com Múltiplas Activities

Receba em primeira mão o conteúdo exclusivo do Blog, além de promoções de livros e cursos de programação. Você receberá um email de confirmação. Somente depois de confirmar é que poderei lhe enviar o conteúdo exclusivo por email.

Email inválido.
Blog /Android /Fragments no Android, Trabalhando com Múltiplas Activities

Fragments no Android, Trabalhando com Múltiplas Activities

Vinícius Thiengo26/01/2014
(10380) (70) (44) (2)
Go-ahead
"Não compare você mesmo com outros, pois é ai que começa a perder confiança em si próprio."
Will Smith
Código limpo
Capa do livro Refatorando Para Programas Limpos
TítuloRefatorando Para Programas Limpos
CategoriaEngenharia de Software
AutorVinícius Thiengo
Edição
Ano2017
Capítulos46
Páginas598
Comprar Livro
Conteúdo Exclusivo
Receba em primeira mão o conteúdo exclusivo do Blog, além de promoções de livros e cursos de programação.
Email inválido

Opa! Blz?

Nesse vídeo (grande) mostro a API de Fragments no Android. Construída para ajudar no trabalho melhor do espaço dos tablets, essa API nos permite colocar mais de uma Activity na tela do dispositivo sem a necessidade de gambiarras para simular essas várias activities na tela. Essa API é muito robusta e apesar de ter sido criada na versão 3.0 do Android ela tem suporte para versões anteriores (até a versão 1.6 do Android há suporte). Vale ressaltar que fragments têm ciclo de vida igualmente tem as activities (porém com alguns métodos a mais) e que o ciclo de vida dos fragments está intrisicamente vinculado ao ciclo de vida da Activity "pai" ou "conteiner" deles, ou seja, quando essa Activity "pai" está no método onResume() de seu ciclo de vida os fragments pertecentes a ela também estão no método onResume() no ciclo de vida deles.

Fique atento quanto ao uso do FrgamentManager, pois é ele que permitirá seu acesso as funcionalidades de busca, inserção e troca de Fragment no layout, juntamente com o FragmentTransaction. Vale ressaltar que o FragmentTransaction somente terá efeito se os fragments em uso tiverem sido inseridos via API e não via XML. Mas enfim, vou evitar mais delongas e deixar você assistir ao vídeo.

O link para download do projeto se encontra logo abaixo no post.

Se você não conhece o ListView, segue link do post que fiz sobre ele:

ListView: Entendendo e Utilizando no Android

Páginas de algumas classes do exemplo:

Página da classe Fragment no site oficial do Android

Página da classe LayoutInflater no site oficial do Android

Vlw

Receba em primeira mão o conteúdo exclusivo do Blog, além de promoções de livros e cursos de programação.
Email inválido

Relacionado

Notification no Android, Criando Notificações Com Toque e VibraçãoNotification no Android, Criando Notificações Com Toque e VibraçãoAndroid
AlarmManager no Android, Sua APP Executando Em Tempos DefinidosAlarmManager no Android, Sua APP Executando Em Tempos DefinidosAndroid
AsyncTask no Android, Acesso a Thread Principal de Forma OtimizadaAsyncTask no Android, Acesso a Thread Principal de Forma OtimizadaAndroid
Construindo View Personalizada no AndroidConstruindo View Personalizada no AndroidAndroid

Compartilhar

Comentários Facebook (21)

Comentários Blog (49)

Para código / script, coloque entre [code] e [/code] para receber marcação especifica.
Forneça seu nome válido.
Forneça seu email válido.
Forneça o comentário.
Enviando, aguarde...
28/06/2016
Esqueci,
Linha 55: lv.setAdapter(new AdapterListView(this, itens));
Linha 49: lv.setOnItemClickListener(this);
            createListView();
Não entendi porque ele diz que o método que estou tentando passar é nulo.
O fato de estar trabalhando com fragments muda algo no createListView?
Responder
27/06/2016
Boa tarde, Thiengo. Gostaria de colocar uma imagem no list. Ficando a imagem e o nome do fragment que vai ser chamado. Como faço isso? Obrigada.
Responder
Vinícius Thiengo (0) (0)
28/06/2016
Fala Fernanda, blz?
Utilize o BaseAdapter junto ao ListView, dessa forma poderá fornecer um layout simples que tenha ao menos um ImageView e um TextView, esses dentro de um View root, que em seu caso pode ser um LinearLayout com orientação horizontal.

Feito isso, terá de utilizar o click de listener do ListView, onItemClickListener(), para abrir o fragment correto, que de acordo com a lista de objetos que vai utilizar junto ao base adapter tende a ser algo não mt difícil. Abaixo alguns links que podem lhe ajudar. Abraço

BaseAdapter: http://www.thiengo.com.br/utilizando-baseadapter-para-personalizacao-completa-da-listview

LinearLayout: http://www.thiengo.com.br/linearlayout-no-android-entendendo-e-utilizando

ListView: http://www.thiengo.com.br/carregando-dados-no-listview-com-onscrolllistener-e-volley-no-android
Responder
28/06/2016
Eu tentei por BaseAdapter, porém quando vou executar da FATAL EXCEPTION.
FATAL EXCEPTION:  Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference
                                                                                   at com.androidcontrol.profilesyanz.SelectProfile.createListView(SelectProfile.java:55)
                                                                                   at com.androidcontrol.profilesyanz.SelectProfile.onCreate(SelectProfile.java:49)
Minha classe principal é essa:
public class SelectProfile extends FragmentActivity implements AdapterView.OnItemClickListener {
    FragmentManager fm = getSupportFragmentManager();
    private ListView lv;
    private ArrayList<ItemListView> itens;

    int lastPosition = 0;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_select_profile);


            if (savedInstanceState == null) {
                ProfileModule profile = new ProfileModule();
                FragmentTransaction ft = fm.beginTransaction();
                ft.add(R.id.layout_fragment, profile, "Cenários");
                ft.commit();
            }


            //String[] lista = new String[]{"Cenários","Expansão", "RGB"};


            ListView lv = (ListView) findViewById(R.id.listView1);
           lv.setOnItemClickListener(this);
            createListView();
        }

    private void createListView() {
        itens = new ArrayList<ItemListView>();
        //AdapterListView adapterListView = new AdapterListView(this, itens);
        lv.setAdapter(new AdapterListView(this, itens));
        lv.setCacheColorHint(Color.TRANSPARENT);
        }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        FragmentTransaction ft = fm.beginTransaction();

        if(position == 0){
            ProfileModule profile = (ProfileModule) fm.findFragmentByTag("Cenários");

            if(profile == null) {
                profile = new ProfileModule();
            }
            ft.replace(R.id.layout_fragment, profile, "Cenários");
        }
        else if(position == 1){
            LampModule lampada = (LampModule) fm.findFragmentByTag("Expansão");

            if(lampada == null) {
                lampada = new LampModule();
            }
            ft.replace(R.id.layout_fragment, lampada, "Expansão");
        }
        else if(position == 2){
            RGBModule rgb = (RGBModule)fm.findFragmentByTag("RGB");

            if(rgb == null) {
                rgb = new RGBModule();
            }
            ft.replace(R.id.layout_fragment, rgb, "RGB");
        }

        ft.addToBackStack("pilha");
        ft.commit();
        lastPosition = position;

    }
}
Agradeceria muito se me respondesse.
Responder
Vinícius Thiengo (0) (0)
03/07/2016
Fernanda, o listView em:

ListView lv = (ListView) findViewById(R.id.listView1);

É local, logo o listView variável de instância permanece null. Para resolver somente remova o ListView, deixe somente:

lv = (ListView) findViewById(R.id.listView1);

Isso no código final do onCreate(). Dessa forma deve funcionar sem problemas. Abraço
Responder
03/07/2016
Fiz o que você disse, porém agora quando executo não aparece nem o nome em nem a imagem no list
Responder
Vinícius Thiengo (0) (0)
04/07/2016
Sim, a sua variável de instância "itens" está vazia, precisa colocar algum dado nela, vc apenas instanciou um ArrayList, mas ainda vazio. Abraço
Responder
Daniel (1) (0)
10/08/2015
E ai thiengo , estou querendo criar um novo fragment apartir de um item dentro do RecyclerView.
Mas quando eu uso o replace, esse novo fragment aparece em branco...

@Override
    public void onClickListener(View view, int position) {
        Fragment c2 = new CestaF();
        FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
        ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
        ft.replace(R.id.pager, c2);
        ft.addToBackStack("stak");
        ft.commit();
        }
Responder
Vinícius Thiengo (0) (0)
11/08/2015
Fala Daniel, blz?
O método onCreateView() de seu fragment está sendo chamado? Provavelmente o problema é nele, pois é lá que a View container do fragment é retornada. Abraço
Responder
12/08/2015
Esta criando sim thiengo, coloquei o Log.d("onCreate","criou"); na view CestaF;,

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
       Log.d("onCreate","criou");
        return inflater.inflate(R.layout.fragment_cesta, container, false);

    }

e continua banco, sendo que o fragment cesta esta com background diferente...
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:background="#f4f5f6"
    android:layout_height="match_parent" tools:context="apprumo.com.doealimento.fragments.CestaF">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="Large Text"
        android:id="@+id/textView3"
        android:layout_gravity="center" />

</FrameLayout>
Responder
Vinícius Thiengo (0) (0)
13/08/2015
Daniel, tente rodar sem o ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);

Se mesmo assim não for, utilize add() no lugar do replace(). Ainda não rodando como esperado, volte ae que vamos dar um outro jeito. Abraço
Responder
Daniel (1) (0)
13/08/2015
Ainda não deu certo.... Vou manda o link do projeto no git, daí tem como VC vê isso p mim? Travei nessa parte e o projetos não anda..
https://github.com/fonzaex/android-projects/tree/master/DoeAlimento/app/src/main


Dentro do fragmentos destino, to tentando chamar o fragmentos cesta
Responder
Vinícius Thiengo (0) (0)
14/08/2015
Fala Daniel, blz?
Como informado em página do Facebook, veja se essa discussão (http://stackoverflow.com/questions/18588944/replace-one-fragment-with-another-in-viewpager) e consequentemente essa resposta (http://stackoverflow.com/a/18612049/2578331) ajudam a resolver seu problema, pois as dúvidas foram as mesmas. Abraço
Responder
Alexandre Ferreira (1) (0)
01/04/2015
Blz Thiengo, e o seguinte estou implementando um Fragment, so que dentro dele eu quero criar uma lista,  tem como demostrar algum tipo de exemplo ou indicar um link. No meu caso estou usando Swiper View ai queria que em cada aba fosse aberto uma lista, como Bebidas, Comidas, Porçoes. Desde já agradeço pelo video muito bom.
Responder
Vinícius Thiengo (0) (0)
02/04/2015
Fala Alexandre, blz sim.
Dê uma olhada nesse vídeo (http://www.thiengo.com.br/listview-entendendo-e-utilizando-no-android) e tente fazer a mesma coisa porém dentro do método onCreateView() do fragment. Essa é uma forma de implementação de lista no fragment. Se não der certo volte ae que daremos um jeito. Abraço

Veja esse tb: http://www.thiengo.com.br/utilizando-baseadapter-para-personalizacao-completa-da-listview
Responder
Jhonata (0) (0)
24/12/2014
Ola tudo certo?
To acompanhando os seus videos e estão sendo de grande ajuda,

Surgiu um problema que é o seguinte, eu tenho uma mainActivity que extend FragmentActivity e tenho 2 Fragments e esses caras contem um listView cada um, eu preciso atualizar as listas independentes porem não estou conseguindo pois mesmo que chamando o fragment onde contem a lista que quero atualizar e dando o notifyDataSetChanged() na lista, que é chamado pelo fragment, ele nao atualiza a tela, só atualiza se na Main eu recriar as tabs com o adapter da tab

poderia me dar uma luz?
Parabens pelos videos Abraços e boas festas
Responder
Vinícius Thiengo (0) (0)
25/12/2014
Fala Jhonata, tudo certo sim.
Me diz, no fragment vc tem uma variavel de instancia que contem a referencia para o adapter que será utilizado em seu listView. Esse adapter recebe tb como parametro de entrada a lista de objetos que vc está para mostrar no ListView. E quando vc tem novos dados ou algum objeto da lista foi atualizado vc apenas faz a atualização na mesma lista que está vinculada ao adapter e então logo depois somente chama o método notifyDataSetChanged() do adapter, está fazendo exatamente isso? Somente com dados criados no fragment, não precisa de dados da Activity nesse caso. Abraço
Responder
Jhonata (0) (0)
26/12/2014
Dae blza,
Pior que não o que tenho seria isso:
private View getLayout() {
LinearLayout layout = new LinearLayout(this.context);
try {

MovimentoController mController = new MovimentoController(context);
MovimentoListView listaMovimentos = new MovimentoListView(context);

List<Movimento> movimentosAtualizados = mController.movimentosAtualizados;
if (movimentosAtualizados.size() > 0) {
listaMovimentos.atualizarItens(movimentosAtualizados);
} else {
movimentosAtualizados = mController
.getMovimentosMensaisUsuario(idUsuarioLogado);
}
listaMovimentos.atualizarItens(movimentosAtualizados);
layout.addView(listaMovimentos);

} catch (SQLException e) {
new SQLException(e);
}
return layout;
}

Esse metodo é chamado pelo meu onCreateView() do fragment e so nesse momento eu tenho a lista, se eu criar uma instancia do adapter ou da lista no meu fragment consigo atualizar direto ao trocar de aba na tela, somente passando os dados pra lista? Eu avia criado um metodo que retornava a lista e passava os novos dados por parametro, debugando ele atualizava a lista mais em tela não
Responder
Vinícius Thiengo (0) (0)
26/12/2014
Jhonata da maneira como está fazendo acredito que não funcionará, suas variáveis de lista e ListView são locais no método onCreateView(), ou seja, sempre que for querer atualizar a lista quando o fragment já estiver aberto vc teria de Acessar o listView novamente e criar tudo de novo se não me engano, seu ListView, sua lista de movimentos e o adapter que será vinculado ao ListView vc pode colocar como variáveis de instancia, ou seja, variáveis declaradas no escopo da classe e não do método, assim vc consegue acessá-las de qualquer método para poder atualizar o listView, basicamente vc precisaria de acesso a esses três componentes, ListView, Adapter e Lista, mas somente vi o acesso ao ListView e a Lista de movimentos. O seu linearLayout pode já conter o ListView no XML, não precisa add ele em tempo de execução. Abraço
Responder
Wander (1) (0)
20/10/2014
Cara muito bom mesmo o seu site, aprendi muito com os videos..

Mas fica uma dica, tente falar menos "perfeito?" ...nesse videos deve ter falado isso umas 120 vezes...

Desculpa a chatice...mas apenas uma dica para melhorar.

Valeu.
Responder
09/10/2014
Cara gosto mt dos seus video
estou fazendo um tcc para o meu curso e preciso de ajuda "como chamar outro fragment através de um fragment"?
Responder
Vinícius Thiengo (1) (0)
10/10/2014
Fala Stan, blz?
Segue um exemplo de como fazer isso:

NotificationFragment frag = new NotificationFragment((Notification) listViewControl.getList().get(position));
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.replace(R.id.layoutLeftData, frag);
ft.addToBackStack("stak");
ft.commit();

Esse script está dentro de um fragment e está chamando outro fragment (NotificationFragment) e colocando essa chamada na pilha de fragments (ft.addToBackStack("stak")) que criei com o nome "stak". Abraço
Responder
Andressa (0) (0)
23/08/2014
Parabens pelo video Vinicius, me ajudou muito.
Mas fiquei com uma duvida. Estou criando um app que recebera dados via xmlrpc, e como vc mencionou no seu video "Vale ressaltar que o FragmentTransaction somente terá efeito se os fragments em uso tiverem sido inseridos via API e não via XML".
Nesse caso usar fragments na minha aplicação nao funcionará?
Responder
Vinícius Thiengo (0) (0)
24/08/2014
Fala Andressa, blz?
Então, já peço desculpas, pois não expressei direito. O XMLRPC é um método de comunicação, o xml que mencionei no vídeo é o XML de layout, de estrutura da Activity, o que deve ser entendido é que vc pode criar o fragment no layout XML e acessa-lo via findFragmentById(), se não me engano é isso mesmo (tempo que não utilizo assim), nesse caso há as limitações de uso que falei no vídeo. A outra forma de criar é via API, como: new MeuFragment(). A sua comunicação via xmlrpc não influencia em nada. Alias se não me engano vc terá de realizar o parser xml, coisa que não recomendo, pois parser xml é mt pesado no Android. Abraço
Responder
Andressa (0) (0)
25/08/2014
Ahhh ta, entendi e obrigado pelo esclarecimento.

Aproveitando, tenho mais uma duvida, por exemplo, no click do textView do Fragment1, pode enviar um texto pro Fragment2?
Responder
Vinícius Thiengo (0) (0)
25/08/2014
Pode sim, sem problemas. Abraço
Responder
Andressa (0) (0)
25/08/2014
Entao eu teria que criar um metodo no onClick do textView, e na class Fragment1, chamar o Fragment2 passando como parametro o texto que quero alterar? Ou tenho que fazer isto no MainActivity.java? Podes me passar algum exemplo de como enviar informações entre fragment?
Responder
Vinícius Thiengo (0) (0)
26/08/2014
É isso ae mesmo, vc pode passar a mensagem pelo construtor do fragment2... vou deixar vc quebrar a cabeça ai em como fazer... é bem tranquilo, vc fez já para que a Activity chame o fragment, agora é só fazer de fragment para fragment (que não muda quase nada). Abraço
Responder
Rafael Mota (0) (0)
11/05/2014
Muito Bom! Parabéns e wlw por compartilhar.
Responder
rafael (0) (0)
08/04/2014
Vinicius muito bom o tutorial! Deu uma clareada nas ideias bacana hehehe.

Agora não sei se acontece só comigo, mas ta dando forced closed se selecionarmos o "Fragment2", "Fragment3" e depois clicarmos no "Alterar texto fragment 1".

"java.lang.NullPointerException"

Se puder dizer o que está causando este problema ficarei grato. Obrigado pela aula! =)
Responder
Vinícius Thiengo (0) (0)
09/04/2014
Fala Rafael, blz? Vou dar uma checada aqui, tb não sabia dessa Exception, abraço
Responder
Vinícius Thiengo (0) (0)
14/04/2014
Fala Rafael, blz? Então olhei o código aqui e achei o problema, eu não estava verificando se era o Fragment1 que estava no topo da pilha... logo quando não fosse não podia alterar o texto, pois o TextView não estava na tela... corrigi esse bug e agora o script esta funcionando. Grande abraço e vlw por ter mi alerta... flw
Responder
marcelo (0) (1)
21/03/2014
Boa noite, parabéns pela video aula. Só fiquei com uma dúvida. Como ficaria este código adaptado para Smartphone e tablet ao mesmo tempo já que no smartphone não temos o mesmo espaço? Como ficaria o reaproveitamento de código? Obrigado.
Responder
Vinícius Thiengo (0) (0)
22/03/2014
Opa Marcelo, blz?
Então, o que eu faço é identificar via script se é ou não um tablet que está sendo utilizado. No layout da Activity principal eu coloco dois containers (pode ser no caso dois LinearLayouts) dentro desse layout. Se eu identificar que é tablet eu trabalho com os dois para melhor utilizar a tela do tablet caso contrário trabalho apenas com um container e escondo o outro via setVisibility(View.GONE). Segue código que utilizo para identificar se é Tablet ou não:

public static boolean isTablet(Context context){
if(context == null){
return(false);
}

return( (context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE );
}

Note que esse código está no livro "Google Android Para Tablets" de Ricardo Lecheta. Abraço
Responder
Marcelo (0) (0)
22/03/2014
Bom dia Vinícius, ah legal!!!... entendi!!!... aí se for smartphone você faz o replace no próprio fragment que tem o listview e vai adicionando na pilha para poder voltar certo? obrigado :-)
Responder
Vinícius Thiengo (0) (0)
22/03/2014
Perfeito! Assim quando for tablet vc utiliza a área ao lado que será útil para mostrar o conteúdo da listView. Abraço
Responder
11/05/2014
Olá! Tudo bem? Espero que sim. Então, estou iniciando e não entendi  como fazer para adaptar para smartphone. Teria como mostrar um exemplo? Agradeceria muito.
Responder
Vinícius Thiengo (0) (0)
11/05/2014
Fala Rafael, blz? Então já me pediram isso outras vezes... está na fila de vídeos a fazer aqui. abraço
Responder
Rafael Mota (0) (0)
11/05/2014
Blz! Aguardando ansiosamente rsrsr. abraços.
Responder
27/01/2014
Muito bom esse tutorial, parabéns. Uma dúvida é como carregar o ListView com dados do SQLIte utilizando Fragment?
Responder
Vinícius Thiengo (1) (0)
28/01/2014
*Respondido via email
Responder
05/02/2014
Manda pra mim, se puder.
Responder
Vinícius Thiengo (0) (0)
05/02/2014
Fala Alex, então, na verdade o Fred não tinha explicado mt bem o que ele queria, mas por email ele esclareceu. O que ele queria era colocar o ListView de um lado e estático no layout e então o outro lado teria toda a atulização da APP (as outras activities). Eu acabei ajudando ele e fazendo parte do projetinho, ficou legal para entender. Vou enviar o projeto para ti por email, terá que abrir no eclipse com Android. Note que sou péssimo para comentar código, porém acredito que ele esteja bem limpo e dividido. Caso dê uma viajada no código, os vídeos aqui sobre Fragments e ActionBar vão ajudar. Abraço
Responder
06/02/2014
Não estou conseguindo rodar no emulador como tablet. Tem como postar aqui uma ajuda?
Responder
Vinícius Thiengo (0) (0)
07/02/2014
Frederico vc precisa pegar o erro que está dando, pois o código que lhe enviei rodou aqui no tablet. Quando vc rodar a APP no emulador de tablet e assim a exception for gerada, vá ao LogCat e copia a primeira linha depois de FATAL ERROR e posta aqui. O erro pode ser no BD, altere o numero de versão dele. Outra dica é tentar rodar em um dispositivo real ao invés de um emulador. Lemnro que aquele dia o problema era a lentidão. Abraço
Responder
07/02/2014
Não é erro não. Tem razão, lentidão. Tem como mudar ppara outro dispositivo ou tem que ser tablet no emulador? To fazenfo um teste no Win 8.1, sera que da umuma melhorada?
Responder
Vinícius Thiengo (0) (0)
07/02/2014
Frederico, acabei de postar um vídeo que mostro como instalar e utilizar um emulador mt mais rápido que o convencional do Android, segue link: http://www.thiengo.com.br/instalando-o-emulador-genymotion-no-android
Responder
Alex Passos (0) (0)
20/04/2014
Olá Vinícius,
Estou precisando do exemplo parecido... fragment utilizando o listview com SQLite... teria como me enviar esse exemplo: passos_alex@hotmail.com
Responder
Vinícius Thiengo (0) (0)
20/04/2014
Respondido em email!
Responder