Animação, onLongPress e GridLayoutManager em RecyclerView, Material Design Android - Parte 3

Investir em Você é Barra de Ouro a R$ 2,00. Cadastre-se e receba grátis conteúdos Android sem precedentes! Você receberá um email de confirmação. Somente depois de confirma-lo é que eu poderei lhe enviar os conteúdos semanais exclusivos. Os artigos em PDF são entregues somente para os inscritos na lista.

Email inválido.
Blog /Android /Animação, onLongPress e GridLayoutManager em RecyclerView, Material Design Android - Parte 3

Animação, onLongPress e GridLayoutManager em RecyclerView, Material Design Android - Parte 3

Vinícius Thiengo
(8460) (77)
Go-ahead
"O método consciente de tentativa e erro é mais bem-sucedido que o planejamento de um gênio isolado."
Peter Skillman
Prototipagem Android
Capa do curso Prototipagem Profissional de Aplicativos
TítuloAndroid: Prototipagem Profissional de Aplicativos
CategoriasAndroid, Design, Protótipo
AutorVinícius Thiengo
Vídeo aulas186
Tempo15 horas
ExercíciosSim
CertificadoSim
Acessar Curso
Quer aprender a programar para Android? Acesse abaixo o curso gratuito no Blog.
Lendo
TítuloManual de DevOps: como obter agilidade, confiabilidade e segurança em organizações tecnológicas
CategoriaEngenharia de Software
Autor(es)Gene Kim, Jez Humble, John Willis, Patrick Debois
EditoraAlta Books
Edição1ª
Ano2018
Páginas464
Conteúdo Exclusivo
Investir em Você é Barra de Ouro a R$ 2,00. Cadastre-se e receba gratuitamente conteúdos Android sem precedentes!
Email inválido

Tudo bem?

No vídeo acima daremos continuidade à série Material Design Android. Está aula é na verdade o término da aula anterior, a segunda aula, onde iniciamos os trabalhos com o framework de lista mais eficiente no desenvolvimento de aplicativos Android, o RecyclerView.

Aqui vamos prosseguir com o foco nas outras duas populares APIs de LayoutManager:

  • GridLayoutManager;
  • StaggeredGridLayoutManager.

A primeira API, GridLayoutManager, tem como responsabilidade alinhar os itens em grid, com linhas e colunas, porém não evitando espaços extras, gaps, quando houver itens em mesma linha (ou coluna, dependendo da orientação escolhida para o LayoutManager) com tamanhos diferentes.

GridLayoutManager sendo utilizado no RecyclerView

Enquanto a segunda API, StaggeredGridLayoutManager, além de também ter como responsabilidade alinhar os itens em grid, também trabalha a responsabilidade de "não ter gaps", espaços extras, entre as células. Os itens ficam todos corretamente encaixados em grid, mesmo se os tamanhos forem distintos.

StaggeredGridLayoutManager sendo utilizado no RecyclerView

Veja bem:

Não deixe de entender muito bem como utilizar os dois LayoutManagers citados anteriormente, pois hoje em dia é muito comum o trabalho com itens em grid, principalmente em grid sem gaps, utilizando a API StaggeredGridLayoutManager. E ainda não há indícios de que isso tende a mudar.

Voltando ao conteúdo do vídeo... nele também é apresentado como implementar o ouvidor OnLongPressListener, além do OnClickListener, utilizando a API GestureDetector.SimpleOnGestureListener que, via objeto MotionEvent, nos permite detectar qual foi o evento disparado: OnLong; ou OnClick.

Por fim, na vídeo aula, é mostrado como utilizar a biblioteca Android View Animations, de Daimajia, para inserir animações nos itens do RecyclerView.

Note que nem todas as animações funcionam:

  • ou Porque a View sendo utilizada, como cliente da API de animação, não dá suporte;
  • ou Porque o aparelho, versão Android instalada, realmente não suporta as entidades utilizadas na API de animação.

Porém, em meus testes com alguns emuladores AVD, a maioria funcionou sem problemas, inclusive em device virtual com a API 10 (Android Gingerbread).

Uma dica importante quando utilizando a API de animação View Animations:

Não esqueça de utilizar os blocos try...catch, caso contrário é provável que o seu projeto de aplicativo tenha problemas com Exceptions em aparelhos com versões antigas do Android, mais precisamente em aparelhos com versões anteriores ao Android 21, Lollipop.

Note que no vídeo da aula anterior eu informei sobre: apresentar nesta terceira aula o componente visual CardView. Porém eu optei por deixar o CardView em uma aula somente dedicada a ele, que na verdade é a quarta aula, a próxima.

Se você estiver pensando em utilizar algum framework de lista, em formato de grid, para o trabalho com tags, por exemplo, não faça isso! No Android tem um componente visual especifico para este tipo de layout e que certamente será uma escolha mais inteligente. Estou falando do FlexboxLayout.

Antes de finalizar mais uma aula da série Material Design (não deixe de assistir à vídeo aula), deixo a seguir alguns links de conteúdos aqui do Blog, acompanhados de vídeos, que lhe colocarão em dia com o que há de novo no desenvolvimento de aplicativos:

E caso você tenha como meta aprender a construir apps Android, ou evoluir nesta área, também com os conteúdos gratuitos do Blog, então não deixe de acessar a lista para estudos em: Estudando Android - Lista de Conteúdos do Blog.

E não esqueça de se inscrever 📫na lista de e-mails do Blog para receber todos os conteúdos Android em primeira mão.

Se inscreva também no canal do Blog no YouTube para acompanhar as últimas novidades disponíveis lá e aqui no site.

Surgindo dúvidas ou dicas, pode enviar abaixo na área de comentários que logo eu lhe respondo.

Obs. : o link para download do projeto apresentado em vídeo se encontra logo abaixo no artigo, na seção "Download".

Abraço.

Aula anterior

Está, "Animação, onLongPress e GridLayoutManager em RecyclerView, Material Design Android - Parte 3", é a terceira aula da série Material Design no Android. A aula anterior, caso você ainda não tenha visto, é a seguinte:

Próxima aula

A próxima aula a está, a quarta aula, é a seguinte:

É importante que você siga as aulas na ordem apresentada em série, isso para poder tirar o máximo dela e assim evoluir como esperado no mundo de desenvolvimento Android.

Códigos do projeto

Para ter acesso a todos os códigos completos do projeto desenvolvido na série Android Material Design, basta entrar nos repositórios GitHub dele em:

Fontes

GridLayoutManager - documentação oficial Android

StaggeredGridLayoutManager - documentação oficial Android

GestureDetector - documentação oficial Android

GestureDetector.SimpleOnGestureListener - documentação oficial Android

Investir em Você é Barra de Ouro a R$ 2,00. Cadastre-se e receba grátis conteúdos Android sem precedentes!
Email inválido

Relacionado

APP Thiengo [Calopsita] 3.0APP Thiengo [Calopsita] 3.0Android
Busca Por Locais Próximos, Location API Android - Parte 5Busca Por Locais Próximos, Location API Android - Parte 5Android
Toolbar, Material Design Android - Parte 1Toolbar, Material Design Android - Parte 1Android
RecyclerView, Material Design Android - Parte 2RecyclerView, Material Design Android - Parte 2Android

Compartilhar

Comentários Facebook

Comentários Blog (77)

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...
29/11/2016
Thiengo blz? bom dia tenho uma duvida sobre o GridLayoutManager, tenho a seguinte situação uma lista com 7 imagens com prioridades e data imagem de prioridade 1 fica no topo quando a prioridade for igual a data mais antiga fica na frente tudo isso divididos em 3 colunas, linhas de baixo completas linha de cima centralizada com a imagem que sobra, (duas linhas com 3 e uma linha com uma). posso usar GridLayoutManager?
Responder
Vinícius Thiengo (1) (0)
01/12/2016
Jasian, tudo bem aqui.

Pode sim utilizar o GridLayoutManager.

O que tem que ficar atento é que o GridLayoutManager é relativo somente a apresentação do conteúdo, logo, independente da lógica de negócio, se no final das contas a apresentação deve ser em Grid, o GridLayoutManager é um excelente opção.

Todos os cálculos e lógicas para logo depois apresentar o conteúdo de forma correta devem ser aplicados a lista de objetos que será vinculada ao adapter do Grid.

Ou seja, essas regras de linhas, colunas, imagens, datas e prioridades, você aplica na lista. Abraço.
Responder
01/12/2016
vlw thiengo, entendi o que devo fazer, agora eu consigo centralizar o GridLayoutManager de 3 colunas quando tiver somente 2 ou 1 item sobrando?
minha lista sera criada atraves de um banco sqlite.
Responder
Vinícius Thiengo (0) (0)
02/12/2016
Jasian, essa questão de centralizar ainda não apliquei.

Encontrei essa discussão sobre:

http://stackoverflow.com/questions/37501582/center-items-horizontally-in-recyclerviewusing-gridlayoutmanager

Veja a resposta e se realmente funciona. Depois, se possível, volte aqui e de um feedback se ela é ou não funcional, digo, a solução do link acima. Abraço.
Responder
19/01/2017
Demorei um pouco para da uma resposta mais não funcionou quando tenha mais de 3 imagens funciona mais o layout não fica como desejado, quando te duas imagens não fica uma do lado da outra elas aparecem em lista.
tem alguma outra solução de apresentar itens na tela sem usar os ...layoutmanager ? mais usando o recyclerview.
Responder
Vinícius Thiengo (0) (0)
19/01/2017
Jasian, tentou com o StaggeredGridLayoutManager?

No atual projeto que estou trata;hando eu tinha de colocar imagens em grade, com o GridLayoutManager ficou muito ruim, o espaçamento mudava muito com o rotacionamento da tela ou com telas maiores.

Com StaggeredGridLayoutManager tenho sempre o mesmo espaçamento, o definido no layout do item do RecyclerView.

Em meu caso o layout é expandido com o gerenciamento do StaggeredGridLayoutManager. Somente defino a quantidade de colunas e a orientação da grade.

Veja se utilizando ele consegue o layout desejado. Abaixo o trecho de código que estou utilizando:

ArrayList<Imagem> imagens = Mock.criarGaleriaAleatorio();
RecyclerView rvGaleria = (RecyclerView) findViewById(R.id.rv_galeria);
StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(4, StaggeredGridLayoutManager.VERTICAL );
GaleriaAdapter adapter = new GaleriaAdapter(imagens);

layoutManager.setAutoMeasureEnabled(true);
rvGaleria.setNestedScrollingEnabled(false);
rvGaleria.setHasFixedSize(false);
rvGaleria.setLayoutManager( layoutManager );
rvGaleria.setAdapter(adapter);

Precisei de algumas configurações extras, pois meu RecyclerView está dentro de um NestedScrollView, mas somente o:

?
ArrayList<Imagem> imagens = Mock.criarGaleriaAleatorio();
RecyclerView rvGaleria = (RecyclerView) findViewById(R.id.rv_galeria);
StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(4, StaggeredGridLayoutManager.VERTICAL );
GaleriaAdapter adapter = new GaleriaAdapter(imagens);

rvGaleria.setHasFixedSize( true );
StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(4, StaggeredGridLayoutManager.VERTICAL );
rvGaleria.setLayoutManager( layoutManager );
rvGaleria.setAdapter(adapter);
?

Seria o suficiente para ti se não estiver também dentro de um layout com scroll automático. Abraço.
Responder
19/01/2017
Boa noite thiengo,
não resolveu, pois tenho o mesmo problema os item ficam sempre alinhados a esquerda e preciso que fiquem no meio centralizados.
a montagem dos item e da esquerda para a direita eu precisava que fosse da direita para a esquerda.
Responder
Vinícius Thiengo (0) (0)
20/01/2017
Jasian, esse caso, digo, montagem de itens vindo da direita para esquerda, você somente precisa inverter a lista que é vinculada ao adaptar.

E se já tiver de iniciar com o primeiro item mais a direita, ajuste o RecyclerView para iniciar apresentando o último, que no caso seria o primeiro. Com um código similar ao de baixo você consegue isso, apresentar o mais a direita primeiro:

?
recyclerView.scrollToPosition( position );
?

Para apresentar as imagens na horizontal, utilize o LinearLayoutManager como abaixo:

?
recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, true);
?

O RecyclerView e os LayoutManagers dele têm uma série de métodos que muito provavelmente vão lhe permitir construir o lista da maneira que desejar. Não deixe de vê-los nos links a seguir:

https://developer.android.com/reference/android/support/v7/widget/RecyclerView.html?hl=pt-br
https://developer.android.com/reference/android/support/v7/widget/RecyclerView.LayoutManager.html

Abraço.
Responder
26/01/2017
mais com o linear layout eu consigo apresentar três itens e mudar de linha? não entendi bem como devo fazer.
Responder
Vinícius Thiengo (0) (0)
26/01/2017
Jasian, nesse caso utilize o StaggeredGridLayoutManager, porém com a mesma técnica de inverter a lista que será vinculada adapter desse LayoutManager.

Depois, também com a mesma técnica apresentada em comentário anterior, acesse a última posição da lista. Assim provavelmente vai funcionar... digo provavelmente pois achei que eu tinha entendido o problema.
Responder
27/01/2017
boa tarde eu ja utilizei o o StaggeredGridLayoutManager, só que quando tem dois item ele não fica centralizado porque ele aumenta o tamando da coluna quando apresenta duas ai os itens ficam centralizados na coluna e não posso deixar assim porque tem que ficar igual http://www.sgex.eb.mil.br/sistemas/barreta/montar_barreta.php
se puder da uma olhada marque 5 itens e no final da pagina click no botão montar. talvez vendo a imagem fica mais fácil de entender.
Responder
Vinícius Thiengo (0) (0)
29/01/2017
Jasian, fiz o teste. Pode ser três ou duas colunas dependendo da escolha do usuário?

Uma outra opção é construir o layout no Java API, logo depois da escolha do usuário, pois com o LinearLayout e o atributo android:layout_weight nas Views filha dele você conseguiria, provavelmente, o que deseja no design.

Porém, caso seja possível a seleção de vários itens, isso prejudicaria a performance da APP, podendo trava-la até mais do que 5 segundos, gerando assim uma Exception. Responde ai, vamos arrumar uma solução para esse problema. Abraço.
Responder
30/01/2017
Boa tarde Thiengo ele pode escolher varios itens e pode ser uma, duas ou três colunas sendo que a principal e três e sempre a ultima linha e de duas ou uma coluna. vou dar uma olhada no Java API. Obrigado pela ajuda.
Responder
Vinícius Thiengo (0) (0)
31/01/2017
Jasian, veja se consegue seguir com a lógica a seguir:

Seu algoritmo, mais precisamente a lista de objetos que será vinculada ao adapter do RecyclerView, na verdade essa lista poderá ter em cada posição de 1 a 3 objetos, ou seja, cada posição da lista é uma outra lista.

Então seria possível trabalhar com três layouts distintos para itens no adapter do RecyclerView ou com um layout que teria a possibilidade de ter até três ImageViews, por exemplo.

Caso a posição atual da lista vinculada ao adaptar tivesse apenas 2 objetos na lista interna, um ImageView seria escondido:

?
imageView1.setVisibility( View.VISIBLE );
imageView2.setVisibility( View.VISIBLE );
imageView3.setVisibility( View.GONE );
?

Caso tivesse os três, todos estariam visíveis, e assim segue a lógica para quando tivesse apenas um objeto na lista da posição atual.

O layout então seria: http://pastebin.com/btTfAp29

No adapter do RecyclerView você consegue vincular listeners de cliques para cada ImageView caso sua lógica de negócio requeira processamento diferentes para cliques em imagens diferentes.

Note que para as imagens preencherem todo o espaço horizontal você terá de te-las com os tamanhos de largura mínimos como os do link a seguir: http://stackoverflow.com/a/13228830/2578331

Isso devido as diferentes densidades de tela para devices que têm o Android instalado. No link acima ignore os valores de height, esse se adequará aos tamanhos de with necessários nas imagens.

Há inúmeras outras soluções, veja se a anterior lhe ajuda. Abraço.
Responder
03/02/2017
Boa noite Thiengo.
não entendi muito bem como fazer esta modificação no adapter então estou mandando o link dos codigos.

Adapter
http://pastebin.com/9LDqGy2H

MontarBarretaActivity
http://pastebin.com/2yCDwi2n

montarbarreta_barreta.xml
http://pastebin.com/KsPECPCb

activity_montar_barreta.xml
http://pastebin.com/UdmpJnfZ
Responder
15/02/2017
bom dia.
tentei fazer igual me disse mais ainda não deu, ja consegui criar a array de array so que quando ele faz a primeira linha esta tudo certo mais quando passa pra segunda linha o ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) não muda o valor do i

como mosta o log

02-15 10:10:08.975 3131-3131/br.com.jasianjpc.sismedal D/Jasian: verificando o Banco
02-15 10:10:08.975 3131-3131/br.com.jasianjpc.sismedal D/Jasian: todos os dados no Banco
02-15 10:10:13.615 3131-3131/br.com.jasianjpc.sismedal D/Jasian: todos as barretas do usuario
02-15 10:10:13.615 3131-3131/br.com.jasianjpc.sismedal D/Jasian: Barretas = 4
02-15 10:10:13.615 3131-3131/br.com.jasianjpc.sismedal D/Jasian: Div = 1
02-15 10:10:13.615 3131-3131/br.com.jasianjpc.sismedal D/Jasian: Mod = 1
02-15 10:10:13.615 3131-3131/br.com.jasianjpc.sismedal D/Jasian: Linhas = 2
02-15 10:10:13.615 3131-3131/br.com.jasianjpc.sismedal D/Jasian: Mod case 1= 1
02-15 10:10:13.615 3131-3131/br.com.jasianjpc.sismedal D/Jasian: ArrayBarretas na posição= 0ArrayBarretas interno = 0
02-15 10:10:13.615 3131-3131/br.com.jasianjpc.sismedal D/Jasian: ArrayBarretas na posição= 1ArrayBarretas interno = 0
02-15 10:10:13.615 3131-3131/br.com.jasianjpc.sismedal D/Jasian: ArrayBarretas na posição= 1ArrayBarretas interno = 1
02-15 10:10:13.615 3131-3131/br.com.jasianjpc.sismedal D/Jasian: ArrayBarretas na posição= 1ArrayBarretas interno = 2
02-15 10:10:13.615 3131-3131/br.com.jasianjpc.sismedal D/Jasian: MontarBarretaActivity no recyclerview.setLayoutManager
02-15 10:10:13.625 3131-3131/br.com.jasianjpc.sismedal D/Jasian: ViewHolder onCreateViewHolder 1
02-15 10:10:13.625 3131-3131/br.com.jasianjpc.sismedal D/Jasian: ViewHolder onCreateViewHolder case 1 1
02-15 10:10:13.635 3131-3131/br.com.jasianjpc.sismedal D/Jasian: ViewHolder onCreateViewHolder fora do switch view1
02-15 10:10:13.635 3131-3131/br.com.jasianjpc.sismedal D/Jasian: ViewHolder itensBarretas 1
02-15 10:10:13.635 3131-3131/br.com.jasianjpc.sismedal D/Jasian: ViewHolder itensBarretas case 11
02-15 10:10:13.635 3131-3131/br.com.jasianjpc.sismedal D/Jasian: onBindViewHolder 1
02-15 10:10:13.635 3131-3131/br.com.jasianjpc.sismedal D/Jasian: onBindViewHolder itensBarretas1
02-15 10:10:13.635 3131-3131/br.com.jasianjpc.sismedal D/Jasian: ViewHolder onCreateViewHolder 1
02-15 10:10:13.635 3131-3131/br.com.jasianjpc.sismedal D/Jasian: ViewHolder onCreateViewHolder case 1 1
02-15 10:10:13.635 3131-3131/br.com.jasianjpc.sismedal D/Jasian: ViewHolder onCreateViewHolder fora do switch view1
02-15 10:10:13.635 3131-3131/br.com.jasianjpc.sismedal D/Jasian: ViewHolder itensBarretas 1
02-15 10:10:13.635 3131-3131/br.com.jasianjpc.sismedal D/Jasian: ViewHolder itensBarretas case 11
02-15 10:10:13.635 3131-3131/br.com.jasianjpc.sismedal D/Jasian: onBindViewHolder 3
02-15 10:10:13.635 3131-3131/br.com.jasianjpc.sismedal D/Jasian: onBindViewHolder itensBarretas1

http://pastebin.com/PBRBJtyV
Responder
Vinícius Thiengo (0) (0)
19/02/2017
Jasian, faça o seguinte.

No onCreateViewHolder(0 você vai trabalhar somente com um layout, o que tem os três imageViews.

No onBindViewHolder() você vai colocar a lógica para saber se há um item, dois itens ou três itens. Digo, a lógica para:

- Se houver somente um item, esconda com o setVisibility( View.GONE ) dos dois últimos ImageView, esses ImageViews;

- Se houverem dois itens, esconda com o setVisibility( View.GONE ) do último ImageView, esse ImageView e com o setVisibility( View.VISIBLE ) do penúltimo ImageView, apresente-o, pois devido a reciclagem de layout, pode ser que ele tivesse GONE pelo uso anterior;

- Se houverem três itens, utilize para os dois últimos ImageViews o setVisibility( View.VISIBLE ) deles.

Não esqueça de construir um layout com o root sendo um LinearLayout com o android:orientation=?horizontal" e como filho três tags <ImageView> com os atributos:

android:layout_weight=?1?
android:layout_width=?0dp?
android:scaleType=?center?
android:layout_height=?voce_defini_de_acordo_com_as_imagens?

No onBindViewHolder() pode utilizar o if?else, não precisa de switch(). Veja se assim consegue seguir com a construção do projeto. Abraço.
Responder
Ewerton (2) (0)
05/11/2015
Thiengo blz? no onLongPress do RecyclerView como faria pra mostrar um menu de opções para aquele item, como editar e excluir? Tipo um ContextMenu. Obrigado.
Responder
Vinícius Thiengo (1) (0)
07/11/2015
Responder
Ewerton (1) (0)
08/11/2015
Muito obrigado Thiengo, era isso mesmo que precisava.
Responder
02/10/2015
Fala Thiengo, blz? Parabéns pelos vídeos, estou aprendendo muito com eles. Bom Thiengo, estou com certa dificuldade na questão das colunas do GridLayoutManager, no modo retrato coloquei para aparecer duas colunas, mas no modo landscape queria que aparecesse três colunas. Como faço isso?
Responder
Vinícius Thiengo (0) (0)
03/10/2015
Fala Caio, blz sim.
O que pode fazer é instanciar seu GridLayoutManager somente depois de verificar se o device está em portrait ou landscape mode, veja essa resposta do stackoverflow para ver um exemplo dessa verificação  (http://stackoverflow.com/a/6081574/2578331 ). Dessa forma, quando em Landscape instancie com 3 colunas e 2 em Portrait. Abraço
Responder
04/10/2015
Valeu Thiengo, deu certo aqui, muito obrigado! Abraço.
Responder
26/09/2015
Bom dia! ... No caso estou trabalhando com objetos, quando clico encima, preciso pegar esse objeto para trabalhar com ele (excluir, editar), no caso como fazerei isso?
Responder
Vinícius Thiengo (0) (0)
26/09/2015
Fala Ruan, blz?
Vc consegue acessar o objeto no listener de click implementado no adapter do RecyclerView, veja o listener simples nesse vídeo (http://www.thiengo.com.br/recyclerview-material-design-android-parte-2 ). Depois disso pode plotar um Dialog (http://www.thiengo.com.br/material-dialog-correcao-bug-statusbar-e-acoes-nos-fragments-material-design-android-parte-7 ) com botões de deletar ou editar. Caso editar vc pode abrir uma nova Activity somente com os dados desse objeto, em caso de deletar apenas remova da lista esse objeto (a lista que está vinculada ao adapter do RecyclerView) e então de um notifyDataSetChanged() no adapter ou utilize a versão mais otimizada que utilizei no vídeo indicado acima, onde somente o item removido do Recycler é atualizado. Abraço
Responder
08/10/2015
blz fera?

Seguinte quando eu chamo uma nova Activity quando clico no meu alterar ou em outro caso, usando esse metodo de click, ele vai pra Activity , mais quando volto, ele repassa no click e abre de novo a activity .... tentei procurar o erro, unica forma que achei é colocar o click no Adapter, mais queria fazer dessa maneira, onde o click esta no fragment!
Responder
Vinícius Thiengo (0) (0)
10/10/2015
Ruan, verifique se na primeira vez que o click está sendo realizado, se o listener de click não está sendo disparado duas vezes, pois o que pode estar acontecendo é isso, dando a impressão de que o click está sendo acionado novamente, quando já tem duas da mesma Activity na pilha de Activities. A "jogada" está em controlar a lista que é vinculada ao adapter do Recycler, pois com ela, não importa se o click está vinculado via fragment ou adapter, vc consegue atualizar ela em qualquer um desses lugares, até mesmo na Activity que contém o fragment, caso ela tenha vindo de lá. A ultima versão da APP no GitHub funciona sem problemas com o listener no adapter desligado (o context Menu vai parar de funcionar), link: https://github.com/viniciusthiengo/tc-material-design . Abraço
Responder
19/09/2015
Amigo Tiengo...  Na sua vídeo aula vc ensinou a fazer o onclick  porém no *RecyclerView* não tem aquela animação de click sabe? Aquela de que dependendo o lugar q vc clica surge uma bola e vai crescendo enquanto o dedo eh segurado. O listView já tem isso por padrão, mas pelo que notei o RecyclerView não tem...  Sabe me ensinar a fazer isso?  Notei que no seu App aqui também não tem.
Responder
Vinícius Thiengo (1) (0)
19/09/2015
Fala Ronaldo, blz?
O nome é Ripple Effect, dê uma olhada nesse vídeo tuto do SlideNerd, nele é bem explicado como utilizar o Ripple (https://www.youtube.com/watch?v=qvVkDb7DqCk ). É em inglês, mas dá para acompanhar o código sem problemas (provavelmente vou ter de fazer esse vídeo, passei direto dele). Abraço
Responder
wagner (1) (0)
10/07/2015
Thiengo Parabéns pelos vídeos são ótimos.  A minha dúvida é a seguinte tenho um recyclerview e dentro tenho um checkebox, quando marco um checkebox e rolo a barrinha de scroll ele mostra outro checkebox marcado, mas na verdade só marquei um, vc sabe porque isso acontece? Vc tem alguma referência de multiselect no recyclerview? Muito obrigado.
Responder
Vinícius Thiengo (1) (0)
11/07/2015
Fala Wagner, blz?
O que está acontecendo é que o RecyclerView reutiliza as vies dos itens para reconstruir os próximos itens, otimização de uso da memória. Porém ele reutiliza as views da maneira que elas foram utilizadas na última vez, com o mesmo estado.

O que vai fazer é utilizar uma lista de objetos do tipo de uma classe que vc vai criar, por exemplo, classe Produto. Além de "n" atributos que essa classe vai ter, terá um atributo para gravar o estado do Checkbox, uma boolean. Assim, cada objeto da lista que será vinculada ao seu adapter será o objeto responsável por criar o item atual da lista, fornecendo os labels e o estado do checkbox, ou seja, terá um condicional informando se o checkbox deverá ser apresentado marcado ou não, esse condicional utilizará o atributo do checkbox de cada objeto, o mesmo que foi comentado anteriormente. O checkbox deverá ter tb um listener, pois assim que o estado dele mudar seu script vai utilizar o item da lista na posição alterada para alterar o valor do atributo flag do tipo boolean que é referente ao estado do checkbox daquele item no RecyclerView. Veja se consegue implementar essa lógica ai, pois assim deve funcionar sem problemas. Abraço
Responder
wagner (1) (0)
12/07/2015
Muito obrigado pelas dicas, vou tentar implementar.
Responder
wagner (1) (0)
12/07/2015
Thiengo, muito obrigado, funcionou demais.
Responder
02/06/2015
Qual recurso devo utilizar para agrupar as informações da mesma forma que o app 'Grana' agrupa as parcelas do dia?
É um recyclerview também?

App: https://play.google.com/store/apps/details?id=com.renanferrari.grana

Obs.: A primeira imagem do app mostra o agrupamento de parcelas por dia.
Responder
Vinícius Thiengo (1) (0)
03/06/2015
Fala Maicon, blz?
É difícil dizer que eles estão sim utilizando o RecyclerView, porém com o RecyclerView é sim possível fazer esses agrupamentos, coloque ai alguns layouts personalizados e os chame via condicionais (if...else) no onBindViewHolder() trabalhando como filtro... deve ser no onBindViewHolder(), pois ele é chamado sempre. Abraço
Responder
03/06/2015
Valeu Thiengo...
Vou trabalhar neste formato e ver qual resultado consigo obter.
Muito obrigado!
Responder
arielaluno (0) (0)
29/05/2015
tem algum vídeo que faz esse efeito de foto como do app younha
Responder
Vinícius Thiengo (0) (0)
30/05/2015
Não, de efeito em foto não tenho ainda. Abraço
Responder
arielaluno (1) (0)
29/05/2015
oppa thiengo vc postou algum
video de efeito de transação de tela e um video manipulando datas do proprio celular Parabén peloa videos
Responder
Vinícius Thiengo (0) (0)
30/05/2015
Opa, blz?
Não ainda, mas o de transitions (incluindo entre telas) é provavelmente o próximo que farei. Abraço
Responder
Danilo (2) (0)
10/05/2015
Boa Noite Thiengo.Primeiramente, Parabéns pelo vasto material de qualidade. Estou iniciando desenvolvimento para Android há pouco tempo. Vendo sua aula de Recyclerview, gostaria de saber, se possível, como seria para popular o recyclerview a partir de uma requisição a uma base remota (Web service restful retornando Json). É aconselhável utilizar searchview para fazer buscas a webservices? Desde já agradeço.
Responder
Vinícius Thiengo (0) (0)
10/05/2015
Fala Danilo, blz?
Com a resposta em JSON do server, vc apenas realiza o parser JSON (http://www.thiengo.com.br/parser-json-no-android-entendendo-e-utilizando ) no Android, preenche a lista do tipo de dado que veio wrapped pelo json (Carro, Casa, Loja, ...) e então vincula a lista ao adapter do RecyclerView. Mais ou menos o que faço nesse vídeo (http://www.thiengo.com.br/carregando-dados-no-listview-com-onscrolllistener-e-volley-no-android ), porém nele estou com o ListView, mas é bem similar a ideia.

Sobre o SearchView, na verdade ele mesmo não terá vinculação nenhuma com o WebService, pois o Android não permiti essa ligação direta, porém vc pode utilizar a lib volley no background, pegando o valor do searchView, passando para o Volley e então o Volley realiza a requisição ao WebService esperando obter uma resposta. É assim que faço, porém utilizo a busca local tb, guardando os dados no SQLite, permitindo a APP trabalhar offline. Abraço
Responder
Ronnie (1) (0)
17/05/2015
Olha eu aqui de novo ... rs .... percebi que mesmo sem internet eu navego em praticamente todo seu app, deixando de carregar somente as imagens, que bruxaria é essa??? vc salva a resposta json todo numa base sqlite local ??? aquele abraço ;)
Responder
Vinícius Thiengo (0) (0)
18/05/2015
Fala Ronnie, blz?
É isso mesmo, todo dado que entra o APP salva no SQLite local. Abraço
Responder
Danilo Araújo (1) (0)
04/05/2015
Vlw pelo vídeo, Thiengo.
Mais uma dúvida.
Você tem alguma solução para o problema do número de itens de um recycledview. Por exemplo: Se eu sempre carregar um número fixo de itens pode existir casos que em aparelhos de resolucao e dpi altas o número de itens não seja suficiente para gerar o scroller e o método onScrolled não será chamado. Por outro lado, se eu carregar muitos pra ter certeza que o scroller foi gerado, poderá gerar problemas de desperdício de memória.
Grato.
Responder
Vinícius Thiengo (0) (0)
05/05/2015
Danilo, na verdade ele vai chamar o onScroll sim, se me lembro bem, mesmo sem a tela toda está preenchida com itens, assim que o user tocar na tela ele dispara o evento do onScroll. Mas o que recomendo é que carregue uma quantidade de itens que vc sabe que sempre passará da tela, por exemplo, no caso da APP do Blog, eu carrego uma quantidade que sei que ocupará até mesmo telas de alta resolução e grandes e mesmo assim não carrego mts itens de uma vez só do server. Se estiver carregando 10 hj, pode colocar para carregear 20, ou até mesmo carregar 20 somente na primeira vez, depois volte para o dez quando estiver rolando para baixo o scroll. Abraço
Responder
03/05/2015
Boas Thiengo ;)
Eu sou novo nisto, desculpa a minha ignorância mas têm forma de fazer getView de qualquer posicão, ou seja, eu tenho uma lista de items e algum deles não estão visiveis (só são vistos se fizer scroll), e eu queria pegar a view de qualquer um, têm como ?
Obrigado e abraço ;)
Responder
Vinícius Thiengo (0) (0)
03/05/2015
Fala Pedro, blz?
Na verdade não tem como, pois o RecyclerView trabalha de forma otimizada e consequentemente ele reutiliza as views para apresentar itens da lista. Ou seja, se sua lista tem 100 itens, o RecyclerView utilizará apenas alguns Views (a quantidade que preenche a tela e mais alguns), pois serão o suficiente para serem reaproveitados para colocarem os itens na tela. Se está querendo acessar qualquer item, acesse eles diretamente da lista / array que foi passada para o RecyclerView, é até mais fácil. Abraço
Responder
Marco André (1) (0)
27/04/2015
Vinicius, Parabéns pelo site você com certeza tem ajudado muitas pessoas com esta iniciativa.
Estou com uma duvida, quando utilizado o RecyclerView para criar um chat utilizando "setReverseLayout(true)" para criar um "CHAT".
O Problema é o seguinte o RecyclerView ocupa toda a tela e não aceita o parametro "android:layout_height="wrap_content".

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android "
    xmlns:tools="http://schemas.android.com/tools "
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    
    <android.support.v7.widget.RecyclerView
        android:id="@+id/rv_list"
        android:scrollbars="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        />



    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:background="@drawable/back"
        android:orientation="horizontal"
        android:padding="5dp" >

        <EditText
            android:id="@+id/edComentario"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_weight="3"
            android:ems="10"
            android:textColorHint="@color/black"
            android:textColor="@color/black"
            android:gravity="top|left"
            android:maxLength="195"
            android:inputType="textMultiLine"
            android:hint="Digite um comentário...">"
            <requestFocus />
        </EditText>

        <ImageButton
            android:id="@+id/btComentario"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_weight="1"
            android:background="@color/White"
            android:src="@drawable/ic_action_social_send_now" />
    </LinearLayout>


</LinearLayout>



Agora caso eu inverta e coloque o <LinearLayout> antes do RecyclerView ele funciona.

Obrigado desde já, abraço!
Responder
Vinícius Thiengo (1) (0)
28/04/2015
Fala Marco, blz?
Trabalhe com peso no RecyclerView para ver se funciona sem problemas. Peso no caso seria o atributo android:layout_weight="1" com o android:layout_height="0dp". Abraço
Responder
Marco André (2) (0)
28/04/2015
Vinícius muito obrigado, funcionou!! Abraço
Responder
rodrigues.brodrigues (1) (0)
20/04/2015
Thiengo como faco o loading que tem no seu app? enquanto ele esta carregando a tela e as listas?
Responder
Vinícius Thiengo (0) (1)
20/04/2015
Fala Rodrigues, blz?
Todo o conteúdo fica dentro de um FrameLayout (que tem o comportamento de empilhar Views), porém todo o conteúdo útil (listas, posts, ...) fica dentro de um ViewRoot que está dentro do FrameLayout e dentro desse FrameLayout tem tb um ProgressBar (view irmã do ViewRoot com conteúdo útil), logo quando abro a APP o ProgressBar está visivel e centralizado enquanto o ViewRoot está escondido, assim que o Volley Android me retorna uma resposta eu verifico se foram retornados dados, se sim o script os coloca na tela logo depois de esconder o ProgressBar, caso nada tenha sido retornado o script verifica se há dados no SQLite, porém de qualquer forma o ProgressBar é escondido e então alguma informação é apresentada (os dados de post ou um aviso informando que não há dados disponíveis). Abraço
Responder
alessandrobarreto50 (1) (0)
21/04/2015
Thiengo como faço para utilizar a lib volley no android studio? Eu não consigo importa ela e compilar ela.
Responder
Vinícius Thiengo (0) (0)
21/04/2015
Alessandro, coloque a linha abaixo em seu gradle:

compile 'com.mcxiaoke.volley:library:1.0.6'

dessa forma deve rodar. Abraço
Responder
Oliver (1) (0)
16/04/2015
Simplesmente Fantástico!
Parabéns! Estou aprendendo muito.
Pretende abordar buscas com recicleview igual a app do site? Poderia adiantar algum link da documentação?
Abraços!
Responder
Vinícius Thiengo (0) (0)
16/04/2015
Fala Oliver, blz?
Provavelmente vou abordar esse assunto sim. Par ir adiantando leia esses (abaixo) da documentação (peguei deles tb para por na APP). Abraço

http://developer.android.com/guide/topics/search/search-dialog.html

http://developer.android.com/training/search/setup.html

http://developer.android.com/guide/topics/search/searchable-config.html
Responder
Ruan Alves (1) (0)
16/04/2015
Primeiramente te parabenizar! Queria tirar uma dúvida, sobre a questão das versões, tipo nao utiliza mais ActionBar, muitas das coisas que aprendemos, ou como eu que está começando agora, é bom pegar esse conteúdo novo, ou tb revisar os conteúdos antigos? Estou meio perdido sobre está questão ... Pois a versões antigas de android ... Grato!
Responder
Vinícius Thiengo (1) (0)
16/04/2015
Fala Ruan, blz?
Etão, já comece com o conteúdo novo (Toolbar, RecyclerView, ...), pois além deles terem suporte para versões anteriores do Android as entidades antigas (ActionBar, ListView, GridView, ...) ou já estão depreciadas ou provavelmente vão estar logo. Tende em mente que as novas entidades tb tendem a ser mais eficientes. Abraço
Responder
Rua Alves (1) (0)
16/04/2015
Obrigado! ... No caso a logica, igual Fragments, isso não muda, so o conteúdo de designer mesmo .. que já coisa demais .. :) ....
Responder
Vinícius Thiengo (0) (0)
16/04/2015
Muda a forma de utilizar devido a alguns métodos novos que são utilizados, mas não é tranquilo tb, até mais fácil que com as entidades antigas. Somente o RecyclerView que será um pouco chato dependendo do que quiser implementar (o OnClick, por exemplo), mas ai os vídeos de RecyclerView daqui d oBlog já cobrem isso para ti. Abraço
Responder
Wiliam (1) (0)
13/04/2015
Oi Thiengo, tudo bom cara? Muito show estou acompanhando todas as aulas, mas quero tirar uma duvida com vc q nao tem muito a ver com o video e parece ser meio idiota mas eu nao achei resposta em lugar nenhum,. Assim cara eu to com um projeto no qual eu criei um layout declarando ele como gone no xml e eu quero colocara ele visível via api mas eu não estou conseguindo, a forma q eu estou fazendo é a seguinte:      
<LinearLayout
            android:id="@id/fragment_B"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_weight="0.5"
            android:visibility = "gone"
            android:background="#B4B4B4"
             >
        </LinearLayout>
aqui meu codigo xml....

no java eu to pegando o id dele e estou fazendo isso:
LinearLayout.setVisibility(View.VISIBLE);

mas não ta funcionando com as imageViews ele funciona mas com o layout não. Você sabe me dizer se eu estou fazendo da maneira certa ou se existe outro método para eu fazer isso? ou se falta fazer alguma coisa com o layout q eu nao estou fazendo? Desd ja agradeço pela sua ajuda cara, valeu abraços.
Responder
Vinícius Thiengo (0) (0)
13/04/2015
Fala Wiliam, blz?
Eu teria de ver todo o XML para ver o que realmente pode ser, porém diga se quando vc não utiliza o android:visibility = "gone" se o layout aparece sem problemas, aparece? Já tentou com android:visibility = "invisible" ao invés de "gone"? Tem alguma view que disputa espaço com o LinearLayout que está utilizando peso para tamanho (android:layout_weight="1", por exemplo)? Abraço
Responder
wiliam (1) (0)
14/04/2015
Sim cara, quando eu utilizo sem o android:visibility = "gone" ele aparece sem problemas eu fiz ate um teste assim, deixei ele visivel e no codigo java eu coloquei ele pra ficar gone e nem isso funcionou, a unica coisa q me instiga um pouco é que esse layout esta servindo de container para um textView e uma View e esses dois elementos eu não coloquei neles o android:visibility = "gone" será q pode ser isso?
Responder
Vinícius Thiengo (2) (0)
15/04/2015
Wiliam, e com visibility="invisible", já testou? Pois a diferença é que o gone remove a view do xml já o invisible apenas o deixa invisível, porém mantém a view na hierarquia xml. Teste o invisible e teste tb colocando os elementos filhos no mesmo estado de seu LinearLayout. Abraço
Responder
Wiliam (1) (0)
30/04/2015
Valeu cara consegui resolver o problema, foi que eu esqueci de colocar o convertView. antes do findViewById quando eu recupero o id do layout(falta de atenção minha msm rs) msm assim muito obrigado cara, agora eu tenho uma outra duvida queria saber se vc poderia me ajudar nessa tbm. Assim, eu criei um chat tipo grupo do whatsapp e eu tenho nele um ListView onde eu preencho as mensagens q vem do bd remoto eu tenho uma classe chamada "mensagens" com os atributos mensagem, username, notificação e image. Sempre q o usuário envia uma mensagem eu crio um vetor de objetos "messages"  preencho os atributos com a mensagem, nome e etc e envio pra minha classe adapter. Quando o usuário entra no grupo eu envio do bd remoto "fulano entrou no grupo" então crio novamente esse vetor de mensagens mas só com o atributo "notificação" preenchido nos outros atributos eu coloco null e envio pro meu adapter no método "getView" eu verifico se a variável notificação é diferente de null se for eu coloco aquele layout da minha duvida anterior como VISIBLE e coloco nele a notificação e o outro layout das messagens normal eu coloco como GONE então minha lista fica dessa forma como vc ver ai na imagem --> http://i.imgur.com/etG6KoA.png  Até ai tudo bem ta funcionando legal, agora é que vem o problema, eu vou escrevendo as mensagens quando da um certo numero de mensagens por exemplo na tela cabe dez eu escrevo 20 messages ai quando eu rolo pra ver as mensagens q tao em cima ele vai colocando a notificação no lugar da mensagem e minha lista vai ficando dessa forma --> http://i.imgur.com/rZpWSzD.png  Você sabe dizer por que acontece isso? e se ja aconteceu com vc algo semelhante como vc resolveu? preciso muito dessa ajuda cara, desd ja te agradeço valeu. Abraços.
Responder
Vinícius Thiengo (1) (0)
01/05/2015
Fala Wiliam, blz?
Já vi isso já, mais de uma vez. Mt provavelmente o erro está na lógica que vc implementou no método getView(), com isso ele devolve o layout errado preenchido, mostre um print somente do getView(). Abraço
Responder
wiliam (1) (0)
02/05/2015
Da uma olhadinha aqui cara, eu não consegui achar o erro :/
parte 1 --> http://i.imgur.com/0XSFLtP.png
parte 2 --> http://i.imgur.com/qFEEy53.png

Fiz dois prints pq nao coube tudo na tela ;), mas valeu ai cara, espero q vc possa me ajudar. Abraços irmão.
Responder
Vinícius Thiengo (1) (0)
02/05/2015
Wilian, em seu primeiro condicional, quando notificação não é null, vc esconde o layout de mensagem e mostra o de notificação. Porém quando a notificação é null vc não volta o layout para VSISIBLE e coloca o de notificação como GONE, e o problema é que vc está utilizando o padrão ViewHolder, ou seja, no else vc teria de colocar o inverso do código VISIBLE e GONE do primeiro condicional. Tenta dessa forma e ve se passa. Abraço
Responder
wiliam (0) (0)
02/05/2015
Aê cara funcionoooou :D vc é foda vei. Eu só não entendi ainda o por que de acontecer isso :/ se n for muito incomodo vc poderia me dar uma breve explicação? Mas de qualquer forma obrigado msm cara, só vc pra me salvar nessas horas. Abração cara, valeu.
Responder
Vinícius Thiengo (1) (0)
03/05/2015
O que aconteceu foi que seu script está reaproveitando o layout inflado para otimizar o uso do ListView, porém somente quando era Notificação é que vc escondia parte do layout e apresentava outra, sendo assim, quando é rolado o ListView, os itens que vão aparecendo estão aproveitando layouts que já foram inflados anteriormente com outros itens, quando chegou no item que não era notificação, porém o layout reaproveitado foi o de uma notificação, ele preencheu o layout con os dados, porém não mudou a apresentação, deixando a parte de notificação oculta e mostrando a outra. Abraço
Responder
Gabriel (1) (0)
13/04/2015
Obrigado por mais um ótimo vídeo, parabéns cara!

Fiquei com uma dúvida, como ponho aquele feedback pro usuário de que o click dele é simples ou um long, em que a view vai escurecendo pouco a pouco ou tem a ação do click normal? Abraço
Responder
Vinícius Thiengo (0) (0)
13/04/2015
Fala Gabriel, blz?
Vc diz o Toast em que aparece a mensagem de feedback? Na verdade ele vai desaparecendo sozinho, mas se vc clicar nele o processo de desaparecimento é adiantado. Era isso? Aquilo é um Toast.makeText(context, message, duration).show(). Baixe o exemplo que está aqui no post disponível para download e dê uma estudada nele tb. Abraço
Responder
Gabriel (1) (0)
14/04/2015
Não era isso não, por exemplo, no Whatsapp quando você dá um longpress ele mostra um dialog, mas enquanto você ta apertando a view que está sendo clicada vai escurecendo aos poucos até ser marcada, é esse efeito. E o efeito de click normal também, quando dá um click a view escurece um pouco, bem rápido, como um button.
Responder
Vinícius Thiengo (0) (0)
15/04/2015
Ok, acho que entendi. Vc está falando do Ripple Effect no Android. Dê uma olhada nesse vídeo (https://www.youtube.com/watch?v=qvVkDb7DqCk&index=25&list=PLonJJ3BVjZW6CtAMbJz1XD8ELUs1KXaTD ) para ver como implementar. Dê uma olhada nessa lib de support (https://github.com/traex/RippleEffect ) e na resposta certa desse post (http://stackoverflow.com/questions/26686250/material-effect-on-button-with-background-color ). Respondi com Ripple, mas percebi que provavelmente o que vc quer é isso (http://stackoverflow.com/questions/2614545/animate-change-of-view-background-color-in-android ) dê uma olhada na resposta certa. Com transition vc pode mudar apenas a cor debackground. Abraço
Responder
Willian (1) (0)
21/06/2016
Alguem consegui resolver o problema do cardview duplicar o evento do onclick? Quando executo pra chamar uma nova activity ele executa duas vezes e chama a activity duas vezes.
Responder
Vinícius Thiengo (0) (0)
25/06/2016
Certificou-se de não estar passando o onClickListener (caso esteja com o onClick) mais de uma vez ao Recycler? Pergunto isso, pois nos dois vídeos sobre Recycler do blog coloquei mais de uma configuraçã de click. Abraço
Responder