Logo Passei Direto
Buscar
Material
páginas com resultados encontrados.
páginas com resultados encontrados.
left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

Prévia do material em texto

<p>CriminalIntent		(COPIE ESTE ARQUIVO PARA SUA PASTA E MARQUE TODA AULA O LOCAL EM QUE VOCÊ PAROU)</p><p>Aplicativo baseado no livro Android Programming 3rd Editon – Big Nerd Ranch</p><p>Esse aplicativo irá armazenar uma lista de “crimes de escritório” como deixar a impressora sem papel após a impressão do seu arquivo ou deixar os pratos sujos na pia para serem lavados ou esquecer de entregar um trabalho para o professor. Um registro com título, data e foto será armazenado para que seja possível enviar para um contato suspeito esses dados por e-mail, facebook ou outro aplicativo.</p><p>Inicialmente criado com a versão 3.3.1 do Android Studio.</p><p>Vá PARA A PÁGINA 3</p><p>Durante o desenvolvido deste material utilizamos a versão 3.3.2 do Android Studio.</p><p>CONFIGURAÇÃO PARA ANDROID STUDIO 3.2.1		ESTA VERSÃO É A DO LABORATÓRIO</p><p>CLIQUE EM FILE NEW</p><p>NOME DO PROJETO CriminalIntent</p><p>(as próximas janelas apenas para referência)</p><p>LEITURA</p><p>https://android-developers.googleblog.com/2019/01/android-studio-33.html</p><p>https://codelabs.developers.google.com/</p><p>http://www.fujiax.com/developer_android_/studio/releases/</p><p>Criar uma nova classe na pasta Java com.example.criminalintent utilize o botão direito do mouse, escolha New Java Class nomeie a classe como CrimeActivity</p><p>Criar um novo layout na pasta res layout utilize o botão direito do mouse, escolha New Layout resource file nomeie o layout como activity_crime</p><p>No arquivo da classe CrimeActivity.java faça a alteração no código</p><p>Se preferir abra a classe MainActivity.java. Utilize CTRL+A para selecionar e depois CTRL+C para copiar. Retorne para classe CrimeActivity.java. Utilize CTRL+A para selecionar e depois CTRL+V para colar. Altere logo após public class MainActivity com erro para public class CrimeActivity.</p><p>Abra o arquivo AndroidManifest.xml para alterar a atividade que iniciará o aplicativo. Passe de MainActivity para CrimeActivity</p><p>Criando a camada Model do aplicativo escrevendo a classe Crime.java na pasta java com.example.criminalintent</p><p>Na classe Crime.java vamos adicionar os atributos (campos ou propriedades ou variáveis) Id, title, date and status para representar o crime e um construtor para inicializar o ID e data do registro.</p><p>Ao iniciar declaração private UUID mId; o editor de código do Android Studio irá atender ao pedido da linguagem Java para que solicite a inclusão no framework do Android a classe UUID. Faça uso do ALT+ENTER e importe a classe.</p><p>A classe UUID (Universally Unique Identifier) ou GUID (Globally Unique Identifier) são técnicas de identificação de registros globais, ou seja, os seus registros recebem um id de forma que não existirá outro no mundo com o mesmo (probabilidade muito baixa de acontecer). Na prática, este tipo de identificação é muito útil para evitar problemas de segurança e evitar que softwares mal-intencionados encontrem registros desprotegidos.</p><p>Ao fazer uso do ALT+ENTER com o cursor sobre UUID surge a janela para importar a classe.</p><p>Importe a classe java.util.Date</p><p>O próximo passo é gerar os getters e setters, ou seja, vamos fazer ENCAPSULAMENTO dos dados que “transitam” em nossa classe.</p><p>Mas o que é Encapsulamento? Consiste que os atributos de uma classe não podem ser acessados diretamente. Estes métodos são seletores e modificadores dos atributos de sua classe.</p><p>O Encapsulamento nos oferece a ideia de tornar o software ou aplicativo mais flexível, fácil de modificar e de criar novas implementações. O Encapsulamento oferece um controle de acesso aos atributos e métodos de uma classe. É uma forma eficiente de proteger os dados manipulados dentro da classe, além de determinar onde esta classe poderá ser manipulada.</p><p>Um método getter é utilizado para recuperar alguma informação, geralmente utilizado para trazer informação de algum atributo, sem ter que utilizar o atributo explicitamente. Então chamamos através de métodos. Eis ai um dos princípios de OO (paradigma de programação orientação a objetos). Já o método setter é utilizado para setar (definir) um valor dentro de um objeto, de uma variável.</p><p>Por convenção são utilizados minúsculos juntamente com os nomes dos métodos, get são assessores, consultores, somente acessam, consultam determinado atributo. Os set são modificadores, esses sim alteram os atributos.</p><p>Métodos getters e setters funcionam bem, principalmente quando se utilizam frameworks, como o Hibernate, porém, eles devem ser utilizados com moderação.</p><p>Quando um atributo é do tipo boolean você não usa GET, mas sim IS. Traduzindo essa regra não existe getSolved() e sim isSolved().</p><p>O nome 'set' e 'get' em um método é uma convenção da Sun, para representar que um método faz na classe. Além disso, por convenção get e set vem em caixa baixa e a primeira letra do nome do método em caixa alta.</p><p>LEITURA https://www.devmedia.com.br/get-e-set-metodos-acessores-em-java/29241</p><p>Com o botão direito do mouse clique no construtor Crime() e escolha Generate.</p><p>Escolha Getter</p><p>Escolha a variável mId. Este membro da classe é do tipo read-only (apenas leitura).</p><p>Veja o resultado na imagem abaixo.</p><p>Com o botão direito do mouse clique no construtor Crime() e escolha Generate.</p><p>Escolha Getter and Setter</p><p>Escolha mTitle, mDate e mSolved (utilize a tecla CTRL+clique para selecionar os três)</p><p>Veja o resultado desta ação na imagem abaixo.</p><p>UI Fragments</p><p>Esse aplicativo irá utilizar Fragmentos (para anexar a foto, iniciar um outro aplicativo, enviar um e-mail). O fragmento pertence a atividade, ou seja, é interno a atividade. O sistema operacional cuida somente da atividade, ou seja, não é responsável pelo que acontece com o fragmento. A responsabilidade sobre o que ocorre com o fragmento é da atividade. Esteja atento ao ciclo de vida de cada fragmento e o ciclo de vida do aplicativo.</p><p>Você tem duas opções quando se trata de hospedar um fragmento de interface do usuário em uma atividade:</p><p>• adicionar o fragmento ao layout da atividade. É simples, mas inflexível. Se você adicionar o fragmento no layout da atividade, você vincula o fragmento e sua visualização à visão da atividade e não pode trocar esse fragmento durante a vida útil da atividade.</p><p>• adicionar o fragmento no código da atividade. É mais complexo, mas, é a única maneira de ter controle em tempo de execução do aplicativo sobre seus fragmentos. Você determina quando o fragmento é adicionado à atividade e o que acontece depois disso. Você pode remover o fragmento, substitui-lo por um outro e em seguida adicionar o primeiro fragmento novamente.</p><p>Assim, para alcançar a flexibilidade real da interface do usuário, você deve adicionar seu fragmento no código.</p><p>No arquivo activity_crime.xml iremos converte o layout para FrameLayout.</p><p>Clique com o botão direito do mouse sobre a Componet Tree.</p><p>Escolha Convert view...</p><p>Selecione FrameLayout e depois clique no botão em Apply</p><p>Altere o ID do FrameLayout para fragment_container</p><p>Observe que o FrameLayout está vazio pois a CrimeActivity não foi hospedada pelo fragmento.</p><p>Veja o modo texto do arquivo activity_crime.xml</p><p>Criando a UI Fragment</p><p>No arquivo strings.xml acrescente os seguintes pares string/valor (veja linhas 3 a 6)</p><p>Construir o layout para o CrimeFragment. Esse layout será do tipo LinearLayout vertical com dois TextViews, um EditText, um Button e um Checkbox.</p><p>Com o botão direito do mouse sobre a pasta layout escolha New Layout resource file. Informe o nome para o arquivo fragment_crime.xml e altere o root element para LinearLayout</p><p>Vá para o modo Design e arraste da janela Palette um TextView para a Componet Tree</p><p>Arraste um EditText (na imagem apresentada PlainText)</p><p>Arraste um outro TextView</p><p>Arraste um Button</p><p>Arraste um CheckBox</p><p>Observe a Component Tree</p><p>Ajustando os atributos</p><p>Para o primeiro TextView altere o atributo text para @string/crime_title_label</p><p>o EditText altere o atributo ID para crime_title, o atributo hint para @string/crime_title_hint e deixe o atributo text sem conteúdo.</p><p>Caso você não observe o atributo hint e utilize o atributo text o resultado para o usuário é que</p><p>filho seria iniciada por um fragmento da atividade pai chamando startActivityForResult(…).</p><p>Na morte da atividade filho, a atividade pai receberia uma chamada para onActivityResult(…), que seria encaminhada para o fragmento que iniciou a atividade filho.</p><p>Veja a imagem abaixo que apresenta a comunicação de interatividade em telefones</p><p>Fig.12.11-liv243-pdf877</p><p>Em um tablet onde você tem bastante espaço geralmente é melhor apresentar um DialogFragment ao usuário para obter a mesma entrada. Nesse caso, você define o fragmento de destino e chama show(…) no fragmento da caixa de diálogo. Quando descartado, o fragmento de diálogo chama onActivityResult(…) em seu destino.</p><p>Fig.12.12-liv244-pdf878</p><p>O onActivityResult(...) do fragmento sempre será chamado se o fragmento iniciou uma atividade ou mostrou um diálogo. Então você pode usar o mesmo código para apresentações diferentes.</p><p>Ao configurar as coisas para usar o mesmo código para um fragmento de tela inteira ou um fragmento de caixa de diálogo, você pode substituir DialogFragment.onCreateView(…) em vez de onCreateDialog(…) para se preparar para os dois tipos de apresentações.</p><p>ToolBar</p><p>Barra de ferramenta ou barra do aplicativo ou ainda barra de ações, é um dos elementos de design mais importantes das atividades do seu aplicativo, pois ela fornece uma estrutura visual e elementos interativos que são familiares para os usuários. O uso da barra do aplicativo torna seu aplicativo consistente com outros aplicativos Android, permitindo que os usuários entendam rapidamente como operá-lo e ter uma ótima experiência. As principais funções da barra do aplicativo são:</p><p>· Um espaço dedicado para dar uma identidade ao seu aplicativo e indicar a localização do usuário no aplicativo.</p><p>· Acesso a ações importantes de uma maneira previsível, como a pesquisa.</p><p>· Suporte à navegação e alternação de visualização (com guias e listas suspensas).</p><p>Infelizmente o Toolbar precisa estar em todos os layouts. Por questões de configurações de atributos de tema e posicionamento. Se instanciar o Toolbar e adicioná-lo manualmente no layout pode ser complicado ter de configurar sua posição e adicionar todos os atributos para estilizá-lo.</p><p>A barra de ferramentas é um componente essencial de qualquer aplicativo Android bem projetado. Resumindo: a barra de ferramentas inclui ações que o usuário pode executar, fornece um mecanismo adicional para navegação e também fornece consistência e identidade visual do design.</p><p>LEITURA</p><p>https://developer.android.com/training/appbar/?hl=pt-br</p><p>https://developer.android.com/training/appbar/setting-up.html?hl=pt-br</p><p>https://pt.stackoverflow.com/questions/38883/como-usar-o-widget-toolbar</p><p>https://pt.stackoverflow.com/questions/110412/como-criar-um-toolbar-duplo?rq=1</p><p>https://pt.stackoverflow.com/questions/119448/cor-do-%C3%ADcone-toolbar-android?rq=1</p><p>https://pt.stackoverflow.com/questions/272374/toolbar-com-duas-cores-diferentes?rq=1</p><p>http://www.zoftino.com/android-toolbar-tutorial</p><p>https://stackoverflow.com/questions/43797567/android-extend-toolbar-into-translucent-status-bar-while-keeping-other-layout-ob</p><p>https://medium.com/@lucasurbas/making-android-toolbar-responsive-2627d4e07129</p><p>https://material.io/design/layout/responsive-layout-grid.html#columns-gutters-margins</p><p>AppCompat</p><p>O componente da barra de ferramentas foi adicionado ao Android no Android 5.0 (Lollipop). Antes do Lollipop a barra de ação era o componente recomendado para navegação e ações dentro de um aplicativo.</p><p>A barra de ação e a barra de ferramentas são componentes muito semelhantes. A barra de ferramentas é construída sobre a barra de ação. Ele tem uma interface do usuário ajustada e é mais flexível nas maneiras que você pode usá-lo.</p><p>A biblioteca AppCompat permite que você forneça uma barra de ferramentas Lollipop em qualquer versão do Android anterior a API 9 (Android 2.3).</p><p>LEITURA</p><p>https://developer.android.com/topic/libraries/support-library/?hl=pt-br</p><p>https://developer.android.com/topic/libraries/support-library/features?hl=pt-br</p><p>Usando a biblioteca AppCompat</p><p>Você já está usando a biblioteca AppCompat. Novos projetos vêm com isso automaticamente. Mas e se você precisar adicionar a biblioteca AppCompat a um projeto legado? AppCompat tem alguns requisitos que você precisa conhecer.</p><p>A biblioteca AppCompat requer que você:</p><p>· adicione a dependência do AppCompat</p><p>· use um dos temas do AppCompat</p><p>· garanta que todas as atividades sejam uma subclasse de AppCompatActivity</p><p>Atualizando o tema</p><p>A biblioteca AppCompat vem com três temas:</p><p>· Theme.AppCompat - um tema escuro</p><p>· Theme.AppCompat.Light - um tema claro</p><p>· Theme.AppCompat.Light.DarkActionBar - um tema claro com uma barra de ferramentas escura</p><p>O tema para seu aplicativo é especificado no nível do aplicativo e, opcionalmente, por atividade no seu AndroidManifest.xml. Abra o AndroidManifest.xml e observe a tag do aplicativo. Observe o atributo android:theme.</p><p>Fig.13.1-liv248-pdf893</p><p>Usando AppCompatActivity</p><p>O requisito final para usar a biblioteca AppCompat é garantir o funcionamento de todas as suas atividades que utilizam a subclasse AppCompatActivity. Temos utilizado a AppCompatActivity como implementação do fragmento, portanto, nenhuma alteração é necessária.</p><p>Menus</p><p>A área superior direita da barra de ferramentas é reservada para o menu da barra de ferramentas. O menu consiste em itens de ação (às vezes também chamados de itens de menu), que podem executar uma ação na tela atual ou no aplicativo como um todo. Você adicionará um item de ação para permitir que o usuário crie um novo crime.</p><p>Nosso menu exigirá alguns recursos de string. Adicione-os em strings.xml. Essas strings podem parecer misteriosas neste momento, mas é bom cuidar delas. Quando você precisa deles mais tarde, eles já estarão no lugar, e você não terá que parar o que está fazendo para adicioná-los. Estamos antecipando a programação no futuro</p><p>Observou algo de diferente na linha 12? Quando utilizamos, por exemplo, %1$d estamos informando que aquela string é dinâmica, ou seja, seu conteúdo muda de acordo com o uso do aplicativo. Tem usos básico e para plural.</p><p>LEITURA</p><p>https://developer.android.com/guide/topics/resources/string-resource?hl=pt-br</p><p>https://stackoverflow.com/questions/3656371/dynamic-string-using-string-xml</p><p>Criando o menu fragment_crime_list</p><p>Clique com o botão direito do mouse na pasta res</p><p>Informe o nome do arquivo fragment_crime_list altere o Resource type para Menu e por fim indique o Directory name como menu (em minúsculo).</p><p>LEITURA</p><p>https://stackoverflow.com/questions/50271002/navigation-architecture-component-new-resource-dialog-doesnt-have-navigation</p><p>Observe que há em pastas diferentes (layout e menu) o arquivo fragment_crime_list.</p><p>Inclua um Menu Item arrastando para a COMPONENT TREE.</p><p>Altere os atributos do Menu Item</p><p>Ou no modo texto inclua o item e os seus atributos.</p><p>O atributo showAsAction indica se o item aparecerá na própria barra de ferramentas ou no overflow menu. Você informou dois valores, ifRoom e withText, para que o ícone e o texto do item apareçam na barra de ferramentas se houver espaço. Se houver espaço para o ícone, mas não para o texto, apenas o ícone ficará visível. Se não houver espaço para nenhum deles, o item será relegado ao menu flutuante.</p><p>Exemplo overflow menu</p><p>Se você tiver itens no menu flutuante, esses itens serão representados pelos três pontinhos no lado direito da barra de ferramentas.</p><p>Outras opções para showAsAction incluem always (sempre) e never (nunca). Usar always não é recomendado; é melhor usar ifRoom e deixar o SO decidir. Usar never é uma boa escolha para ações menos comuns. Em geral, você só deve colocar itens de ação que os usuários usarão com frequência na barra de ferramentas para evitar a confusão na tela.</p><p>LEITURA</p><p>https://www.android-examples.com/overflow-menu/</p><p>https://stackoverflow.com/questions/30248628/can-i-show-icon-in-overflow-menu-of-android-toolbar/30248673</p><p>O namespace do aplicativo</p><p>Observe que fragment_crime_list.xml usa a tag xmlns para definir um novo namespace, app, que é separado da</p><p>declaração usual de namespace do Android. Este namespace de aplicativo é usado para especificar o atributo showAsAction.</p><p>Essa declaração de namespace incomum existe por motivos herdados com a biblioteca AppCompat. As APIs da barra de ação foram adicionadas primeiro no Android 3.0. Originalmente, a biblioteca AppCompat foi criada para agrupar uma versão de compatibilidade da barra de ação em aplicativos que suportam versões anteriores do Android, para que a barra de ação existisse em qualquer dispositivo, mesmo aqueles que não suportassem a barra de ação nativa. Em dispositivos que executam o Android 2.3 ou mais antigo, existem menus e seus correspondentes XMLdid, mas o atributo android: showAsAction foi adicionado somente com o lançamento da barra de ação.</p><p>A biblioteca AppCompat define seu próprio atributo showAsAction personalizado e não procura o atributo showAsAction nativo.</p><p>Usando o Android Image Asset Studio</p><p>O Android Studio tem uma ferramenta chamada Image Asset Studio que ajuda a criar ícones personalizados para o aplicativo com ícones do Material Design, imagens personalizadas e strings de texto.</p><p>Ele gera um conjunto de ícones na resolução correta para toda densidade de tela generalizada a que seu aplicativo oferece suporte. O Image Asset Studio coloca os ícones gerados recentemente em pastas específicas de cada densidade no diretório res/ do projeto. Em tempo de execução, o Android emprega os recursos corretos com base na densidade da tela do dispositivo em que seu aplicativo está sendo executado.</p><p>O Image Asset Studio ajuda a gerar os seguintes tipos de ícone:</p><p>· Ícones de inicialização</p><p>· Barra de ações e ícones de aba</p><p>· Ícones de notificação</p><p>LEITURA</p><p>https://developer.android.com/studio/write/image-asset-studio?hl=pt-br</p><p>EXPERIMENTE</p><p>http://assetstudio.androidpro.com.br/</p><p>No android o atributo android:icon e o valor @android:drawable/ic_menu_add faz referência a um ícone do sistema. Um ícone do sistema é aquele encontrado no dispositivo, e não nos recursos do seu projeto.</p><p>Em um protótipo, referenciar um ícone do sistema funciona bem. No entanto, em um aplicativo que será publicado na Google Play é melhor ter certeza do que o usuário verá em vez de deixá-lo para cada dispositivo. Os ícones do sistema podem mudar drasticamente entre dispositivos e versões do SO e em alguns dispositivos podem ter ícones do sistema que não se encaixam no restante do design do seu aplicativo.</p><p>LEITURA</p><p>https://blog.caelum.com.br/publicando-sua-app-no-google-play/</p><p>Uma alternativa é criar seus próprios ícones do zero. Você precisará preparar versões para cada densidade de tela e possivelmente para outras configurações de dispositivo. Para mais informações, acesse as diretrizes de design de ícones do Android em developer.android.com/design/style/iconography.html.</p><p>Uma segunda alternativa é encontrar ícones do sistema que atendam às necessidades do seu aplicativo e copiá-los diretamente nos recursos que podem ser desenhados no projeto.</p><p>Os ícones do sistema podem ser encontrados no diretório do Android SDK. No Windows, o local padrão é \Users\user\sdk. Você também pode verificar sua localização do SDK abrindo a janela da estrutura do projeto e selecionando a opção de localização do SDK. No diretório do seu SDK, você encontrará recursos do Android, incluindo o ic_menu_add.</p><p>A terceira e mais fácil alternativa é usar o Android Asset Studio, incluído no Android Studio. O Asset Studio permite criar e personalizar uma imagem para usar na barra de ferramentas.</p><p>Clique com o botão direito do mouse no diretório drawable e selecione New Image Asset para abrir o Asset Studio.</p><p>No campo Icon Type escolha Action Bar and Tab Icons. Em Name altere para ic_menu_add. Acione o botão Clip Art e localize o botão add</p><p>Gerando os arquivos através do Asset Studio.</p><p>Altere o menu fragment_crime_list.xml</p><p>Criando o Menu</p><p>No código os menus são gerenciados por retornos de chamada da classe Activity. Quando o menu é necessário o Android chama a Activity e o método onCreateOptionsMenu(Menu).</p><p>No entanto, seu design exige que o código seja implementado em um fragmento e não em uma atividade. O Fragment vem com seu próprio conjunto de callbacks de menu e que você implementará no CrimeListFragment. Os métodos para criar o menu e responder à seleção de um item são:</p><p>public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)</p><p>public boolean onOptionsItemSelected(MenuItem item)</p><p>Acrescente o método onCreateOptionsMenu na classe CrimeListFragment.java</p><p>Sendo necessário importe as classes Menu e MenuInflater fazendo uso de ALT+ENTER</p><p>Nesse método você chama MenuInflater.inflate(int, Menu) e passa o ID do recurso do seu arquivo de menu. Isso preenche a instância do menu com os itens definidos no seu arquivo.</p><p>Observe que você chama a implementação da superclasse de onCreateOptionsMenu(…). Isso não é obrigatório, mas é recomendável a chamada por uma questão de convenção. Dessa forma, qualquer funcionalidade de menu definida pela superclasse ainda funcionará. No entanto, é apenas uma convenção - a implementação do Fragment desse método não faz nada.</p><p>O FragmentManager é responsável por chamar Fragment.onCreateOptionsMenu(Menu, MenuInflater) quando a atividade recebe seu retorno de chamada onCreateOptionsMenu(…) do sistema operacional. Você deve informar explicitamente ao FragmentManager que seu fragmento deve receber uma chamada para onCreateOptionsMenu(…). Você faz isso chamando o seguinte método:</p><p>public void setHasOptionsMenu (boolean hasMenu)</p><p>Definindo o CrimeListFragment.onCreate(Bundle) e deixando o FragmentManager saber que CrimeListFragment precisa receber retornos de chamada do menu.</p><p>Na classe CrimeListFragment.java acrescente o método onCreate.</p><p>Execute o aplicativo e mantenha o botão +</p><p>Gire o dispositivo</p><p>Respondendo a seleções de menu</p><p>Para responder ao usuário quando pressionar o item de ação +Novo Crime será necessário adicionar um novo Crime à sua lista de crimes.</p><p>Na classe CrimeLab.java adicione um método para fazer isso.</p><p>Neste admirável mundo novo onde você será capaz de adicionar crimes a si mesmo, os 100 crimes gerados programaticamente são não mais necessários. Remova o código que gera esses crimes de CrimeLab.java.</p><p>Ou comente o código</p><p>Quando o usuário pressiona um item de ação, seu fragmento recebe um retorno de chamada para o método onOptionsItemSelected(MenuItem). Esse método recebe uma instância de MenuItem que descreve a seleção do usuário.</p><p>Embora o menu contenha apenas um item de ação, os menus geralmente têm mais de um. Você pode determinar qual item de ação foi selecionado, verificando o ID do MenuItem e respondendo adequadamente. Este ID corresponde ao ID atribuído ao MenuItem no seu arquivo de menu.</p><p>Na classe CrimeListFragment.java implemente o método onOptionsItemSelected(MenuItem) para responder à seleção do MenuItem criando um novo Crime, adicionando-o ao CrimeLab e, em seguida, iniciando uma instância de CrimePagerActivity para editar o novo crime.</p><p>Sendo necessário importe as classes MenuItem fazendo uso de ALT+ENTER</p><p>Observe que esse método retorna um valor booleano. Depois de ter manipulado o MenuItem, você deve retornar 'true' para indicar que nenhum processamento adicional é necessário. O default chama a implementação da superclasse se o ID do item não estiver em sua implementação.</p><p>Execute o aplicativo e experimente seu novo menu. Adicione alguns crimes e edite-os depois. (A lista vazia que você vê antes de adicionar qualquer crime pode ser desconcertante)</p><p>Acione o botão + Novo Crime</p><p>Digite algo e escolha uma data.</p><p>Acione o VOLTAR no seu dispositivo</p><p>Repita o procedimento.</p><p>Habilitando a navegação hierárquica</p><p>Até agora CriminalIntent depende muito do botão Voltar para navegar pelo aplicativo. Usar o botão Voltar é uma navegação chamado de navegação temporal, ou seja, leva você para onde você estava por último.</p><p>A navegação hierárquica, por outro lado, leva você até a hierarquia de aplicativos. (Às vezes é chamado de navegação ancestral.)</p><p>Na navegação hierárquica, o usuário</p><p>navega pressionando o botão (botão Up) no lado esquerdo da barra de ferramentas.</p><p>Ative a navegação hierárquica do aplicativo adicionando um atributo parentActivityName no arquivo AndroidManifest.xml.</p><p>Como funciona a navegação hierárquica</p><p>No aplicativo navegando com o botão Voltar e navegando com o botão execute a mesma tarefa. Pressionando qualquer um desses dentro do CrimePagerActivity, o usuário retornará ao CrimeListActivity. Mesmo que eles realizem o mesmo resultado, nos bastidores eles estão fazendo coisas muito diferentes. Isso é importante porque, dependendo do aplicativo, a navegação pode fazer com que o usuário retorne a várias atividades para trás na pilha.</p><p>Quando o usuário navega a partir do CrimePagerActivity uma intent como a seguinte é criada:</p><p>FLAG_ACTIVITY_CLEAR_TOP diz ao Android para procurar uma instância existente da pilha de atividades e, se houver uma, colocar todas as outras atividades fora da pilha para que a atividade que está sendo iniciada seja a mais alta possível.</p><p>Adicionando um ITEM DE AÇÃO alternativa</p><p>Vamos adicionar um item de ação que permite aos usuários mostrar e ocultar uma legenda exibindo o número de crimes da barra de ferramentas do CrimeListActivity.</p><p>Altere o arquivo fragment_crime_list.xml que está na pasta menu para incluir um item</p><p>Crie um novo método updateSubtitle() que irá definir a legenda da barra de ferramentas para exibir o número de crimes na classe CrimeListFragment.java</p><p>Sendo necessário importe as classes AppCompatActivity fazendo uso de ALT+ENTER</p><p>O método updateSubtitle() primeiro gera a string de legenda usando o método getString(int resId, Object… formatArgs), que aceita valores de substituição para os marcadores de posição no recurso de string.</p><p>Em seguida, a atividade que hospeda o CrimeListFragment é convertida em um AppCompatActivity. É importante que você se lembre que o nosso aplicativo usa a biblioteca AppCompat e todas as atividades são uma subclasse de AppCompatActivity, que permite acessar a barra de ferramentas. (Por motivos de legado, a barra de ferramentas ainda é chamada de "barra de ação" em muitos locais da biblioteca AppCompat.)</p><p>Agora que updateSubtitle() está definido chame o método em onOptionsItemSelected(...) quando o usuário pressionar o novo item.</p><p>Execute o aplicativo.</p><p>Alternando o título do ITEM DE AÇÃO</p><p>Agora o subtítulo está visível exibindo “EXIBIR SUBTÍTULO”.</p><p>Seria melhor se o item de ação alternasse seu título e função para mostrar ou ocultar a legenda.</p><p>Quando onOptionsItemSelected(MenuItem) é chamado você recebe o MenuItem que o usuário pressionou como um parâmetro. Você pode atualizar o texto do item “EXIBIR SUBTÍTULO” neste método, mas a alteração de legenda será perdida quando você girar o dispositivo e a barra de ferramentas for recriada.</p><p>Uma solução melhor é atualizar o MenuItem “EXIBIR SUBTÍTUTLO” em onCreateOptionsMenu(…) e acionar uma recriação da barra de ferramentas quando o usuário pressionar o item da legenda. Isso permite que você compartilhe o código para atualizar o item de ação no caso em que o usuário seleciona um item de ação ou a barra de ferramentas é recriada.</p><p>Adicione uma variável de membro para acompanhar a visibilidade da legenda na classe CrimeListFragment.java</p><p>Na classe CrimeListFragment.java atualize o método onCreateOptionsMenu(…) para desencadear uma recriação dos itens de ação quando o usuário pressionar no item de ação “EXIBIR SUBTÍTULO”.</p><p>Modifiquem o método onOptionsItemSelected(...) na classe CrimeListFragment.java para que seja alterado o valor do membro mSubtitleVisible ao mostrar ou ocultar a legenda na barra de ferramentas (em um momento é true e em outro é false).</p><p>Para exibir ou ocultar o subtítulo fazendo uso do método updateSubtitle() da classe CrimeListFragment.java faça a alteração no código.</p><p>Execute o aplicativo e modifique a visibilidade das legendas na barra de ferramentas. Observe que o texto do item de ação reflete a existência da legenda.</p><p>"E se..."</p><p>A programação no Android é muitas vezes como ser questionado com a expressão “E se...”. Você acredita que tem todos os ângulos cobertos e possibilidades possíveis, porém, existe o “E se...”</p><p>Existem ainda mais duas coisas a serem feitas. Primeiro, ao criar um novo crime e, em seguida, retornar a CrimeListActivity com o botão Voltar o número de crimes no subtítulo não será atualizado para refletir o novo número de crimes. Em segundo lugar, a visibilidade da legenda é perdida através da rotação do dispositivo.</p><p>A solução do primeiro problema é atualizar o texto da legenda ao retornar a CrimeListActivity. Inclua uma chamada para updateSubtitle() em onResume(). Seu método updateUI() já existe e faz a chamada em onResume() e onCreateView(…).</p><p>Adicione uma chamada para updateSubtitle() ao método updateUI() na classe CrimeListFragment.java</p><p>Execute o aplicativo e adicione um novo item.</p><p>Caso você escolha para “EXIBIR SUBTÍTULO” e na sequencia também faça a inclusão de um novo item ao retornar será apresentada o número de itens da lista</p><p>Agora repita essas etapas, mas em vez de usar o botão Voltar, use o botão na barra de ferramentas. A visibilidade da legenda será redefinida. Por que isso acontece?</p><p>Um efeito colateral e infeliz na forma como a navegação hierárquica é implementada no Android é que a atividade para a qual você navega será completamente recriada do zero. Isso significa que qualquer variável de instância será perdida e também significa que qualquer estado de instância salvo também será perdido. Essa atividade pai é vista como uma atividade completamente nova.</p><p>Não há uma maneira fácil de garantir que a legenda permaneça visível durante a navegação. Uma opção é substituir o mecanismo de navegação. Você pode chamar finish() na classe CrimePagerActivity.java para voltar à atividade anterior. Isso funcionaria perfeitamente no aplicativo, mas, não funcionaria em aplicativos com uma hierarquia mais realista, já que isso só retornaria uma atividade.</p><p>Outra opção é passar informações sobre a visibilidade das legendas como uma variável extra para a classe CrimePagerActivity.java quando for iniciado. Em seguida, anular o método getParentActivityIntent() em CrimePagerActivity para adicionar uma variável extra à Intent que é usada para recriar o CrimeListActivity.</p><p>Esta solução requer CrimePagerActivity.java para saber os detalhes de como seu pai trabalha.</p><p>Ambas as soluções são menos que ideais, e não há uma ótima alternativa. Por esse motivo, você deixará esse problema acontecer e fará o usuário clicar em "SHOW SUBTITLE" (obviamente isso não é um fardo terrível a ser feito).</p><p>Agora que o subtítulo sempre exibe o número correto de crimes vamos resolver o problema de rotação. Para corrigir esse problema, salve a variável de instância mSubtitleVisible na rotação com o mecanismo de estado da instância salvo.</p><p>Na classe CrimeListFragment.java crie a variável extra SAVED_SUBTITLE_VISIBLE e modifique os método onCreateView(...) e crie o método onSaveInstanceState(Bundle...)</p><p>Execute o aplicativo.</p><p>Utilizando o plural para exibir o número de crimes</p><p>O subtítulo não é gramaticalmente correto quando há um único crime. 1 crimes apenas não mostra a quantidade certa de atenção aos detalhes para o seu gosto. Por esta desafio, corrija este texto de legenda. Você poderia ter duas cordas diferentes e determinar qual deles usar no código, mas isso vai desmoronar rapidamente quando você localize seu aplicativo para diferentes línguas. A melhor opção é usar recursos da cadeia plural (às vezes também chamadas seqüências de quantidade).</p><p>Primeiro, defina uma string plural em seu arquivo strings.xml.</p><p>image2.png</p><p>image86.png</p><p>image87.png</p><p>image88.png</p><p>image89.png</p><p>image90.png</p><p>image91.png</p><p>image92.png</p><p>image93.png</p><p>image94.png</p><p>image95.png</p><p>image3.png</p><p>image96.png</p><p>image97.png</p><p>image98.png</p><p>image99.png</p><p>image100.png</p><p>image101.png</p><p>image102.png</p><p>image103.png</p><p>image104.png</p><p>image4.png</p><p>image105.png</p><p>image106.png</p><p>image107.png</p><p>image108.png</p><p>image109.png</p><p>image110.png</p><p>image111.png</p><p>image112.png</p><p>image5.png</p><p>image113.png</p><p>image114.png</p><p>image115.png</p><p>image116.png</p><p>image117.png</p><p>image118.png</p><p>image119.png</p><p>image120.png</p><p>image6.png</p><p>image121.png</p><p>image122.png</p><p>image123.png</p><p>image124.png</p><p>image125.png</p><p>image126.png</p><p>image127.png</p><p>image128.png</p><p>image129.png</p><p>image130.png</p><p>image7.png</p><p>image131.png</p><p>image132.png</p><p>image133.png</p><p>image134.png</p><p>image135.png</p><p>image136.png</p><p>image137.png</p><p>image138.png</p><p>image139.png</p><p>image8.png</p><p>image140.png</p><p>image141.png</p><p>image142.png</p><p>image143.png</p><p>image144.png</p><p>image145.png</p><p>image146.png</p><p>image147.png</p><p>image148.png</p><p>image149.png</p><p>image150.png</p><p>image151.png</p><p>image152.png</p><p>image153.png</p><p>image154.png</p><p>image155.png</p><p>image156.png</p><p>image157.png</p><p>image158.png</p><p>image159.png</p><p>image160.png</p><p>image161.png</p><p>image162.png</p><p>image163.png</p><p>image164.png</p><p>image165.png</p><p>image166.png</p><p>image167.png</p><p>image168.png</p><p>image169.png</p><p>image170.png</p><p>image171.jpeg</p><p>image172.png</p><p>image9.png</p><p>image173.png</p><p>image174.jpeg</p><p>image175.png</p><p>image176.png</p><p>image177.png</p><p>image178.png</p><p>image10.png</p><p>image179.png</p><p>image180.png</p><p>image181.png</p><p>image11.png</p><p>image182.png</p><p>image183.jpeg</p><p>image184.jpeg</p><p>image185.jpeg</p><p>image186.gif</p><p>image187.png</p><p>image188.png</p><p>image189.png</p><p>image190.png</p><p>image12.png</p><p>image191.png</p><p>image192.jpeg</p><p>image193.jpeg</p><p>image194.png</p><p>image195.png</p><p>image196.png</p><p>image197.png</p><p>image198.png</p><p>image199.jpeg</p><p>image200.jpeg</p><p>image13.png</p><p>image201.jpeg</p><p>image202.jpeg</p><p>image203.png</p><p>image204.png</p><p>image205.png</p><p>image206.png</p><p>image207.png</p><p>image208.png</p><p>image209.png</p><p>image210.png</p><p>image14.png</p><p>image211.png</p><p>image212.png</p><p>image213.png</p><p>image214.png</p><p>image215.png</p><p>image216.png</p><p>image15.png</p><p>image217.png</p><p>image218.png</p><p>image219.png</p><p>image220.png</p><p>image221.png</p><p>image222.png</p><p>image223.png</p><p>image224.png</p><p>image225.png</p><p>image226.png</p><p>image16.png</p><p>image227.png</p><p>image228.png</p><p>image229.png</p><p>image230.png</p><p>image231.png</p><p>image232.png</p><p>image233.png</p><p>image234.png</p><p>image17.png</p><p>image235.png</p><p>image236.png</p><p>image237.png</p><p>image238.png</p><p>image239.png</p><p>image240.png</p><p>image241.png</p><p>image242.jpeg</p><p>image243.png</p><p>image244.png</p><p>image18.png</p><p>image245.png</p><p>image246.png</p><p>image247.jpeg</p><p>image248.png</p><p>image249.png</p><p>image250.png</p><p>image251.png</p><p>image252.png</p><p>image19.png</p><p>image253.jpeg</p><p>image254.png</p><p>image255.png</p><p>image256.png</p><p>image257.png</p><p>image258.png</p><p>image259.png</p><p>image20.png</p><p>image260.png</p><p>image261.png</p><p>image262.png</p><p>image263.png</p><p>image264.png</p><p>image265.png</p><p>image266.png</p><p>image267.png</p><p>image21.png</p><p>image268.jpeg</p><p>image269.jpeg</p><p>image270.jpeg</p><p>image271.jpeg</p><p>image272.jpeg</p><p>image273.png</p><p>image274.png</p><p>image22.png</p><p>image275.png</p><p>image23.png</p><p>image276.png</p><p>image277.png</p><p>image278.png</p><p>image279.png</p><p>image280.png</p><p>image281.png</p><p>image24.png</p><p>image282.png</p><p>image283.png</p><p>image284.png</p><p>image285.png</p><p>image286.png</p><p>image287.png</p><p>image288.png</p><p>image25.png</p><p>image289.png</p><p>image290.png</p><p>image291.png</p><p>image292.png</p><p>image293.png</p><p>image294.png</p><p>image295.png</p><p>image296.png</p><p>image26.png</p><p>image297.png</p><p>image298.png</p><p>image299.jpeg</p><p>image300.jpeg</p><p>image301.png</p><p>image302.png</p><p>image303.png</p><p>image304.png</p><p>image305.jpeg</p><p>image306.jpeg</p><p>image27.png</p><p>image307.jpeg</p><p>image308.jpeg</p><p>image309.jpeg</p><p>image310.png</p><p>image311.png</p><p>image312.jpeg</p><p>image313.png</p><p>image314.png</p><p>image315.png</p><p>image316.png</p><p>image28.png</p><p>image317.png</p><p>image318.jpeg</p><p>image319.jpeg</p><p>image320.jpeg</p><p>image321.png</p><p>image322.png</p><p>image323.png</p><p>image324.png</p><p>image325.png</p><p>image326.jpeg</p><p>image29.png</p><p>image327.jpeg</p><p>image328.jpeg</p><p>image329.png</p><p>image330.jpeg</p><p>image331.jpeg</p><p>image332.png</p><p>image333.png</p><p>image334.png</p><p>image335.png</p><p>image336.png</p><p>image30.png</p><p>image31.png</p><p>image32.png</p><p>image33.png</p><p>image34.png</p><p>image35.png</p><p>image36.png</p><p>image37.png</p><p>image38.png</p><p>image39.png</p><p>image40.png</p><p>image41.png</p><p>image42.png</p><p>image43.png</p><p>image44.png</p><p>image45.png</p><p>image46.png</p><p>image47.png</p><p>image48.png</p><p>image49.png</p><p>image50.png</p><p>image51.png</p><p>image52.png</p><p>image53.png</p><p>image54.png</p><p>image55.png</p><p>image56.png</p><p>image57.png</p><p>image58.png</p><p>image59.png</p><p>image60.png</p><p>image61.png</p><p>image62.png</p><p>image63.png</p><p>image64.png</p><p>image65.png</p><p>image66.png</p><p>image67.png</p><p>image68.png</p><p>image69.png</p><p>image70.png</p><p>image71.png</p><p>image72.png</p><p>image73.png</p><p>image74.png</p><p>image75.png</p><p>image76.png</p><p>image77.png</p><p>image78.png</p><p>image1.png</p><p>image79.png</p><p>image80.png</p><p>image81.png</p><p>image82.png</p><p>image83.jpeg</p><p>image84.png</p><p>image85.png</p><p>ele terá que apagar a mensagem apresentada.</p><p>Para o segundo TextView altere o atributo text para @string/crime_details_label</p><p>Para o Button altere o atributo ID para crime_date e deixe o atributo text vazio.</p><p>Para o Checkbox altere o atributo ID para crime_solved e o atributo text para @string/crime_solved_label</p><p>Altere para o modo texto o arquivo fragment_crime.xml</p><p>No modo texto do layout acrescente as linhas 6, 9 e 24 da imagem abaixo. Pode haver diferença na numeração de linhas para o seu. Tenha atenção ao fechamento da marcação do elemento LinearLayout ></p><p>Criando a classe CrimeFragment.java</p><p>Utilizando na classe CrimeFragment a subclasse Fragment.</p><p>À medida que você informa a subclasse Fragment irá notar que o Android Studio encontra duas classes com o nome do Fragment. Você vai ver Fragment (android.app) e Fragment (android.support.v4.app). O android.app Fragment é a versão de fragmentos embutidos no Sistema operacional Android. Você irá usar o suporte desta versão da biblioteca, por isso, selecione o android.support.v4.app.</p><p>Implementando o ciclo de vida dos métodos do fragmento. Inclua a linha 7. Digite a linha 9 até observar a sugestão do Android Studio e pressione ENTER.</p><p>Acrescente a linha 12 da imagem abaixo</p><p>Há algumas coisas para notar nesta implementação. Primeiro, Fragment.onCreate (Bundle) é um método público enquanto Activity.onCreate (Bundle) está protegido. Os métodos de ciclo de vida de fragmentos ou Fragment.onCreate(…) devem ser públicos porque serão chamados por qualquer atividade que hospede o fragmento.</p><p>Em segundo lugar, semelhante a uma atividade, um fragmento tem um pacote para o qual salva e recupera seu estado. Você pode substituir Fragment.onSaveInstanceState (Bundle) para seus próprios propósitos como com Activity.onSaveInstanceState (Bundle).</p><p>Observe o que não acontece em Fragment.onCreate (…) – você não pode inflar a visualização do fragmento – será necessário você configurar uma instância de fragmento após Fragment.onCreate (…)</p><p>public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)</p><p>Esse método é onde você insufla o layout da visualização do fragmento (fragment_crime.xml) e retorna a exibição inflada (v) para a atividade de hospedagem. Os parâmetros LayoutInflater e ViewGroup são necessários para inflar o layout. O Bundle conterá dados que esse método pode usar para recriar a visualização de um estado salvo.</p><p>Em onCreateView (…), você insufla explicitamente a visualização do fragmento chamando LayoutInflater.inflate (…) e passando o ID do recurso de layout. O segundo parâmetro é o pai da chamada por este fragmento, que geralmente é necessário para configurar os widgets corretamente. O terceiro parâmetro informa o layout inflável para adicionar a exibição inflada ao pai. Passamos o valor falso porque a visualização será feita no código da atividade.</p><p>Inclua da declaração do objeto mTitleField na classe CrimeFragment (linha 13) e faça uso do objeto no método onCreateView (linha 25)</p><p>Criando os métodos do mTitleField (linha 26). Tenha atenção para usar a ajuda do Android Studio na criação.</p><p>Inclua os comentários e a instrução em onTextChanged (linha 36)</p><p>Recolha o bloco de código addTextChangedListener como apresentado na imagem abaixo.</p><p>Inclua a declaração do objeto mDateButton do tipo Button (linha 16) adicione com ALT+ENTER a classe Button.</p><p>Desativar o botão garante que ele não responde de forma alguma ao pressionamento feito pelo usuário e ao mesmo tempo é alterada a sua aparência para anunciar o estado de inatividade.</p><p>Inclua a declaração do objeto mSolvedCheckBox do tipo CheckBox (linha 19)</p><p>Inclua a referência do objeto com o item de layout (linha 53)</p><p>Dependendo da versão do Android Studio utilizada o próximo auto completar poderá ser diferente. Veja que na próxima imagem apresentada CompoundButton.OnCheckedChangeListener{...} poderá ser exibido como OnCheckedChangeListener()</p><p>Inclua a linha 58</p><p>IMPORTANTE Seu código para CrimeFragment está completo. Seria ótimo se você poderia executar CriminalIntent agora e utilizá-lo com o código que você escreveu. Mas você não pode fazer isso. Fragmentos não podem colocar suas visões na tela por conta própria. Para ver seus esforços, você primeiro tem que adicionar um CrimeFragment para uma CrimeActivity.</p><p>Adicionando uma UI Fragment para ser gerenciada com FragmentManager</p><p>Na classe CrimeActivity.java adicione a classe o objeto por gerenciar os fragmentos.</p><p>Transações de fragmentos são usadas para adicionar (add), remover (remove), conecte, desconecte ou substitua fragmentos na lista de fragmentos. As transações são o coração de como você usa fragmentos para compor e recompor telas em tempo de execução do aplicativo. O FragmentManager mantém uma pilha (back stack) de fragmentos e suas respectivas transações em que você pode navegar.</p><p>Arquitetura de aplicativos com fragmentos</p><p>Criando seu aplicativo com fragmentos o caminho certo é extremamente importante. Muitos desenvolvedores, depois de aprender sobre fragmentos, tenta usá-los para cada componente reutilizável em sua aplicação. Este é o caminho errado para usar fragmentos.</p><p>Fragmentos são destinados a encapsular componentes principais de forma reutilizável. Um componente principal neste caso seria no nível de uma tela inteira do seu aplicativo. Se você tem um significativo número de fragmentos na tela de uma vez, seu código ficará cheio de transações de fragmentos e responsabilidades pouco claras.</p><p>Uma solução arquitetônica melhor para reutilização com componentes menores é extrai-los em uma visão personalizada.</p><p>Use fragmentos com responsabilidade. Uma boa regra é ter não mais do que dois ou três fragmentos na tela de cada vez.</p><p>Exibir listas com RecyclerView</p><p>Na camada de modelo (Model) você tem um novo objeto chamado CrimeLab, que será responsável pelo armazenamento de dados centralizado para um crime.</p><p>A exibição de uma lista de crimes requer uma nova atividade e um novo fragmento na camada controladora (Controller) do aplicativo CriminalIntent são elas os objeto, respectivamente, CrimeListActivity e CrimeListFragment.</p><p>Na camada de visualização (View) será constituída de um FrameLayout contendo fragmentos. A visão do fragmento consistirá de um RecyclerView.</p><p>RecyclerView é uma “evolução” da ListView e da GridView, componentes presentes desde da primeira versão do Android para se fazer listas e grades de conteúdo. O RecyclerView é muito mais eficiente que as duas antigas implementações. Uma das grandes de suas grandes vantagens, é a flexibilidade de poder mudar de LayoutManager sem ter de implementar um caminhão de código somente para ter versões de tiles ou cards em nossa lista.</p><p>Suas principais vantagens são:</p><p>· Atualizações (melhorias, novas funcionalidades, correções e etc)</p><p>· Performance! Reuso da célula (view) ao descer/subir a lista</p><p>· Animações</p><p>· Gerenciador de layout</p><p>· No RecyclerView existe um “gerenciador de layout” que define qual será a posição dos itens na lista</p><p>· Atualização apenas de itens alterados</p><p>LEITURA</p><p>LISTAS COM RECYCLERVIEW</p><p>https://medium.com/android-dev-br/listas-com-recyclerview-d3f41e0d653c</p><p>O que é RecyclerView em Android?</p><p>https://pt.stackoverflow.com/questions/82322/o-que-%C3%A9-recyclerview-em-android</p><p>Android RecyclerView Example – Multiple ViewTypes</p><p>https://www.journaldev.com/12372/android-recyclerview-example</p><p>Voltando a programação normal</p><p>O primeiro passo é atualizar camada modelo de CriminalIntent de um objeto Crime único para uma lista de Objetos de crime. Iremos armazenar a lista de crimes em um Singleton. Um Singleton é uma classe que permite apenas uma instância de em si para ser criado.</p><p>O Singleton é um padrão de projeto de software (do inglês Design Pattern). Este padrão garante a existência de apenas uma instância de uma classe, mantendo um ponto global de acesso ao seu objeto</p><p>Um singleton existe enquanto o aplicativo fica na memória. Então, armazenando a lista em um singleton manteremos os dados do crime disponíveis em qualquer fase</p><p>do ciclo de vida das atividades e fragmentos do aplicativo. Tome cuidado com a lista de crimes, pois, eles serão destruídos quando o Android remove seu aplicativo da memória.</p><p>O Singleton CrimeLab não é uma solução para armazenamento a longo prazo de dados (não é Banco de Dados), mas permite que o aplicativo tenha um proprietário dos dados do crime e fornece uma maneira de passar facilmente esses dados entre as classes do controlador.</p><p>Na pasta java com.example.criminalIntente crie uma nova classe CrimeLab.java</p><p>Utilize o botão direito do mouse. Escolha New Java Class</p><p>Existem algumas coisas interessantes nesta implementação do CrimeLab. Primeiro, observe o prefixo s na variável sCrimeLab. Por convenção o Android Studio deixa claro que sCrimeLab é uma variável estática. Além disso, observe o construtor privado CrimeLab. Outras classes não serão capazes de criar um CrimeLab. Finalmente, no método get () em CrimeLab, você passa em um objeto como contexto objeto.</p><p>Na classe CrimeLab.java crie uma lista vazia de Crimes. Além disso, adicione o método getCrimes () que retorna o List e um getCrime (UUID) que retorna o Crime com o ID fornecido.</p><p>Digite a linha 9 para criar a lista. Pressione ALT+ENTER para importar a classe List.</p><p>Inclua a linha de código 23 e os blocos de código 26 a 28 e 30 a 37.</p><p>List <E> é uma interface que suporta uma lista ordenada de objetos de um determinado tipo (linha 13 do código acima). Isto define métodos para recuperar, adicionar, e excluir elementos.</p><p>A linha de instanciação mCrimes (linha 23) usa notação de <> que foi introduzido em Java 7. Esta notação diz ao compilador para deduzir o tipo de itens que a Lista conterá com base no argumento genérico passado na declaração da variável. Aqui o compilador irá deduzir que o ArrayList contém Crimes porque a declaração variável privada List<Crime> retorna mCrimes (linhas 26 a 28).</p><p>Antes do Java 7 os desenvolvedores para utilizar o estilo verboso do Java usariam a implementação desta forma mCrimes = new ArrayList <Crime> ();</p><p>Criando com programação uma lista de 100 crimes.</p><p>Porque activity_crime.xml não nomeia um fragmento específico, você pode usá-lo para qualquer atividade que hospede um fragmento único. Renomeie activity_fragment.xml para refletem seu escopo maior.</p><p>Na janela da ferramenta de projeto, clique com o botão direito do mouse res / layout / activity_crime.xml</p><p>(Certifique-se de clicar com o botão direito do mouse activity_crime.xml e não fragment_crime.xml.)</p><p>Renomeie este layout para activity_fragment.xml e clique em Refactor.</p><p>Quando você renomeia um recurso as referências a ele devem ser atualizadas automaticamente. Se você observar um erro no CrimeActivity.java, então você precisa atualizar manualmente a referência em CrimeActivity</p><p>Criar a classe abstrata SingleFragmentActivity.java</p><p>Esta classe será utilizada várias vezes durante a codificação do aplicativo</p><p>Altere o modificador da classe para Abstract. As classes abstratas são as que não permitem realizar qualquer tipo de instância. São classes feitas especialmente para serem modelos para suas classes derivadas. As classes derivadas, via de regra, deverão sobrescrever os métodos para realizar a implementação dos mesmos. As classes derivadas das classes abstratas são conhecidas como classes concretas.</p><p>LEITURA</p><p>Conceitos – Classes Abstratas: Programação Orientada a Objetos</p><p>https://www.devmedia.com.br/conceitos-classes-abstratas-programacao-orientada-a-objetos/18812</p><p>A classe SingleFragmentActivity é derivada (extends) da classe AppCompatActivity</p><p>Altere a classe como apresentado na linha 5</p><p>LEITURA</p><p>https://www.devmedia.com.br/entendendo-e-aplicando-heranca-em-java/24544</p><p>Neste código você define a visão da atividade para ser inflada a partir de activity_fragment.xml. Então você olha para o fragmento no FragmentManager nesse container criando e adicionando se não existir.</p><p>Usando a classe abstrata SingleFragmentActivity</p><p>Na classe CrimeActivity.java</p><p>Criando novos controladores (modelo MVC)</p><p>Adicione uma nova classe CrimeListFragment.java</p><p>Modifique a classe para estender a classe Fragment</p><p>Adicione uma nova classe CrimeListActivity.java</p><p>Modifique a classe para estender a subclasse SingleFragmentActivity e implemente o método createFragment</p><p>Agora que você criou CrimeListActivity, você deve declará-lo no manifesto. Além do mais você quer que a lista de crimes seja a primeira tela que o usuário vê quando CriminalIntent é iniciado, então, CrimeListActivity deve ser a atividade do inicialização.</p><p>No arquivo AndroidManifest.xml declare a atividade CrimeListActivity e remove o intent-filter de CrimeActivity</p><p>Fazendo uso de RecyclerView</p><p>RecyclerView é uma subclasse de ViewGroup. Ela exibe uma lista de objetos filhos do tipo View para cada item da sua lista de itens. Dependendo da complexidade do que você precisa exibir essas exibições dos objetos filhos podem ser complexas ou muito simples.</p><p>LEITURA</p><p>https://developer.android.com/guide/topics/ui/layout/recyclerview</p><p>https://www.androidpro.com.br/blog/desenvolvimento-android/listviews/</p><p>Lista utilizando RecyclerView (área azul) com várias Views (neste exemplo 6, porém, podemos ter mais de 6 itens e à medida que rolamos a tela novas Views são exibidas)</p><p>Lista utilizando CardView</p><p>Somente o RecyclerView tem a responsabilidades de reciclar os TextViews e posicioná-los na tela. Para obter os TextViews em primeiro lugar o funcionamento ocorre com a utilização de duas classes: Adapter e ViewHolder.</p><p>A ViewHolder permite visualizar e manter as informações da View.</p><p>O que é ViewHolder Pattern? É a abordagem utilizada para guardar um conjunto de views para que possam ser eficientemente acedidas e reutilizadas, quando necessário. A finalidade da classe ViewHolder é guardar as views.</p><p>Qual é a finalidade do ViewHolder Pattern? Evitar o uso repetido de findViewById() para obter as referências às views. Ao serem guardadas num objeto ViewHolder as referências estão disponíveis de imediato.</p><p>Quais são seus benefícios? Evitar a perda de performance devido ao uso repetido de findViewById().</p><p>LEITURA</p><p>https://blog.alura.com.br/utilizando-o-padrao-viewholder/</p><p>O Adapter permite o acesso aos itens de dados. O Adapter também é responsável por fazer uma exibição para cada item no conjunto de dados. Um Adapter é uma classe de Android que intermedia a criação de listas e também lida com outros tipos de componentes, como os tipos Spinner, GridView, Gallery e AutoCompleteTextView.</p><p>O Adapter é responsável por criar o ViewHolders necessário e vincular o ViewHolders aos dados da camada do modelo (MVC).</p><p>LEITURA</p><p>https://www.devmedia.com.br/listas-e-adapters-no-android/33774</p><p>A classe RecyclerView vive em uma das muitas bibliotecas de suporte do Google. O primeiro passo para usar um RecyclerView é para adicionar a biblioteca RecyclerView como dependência.</p><p>Use o botão +</p><p>Escolha Library dependency para adicionar dependência.</p><p>Localize na lista a dependência para o RecyclerView. Poderá ser apresentada uma versão diferente da imagem abaixo. Selecione a biblioteca recyclerview-v7 e clique em OK para adicionar a biblioteca como dependência.</p><p>Após o clique no botão OK aguarde a sincronização.</p><p>E SE ISSO NÃO FUNCIONAR?</p><p>Acrescente manualmente no arquivo build.gradle(Module: app) na área dependencies a SEGUINTE IMPLEMENTAÇÃO:</p><p>implementation ‘com.android.support:recyclerview-v7:28.0.0’</p><p>clique no link Sync Now e aguarde a sincronização</p><p>Crie o layout fragment_crime_list.xml</p><p>Altere a construção fragment_crime_list.xml</p><p>Vá para a classe CrimeListFragment.java e inclua as linhas 14 até 22 da imagem abaixo.</p><p>Parei aqui</p><p>Execute o aplicativo. Você deve ver novamente tela em branco, mas agora você está olhando um RecyclerView vazio.</p><p>Crie o layout list_item_crime.xml. Este novo layout para exibir um item lista de crimes.</p><p>Na janela COMPONENT TREE clique com o botão direito do mouse sobre ConstrainLayout</p><p>Escolha Convert View e selecione LinearLayout</p><p>Na janela de ATRIBUTOS altere a orientação para VERTICAL</p><p>atributo layout_width match_parent</p><p>atributo layout_height wrap_parent</p><p>Arraste um TextView</p><p>Altere os atributos ID, layout_width, layout_height e text</p><p>Arraste um outro TextView</p><p>Altere os atributos ID, layout_width, layout_height e text</p><p>Faça um pequeno ajuste ao layout – adicionando um espaço.</p><p>O Padding é o espaço dentro da View/ViewGroup, entre a borda e o conteúdo. Podemos adicionar esse espaço na parte superior, inferior, nos lados direito e esquerdo.</p><p>LEITURA</p><p>https://www.androidpro.com.br/blog/desenvolvimento-android/android-layouts-viewgroups-intro/</p><p>Poderíamos alterar o valor da margem? Para responder esta pergunta veja a principal diferença entre padding e margin se dá ao fato de que:</p><p>· o padding reserva espaço ao elemento;</p><p>· a margin apenas define o espaçamento e projeta o próprio elemento ou algum com o qual tenha contato.</p><p>Ou seja, se você aplicar background a um elemento que possua padding definido, o espaço relativo ao padding receberá cor, enquanto o mesmo elemento com margin aplicado no lugar do padding não recebe cor na área correspondente à margin.</p><p>LEITURA</p><p>Difference between a View's Padding and Margin</p><p>https://stackoverflow.com/questions/4619899/difference-between-a-views-padding-and-margin</p><p>Abra o código do arquivo list_item_crime.xml e acrescente a linha 6. Esteja atento a marcação de fechamento de bloco ></p><p>Abra a classe CrimeListFragment.java</p><p>No construtor do CrimeHolder acima você inflou o layout list_item_crime.xml.</p><p>Com o ViewHolder definido iremos partir para o Adapter.</p><p>Até concluir o getItemCount() haverá um erro de compilação.</p><p>onCreateViewHolder é chamado pelo RecyclerView quando precisar de um novo ViewHolder para exibir um item.</p><p>Agora que você tem um adaptador conecte-o ao seu RecyclerView. Implemente um método chamado updateUI que configura o CrimeListFragment UI. Por agora vai criar um CrimeAdapter e configurá-lo no RecyclerView.</p><p>Acrescente a linha 18 na classe CrimeListFragment.java na sequencia o método updateUI() linhas 31 a 36 e por último a linha 26 que faz a chamada do método.</p><p>Execute o aplicativo e caso não seja apresentada uma lista com 8 a 10 itens próximos, ou seja, itens separados sendo necessário rolar a tela muito provavelmente o atributo layout_height esteja errado. Verifique</p><p>Ligando os Dados (Binding) da lista de crimes</p><p>Na classe CrimeListFragment.java modifique o construtor CrimeHolder</p><p>Inclua as linhas 43, 44, 49 e 50</p><p>Seu CrimeHolder também precisará de um método para fazer uma ligação com o crime (bind). Isto será chamado cada vez que um novo crime deve ser exibido no seu CrimeHolder.</p><p>Na classe CrimeListFragment.java modifique o construtor CrimeHolder</p><p>Inclua as linhas 45, 54 a 58</p><p>No construtor CrimeAdapter e no método onBindViewHolder inclua as linhas 76 e 77</p><p>Execute o aplicativo e você verá uma lista com 100 crimes e as datas correspondentes. (isso foi gerado pelo código/programação)</p><p>Respondendo ao pressionamento sobre o Crime</p><p>No construtor CrimeHolder implemente View.OnClickListener</p><p>Inclua as linhas 50 e 60 a 63</p><p>Execute o aplicativo.</p><p>Criar UI com layouts e widgets</p><p>A plataforma Android possui 4 densidades principais. Isso significa que ao gerar uma imagem devemos lidar com proporções e não somente medidas.</p><p>MDPI (média), HDPI (Alta), XHDPI (Super) e XXHDPI (Altíssima), antigamente existia a densidade LDPI (baixa), mas ela já meio que foi extinta e não se usa mais. O que acontece é que os devices mais antigos usam as imagens MDPI para preencher o local onde deveriam estar as imagens LDPI.</p><p>OBSERVAÇÃO - Lembrando que densidade não é igual a tamanho de tela. Na teoria, podemos ter dispositivos com densidade de 640dpi (xxxhdpi) com resolução de 320x240 e um outro dispositivo com 120dpi e resolução 1920x1080. Mas densidade é uma métrica legal para filtrar imagens. Uma métrica mais real, porém, bem mais complicada seria combinar as dimensões de tela com a densidade.</p><p>LEITURA</p><p>https://urucumdigital.com/2015/10/15/como-funcionam-as-densidades-no-android/</p><p>https://developer.android.com/training/multiscreen/screendensities?hl=pt-br</p><p>https://pt.stackoverflow.com/questions/82601/android-como-identificar-a-densidade-da-tela-do-usu%C3%A1rio</p><p>Como o Android é executado em dispositivos com uma ampla variedade de densidades de tela, você deve sempre oferecer recursos de bitmap adaptados a cada um dos tipos de densidade generalizados: densidade média, alta, super e altíssima. Isso ajudará a obter uma boa qualidade gráfica e desempenho em todas as densidades de tela.</p><p>Para gerar essas imagens, você deve iniciar com o recurso bruto em formato de vetor (.PNG) e gerar as imagens para cada densidade usando a seguinte escala de tamanho:</p><p>· xhdpi: 2,0</p><p>· hdpi: 1,5</p><p>· mdpi: 1,0 (linha de base)</p><p>· ldpi: 0,75</p><p>Isso significa que, se você gerar uma imagem 200x200 para dispositivos xhdpi, deverá gerar o mesmo recurso em 150x150 para hdpi, 100x100 para mdpi e, por fim, uma imagem 75x75 para dispositivos ldpi .</p><p>Em seguida, coloque os arquivos de imagem gerados no subdiretório adequado em res/ e o sistema escolherá automaticamente o correto com base na densidade da tela do dispositivo onde o aplicativo está sendo executado:</p><p>MyProject/</p><p>res/</p><p>drawable-xhdpi/</p><p>awesomeimage.png</p><p>drawable-hdpi/</p><p>awesomeimage.png</p><p>drawable-mdpi/</p><p>awesomeimage.png</p><p>drawable-ldpi/</p><p>awesomeimage.png</p><p>Assim, sempre que você referenciar @drawable/awesomeimage, o sistema selecionará o bitmap apropriado baseado no dpi da tela.</p><p>Coloque os ícones da tela inicial nas pastas mipmap/.</p><p>res/...</p><p>mipmap-ldpi/...</p><p>finished_launcher_asset.png</p><p>mipmap-mdpi/...</p><p>finished_launcher_asset.png</p><p>mipmap-hdpi/...</p><p>finished_launcher_asset.png</p><p>mipmap-xhdpi/...</p><p>finished_launcher_asset.png</p><p>mipmap-xxhdpi/...</p><p>finished_launcher_asset.png</p><p>mipmap-xxxhdpi/...</p><p>finished_launcher_asset.png</p><p>getResources().getDisplayMetrics().density;</p><p>irá te retornar:</p><p>0.75 - ldpi (baixa resolução)		1.0 - mdpi (média resolução)</p><p>1.5 - hdpi (alta resolução)			2.0 - xhdpi (ótima resolução)</p><p>3.0 - xxhdpi (+ótima resolução)		4.0 - xxxhdpi (excelente)</p><p>Antes de continuar vamos copiar algumas imagens para somente depois trabalhar com ConstraintLayout. É necessário uma cópia das imagens de algema para o nosso projeto.</p><p>Navegue na pasta pública do Professor Marcos e copie a partir da pasta algemas as subpastas para a pasta drawable do projeto.</p><p>Localize a pasta algemas</p><p>CTRL+A para selecionar as pastas (todas) e depois CTRL+C para copiar</p><p>Volte para o Android Studio e clique com o botão direito sobre a pasta res e escolha PASTE</p><p>Abrir o arquivo list_item_crime.xml</p><p>Utilizando a COMPONENT TREE clique com o botão direito do mouse sobre LinearLayout (vertical) e escolha Convert LinerLayout to ConstraintLayout</p><p>O Android Studio perguntará sobre o processo de conversão. Deixe os valores padrão marcados e selecione OK.</p><p>Seu LinearLayout foi convertido para ConstraintLayout.</p><p>O ConstraintLayout foi criado, de acordo com a Build a Responsive UI with ConstraintLayout (https://developer.android.com/training/constraint-layout/index.html). A ideia é ter algo mais confiável, prático e fiel ao que vai “aparecer” no smartphone do seu usuário este novo gerenciador de layouts da plataforma Android. ConstraintLayout ajudam a criar telas com uma hierarquia mais precisa, sem precisar aninhar as views. Ou seja, sempre que você for fazer um layout relativamente complexo e que precise de um alinhamento preciso terá que usar ConstraintLayout. O objetivo desta view é justamente isso, permitir que os desenvolvedores possam otimizar as hierarquias das suas telas.</p><p>O ConstraintLayout permite que você crie layouts grandes e complexos com uma hierarquia flat no seu XML (sem a necessidade de ficar aninhando um monte de layouts uns dentro dos outros). Ele é similar ao Relative Layout, uma vez que todas suas views se relacionam entre si e com o parent, mas é mais flexível do que seu antecessor e mais fácil de usar com o Layout Editor, do Android Studio. Não obstante,</p><p>o ConstraintLayout também possui as melhores características do LinearLayout, que era sua responsividade baseada em pesos, o que nos permite interfaces mais fluidas, bem distribuídas e simples de construir. Tudo em um só layout manager!</p><p>Vantagens:</p><p>· Otimizado para hierarquias de exibição.</p><p>· Você não terá problemas se o estado de visibilidade da sua view for GONE (Essa visão é invisível e não ocupa nenhum espaço para fins de layout) o alinhamento funcionará mesmo assim e você não vai mais se preocupar com layouts quebrados. (a view pode ser INVISIBLE, essa visão é invisível e ocupa espaço para propósitos de layout)</p><p>· Editor completamente amigável.</p><p>· Fácil de usar e feito para desenhar telas responsivas.</p><p>Desvantagens:</p><p>· O layout editor vai simplesmente mover suas views sem motivo algum, isso deve ser causado quando tentamos mover uma view e acabamos clicando em outra.</p><p>· Performance. A performance em que as views são criadas é um pouco inferior se comparar ao RelativeLayout ou LinearLayout.</p><p>· O principal problema é o editor. Com o passar do tempo você vai perceber que o editor faz coisas inesperadas, então, você vai acabar preferindo por criar seus layouts manualmente o que poderá ser um pouco mais rápido.</p><p>LEITURA</p><p>https://stackoverflow.com/questions/11556607/android-difference-between-invisible-and-gone</p><p>http://tips.androidgig.com/invisible-vs-gone-view-in-android/</p><p>https://imasters.com.br/android/como-usar-o-constraint-layout-no-android</p><p>Observe a barra de controles para Constraint</p><p>Precisamos liberar algum espaço. Seus dois TextViews estão ocupando toda a área, o que tornará difícil conectar algo mais. Vamos de encolher os dois widgets.</p><p>Observe os ajustes para layout_width wrap_content e layout_height wrap_content</p><p>Adicione um ImageView em list_item_crime.xml</p><p>Execute o aplicativo.</p><p>Altere os atributos do ImageView</p><p>Atualizar a classe CrimeListFragment.java para manipularmos o ImageView crime_solved. Inclua as linhas 49, 56 e 63.</p><p>Execute o aplicativo.</p><p>Verifique que as algemas agora não aparecem em todas as linhas.</p><p>Selecione o TextView crime_title</p><p>Faça uso da seta do atributo textAppearance para expandir as opções de aparência.</p><p>Na caixa textColor escolha @android:color/black</p><p>Densidades de pixel de tela dp e sp para o TextView</p><p>Às vezes você precisa especificar valores para atributos de exibição em termos de tamanhos (geralmente em pixels, mas às vezes podem ser pontos, milímetros ou polegadas). Associamos isso mais comumente com atributos para tamanho do texto, margens e preenchimento.</p><p>Tamanho do texto é a altura do pixel do texto na tela do dispositivo. As margens (margins) especificam as distâncias entre views e preenchimento (padding) especifica a distância entre as views e as bordas externas de seu conteúdo.</p><p>Mas o que acontece quando suas imagens aumentam, mas suas margens não? Ou quando o usuário configura um texto maior que o tamanho padrão? Para resolver esses problemas, o Android fornece unidades de medida independente de densidade que você pode usar para obter o mesmo tamanho em diferentes densidades de tela. O Android traduz essas unidades em pixels em tempo de execução do aplicativo.</p><p>Unidades de medidas e dimensões utilizadas no Android:</p><p>· px - DEFINIÇÃO: Correspondente ao número de pixels da tela USO. Evite utilizar px para tudo, apenas em casos bem específicos é recomendada.</p><p>· sp - DEFINIÇÃO: (Scale-independent Pixels) Idem ao dp, mas também considera o tamanho da fonte que o usuário está utilizando. É recomendado que use essa unidade quando especificar o tamanho de uma fonte, para que esta seja automaticamente ajustada conforme as preferências da tela do usuário. USO: Sempre utilize sp para fontes!</p><p>· dip ou dp - DEFINIÇÃO: (Density-independent Pixels) Essa unidade é relativa à resolução da tela. Por exemplo se a resolução da tela é de 160 dpi, significa que um dp representa 1 pixel em um total de 160. USO: aconselhado ao invés de usar o px sempre use o dp.</p><p>Ainda temos outras unidades de medidas utilizadas pelo Android:</p><p>· in (polegadas) - DEFINIÇÃO: Baseado no tamanho físico da tela.</p><p>· mm (milímetro) - DEFINIÇÃO: Baseado no tamanho físico da tela</p><p>· pt (pontos) - DEFINIÇÃO: 1/72 de uma polegada, baseado no tamanho físico da tela</p><p>ASSISTIR</p><p>http://www.youtube.com/watch?v=Ocaq1bu3f2w</p><p>LEITURA</p><p>https://developer.android.com/guide/topics/resources/more-resources.html#Dimension</p><p>https://developer.android.com/guide/topics/ui/declaring-layout?hl=pt-br</p><p>http://jonsegador.com/2012/09/diferentes-unidades-de-medida-disponibles-en-android-dp-sp-pt-px-mm-in/</p><p>Atributos Margin X Padding</p><p>Atributos de margem são parâmetros de layout. Eles determinam a distância entre os widgets. Como um widget pode saber apenas sobre si mesmo, as margens devem ser de responsabilidade do pai do widget. O preenchimento (padding), por outro lado, não é um parâmetro de layout. O atributo android:padding informa ao widget quanto a mais do seu conteúdo que deve ser desenhado.</p><p>A diferença principal se dá ao fato de que:</p><p>· o padding reserva espaço ao elemento;</p><p>· a margin apenas define o espaçamento e projeta o próprio elemento ou algum com o qual tenha contato.</p><p>Ou seja, se você aplicar background a um elemento que possua padding definido, o espaço relativo ao padding receberá cor, enquanto o mesmo elemento com margin aplicado no lugar do padding não recebe cor na área correspondente à margin.</p><p>ASSISTIR</p><p>https://www.youtube.com/watch?v=7ivEwRxAsJw</p><p>Estilos, temas e atributos de temas</p><p>Um estilo é um recurso (resource) XML que contém atributos que descrevem como um widget deve olhar e se comportar. Por exemplo, o seguinte XML é um recurso de estilo que configura um widget com um tamanho de texto maior que o normal:</p><p>LEITURA</p><p>https://developer.android.com/guide/topics/ui/themes?hl=pt-br</p><p>https://www.androidpro.com.br/blog/design-layout/criando-styles-e-themes-no-android/</p><p>Existem duas abordagens para modificar o visual dos aplicativos Android. A primeira abordagem envolve modificar diretamente as propriedades das Views nos arquivos XML de layout. Essa abordagem é viável somente se você estiver trabalhando em um aplicativo simples que tenha um pequeno número de Views e Activities.</p><p>A segunda abordagem envolve a criação e o uso de Styles e Themes personalizados. Se você estiver familiarizado com desenvolvimento Web, a primeira abordagem é semelhante ao uso de estilos CSS direto no HTML, e a segunda abordagem é semelhante ao uso de folhas de estilo.</p><p>Diretrizes de Design para o Android</p><p>Você deve ter observado que, para as suas margens, o Android Studio padronizou 16dp ou um valor de 8dp. Este valor segue-se as diretrizes de Design de Material do Android que você pode encontrar em https://developer.android.com/design/index.html</p><p>Seus aplicativos para Android devem seguir estas orientações o tanto quanto possível. No entanto, você deve saber que as diretrizes dependem fortemente de novas funcionalidade do Android SDK e que não é sempre disponível ou fácil de alcançar em dispositivos mais antigos. Muitas das recomendações de design podem ser seguidas usando a biblioteca AppCompat.</p><p>Ferramenta gráfica para a construção de Layout</p><p>As ferramentas gráficas de layout são úteis especialmente com o ConstraintLayout. Porém, nem todos são fã, no entanto, muitos preferem a simplicidade e clareza de trabalhar diretamente com XML, em vez de fazer uso da IDE.</p><p>Não sinta que você tem que escolher lados. Você pode alternar entre as editor gráfico e edição direta XML a qualquer momento. Use qualquer ferramenta de sua preferência e que te agrade para criar os seus layouts.</p><p>O desafio da formatação de datas</p><p>O objeto Date é mais um timestamp do que uma data convencional. Um timestamp é o que você vê quando chama o método toString() em uma data. Timestamp é o registro de data e hora representando um ponto no tempo independente de qualquer fuso horário ou calendário. É representado como segundos e frações de segundos na resolução de nanossegundos no horário UTC Epoch. Ele é codificado usando o Calendário Gregoriano Proléptico.</p><p>O intervalo é de 0001-01-01T00:00:00Z até 9999-12-31T23:59:59.999999999Z. Ao restringir esse intervalo, garantimos que podemos converter de para strings de data no padrão RFC 3339.</p><p>O modo de apresentação da data que você tem em cada uma das linhas do RecyclerView é um bom exemplo do Timestamp. Enquanto timestamps fazem um bem para documentação de dados nos sistemas, para os seres humanos, basta "10 de dezembro de 1968" e poderemos fazer isso com uma instância da classe android.text.format.DateFormat.</p><p>Você pode usar os métodos da Classe DateFormat para obter um formato comum, ou, você pode preparar sua própria formatação da string. Como sugestão crie uma string que formate para exibir o dia da semana também “terça-feira, 10 de dezembro de 1968”.</p><p>LEITURA</p><p>https://stackoverflow.com/questions/522251/whats-the-difference-between-iso-8601-and-rfc-3339-date-formats</p><p>https://developers.google.com/android/reference/com/google/firebase/Timestamp</p><p>https://stackoverflow.com/questions/18929929/convert-timestamp-into-current-date-in-android</p><p>Iniciar uma atividade de um fragmento (usar argumentos de fragmento)</p><p>Na classe CrimeListFragment.java no construtor CrimeHolder no método onClick comente a instrução Toast e substitua pela linha 70 e 71.</p><p>Excute ALT+ENTER e importe a classe INTENT.</p><p>Execute o aplicativo e toque em qualquer item da lista</p><p>Passando o ID do crime como complemento de uma Intent</p><p>A Intent no sistema operacional Android é um mecanismo de software que permite aos usuários coordenar as funções de diferentes atividades para realizar uma tarefa. Dito de outra forma - as Intents permitem que você interaja com componentes do mesmo aplicativo, bem como com componentes contribuídos por outras aplicações. Por exemplo, uma Activity pode iniciar uma Activity externa para tirar uma foto.</p><p>LEITURA</p><p>https://www.androidpro.com.br/blog/desenvolvimento-android/intents/</p><p>Na classe CrimeActivity.java acrescente a Intent (linhas 14 a 19). Se for necessário importe as classes utilizando ALT+ENTER.</p><p>Depois de criar uma Intent explícita, você chama o método putExtra (…) e passa uma chave de string e o valor que a chave mapeia para o crimeId. Neste caso, você está chamando putExtra (String, Serializável) porque o UUID é um objeto serializável.</p><p>Atualize a classe CrimeListFragment.java onde temos o construtor CrimeHolder para que use o método newIntent que irá passar a identificação do crime. Comente a linha 70 e acrescente a linha 71.</p><p>Abra a classe CrimeFragment.java e no método onCreate comente a linha 27 e acrescente as linhas 28 a 30.</p><p>Além da chamada para o método getActivity() temos o código 	que é o mesmo como se você estivesse recuperando o código extra da atividade. O método getIntent() retorna o Intent que foi usada para começar CrimeActivity. Você chama getSerializableExtra(String) sobre a Intent para atribuir o UUID em uma variável.</p><p>Depois de ter recuperado o ID você o usa para buscar o Crime do CrimeLab.</p><p>Na classe CrimeFragment.java inclua no método onCreateView(...) para exibir o título e a data de solução do crime (linha 38 e 61)</p><p>Execute o aplicativo.</p><p>O lado negativo para direcionar a recuperação</p><p>Ter o fragmento acessando a Intent que pertence à atividade de hospedagem torna o código muito simples. No entanto, isso custa o encapsulamento do seu fragmento. CrimeFragment não é mais um bloco de construção reutilizável porque espera que seja sempre hospedado por uma atividade cuja Intent define um nome extra com.example.criminalintent.crime_id.</p><p>Esta pode ser uma expectativa razoável para o funcionamento de CrimeFragment, mas isso significa que CrimeFragment, como atualmente escrito, não pode ser usado com e por qualquer atividade.</p><p>Uma solução melhor é esconder o ID do crime em algum lugar que pertence ao CrimeFragment em vez de manter no espaço do CrimeActivity. O CrimeFragment poderia em seguida, recuperar esses dados sem depender da presença de um nome extra em particular no Intent da atividade. O "algum lugar" que pertence a um fragmento é conhecido como pacote de argumentos do fragmento.</p><p>Argumentos do Fragmento</p><p>Cada instância de fragmento pode ter um pacote de objeto anexado a ele. Este pacote contém pares de valores-chave que funcionam apenas como os nomes extras de uma atividade Intent. Cada par é conhecido como argumento.</p><p>Para criar argumentos de fragmento, você primeiro irá criar um objeto Bundle. Em seguida, você usa métodos específicos para “colocar” (put) os dados no objeto do tipo Bundle (semelhantes aos do Intent). Veja como criar os argumentos para o pacote:</p><p>Abra a classe CrimeFragment.java para anexar os argumentos para um fragmento.</p><p>Para anexar o pacote de argumentos a um fragmento, você chama o método Fragment.setArguments(Bundle). Para anexar argumentos a um fragmento isso deve ser feito depois que o fragmento é criado, mas antes de ser adicionado a uma atividade.</p><p>Para fazer isso os programadores Android seguem uma convenção que é adicionar um método estático chamando a newInstance(...) para a classe do fragmento. Este método cria a instância do fragmento, empacota os dados e define seus argumentos.</p><p>Quando a atividade de hospedagem precisa de instância desse fragmento teremos que chamar o método newInstance(…) em vez do que chamar o construtor diretamente. A atividade pode passar qualquer dos parâmetros exigido para newInstance(…) que o fragmento precisa criar sua argumentos.</p><p>Em CrimeFragment.java escreva um método newInstance(UUID) que aceita um UUID, cria o pacote de argumentos pacote, cria uma instância de fragmento e em seguida, anexa os argumentos ao fragmento.</p><p>Usando a newInstance(UUID) na classe CrimeActivity.java</p><p>EXTRA_CRIME_ID passará a ser privado porque nenhuma outra classe acessará ele. No método createFragment() retornamos uma instância de CrimeFragment() tendo como valor o crimeId.</p><p>Observe que a necessidade de independência não vai nos dois sentidos. CrimeActivity tem que saber muito sobre CrimeFragment, incluindo isso tem um método newInstance(UUID). Isto é bom, pois, Atividades de hospedagem devem saber os detalhes de como hospedar seus fragmentos, mas fragmentos não devem ter que saber detalhes sobre a suas atividades. Pelo menos, não se você quiser manter a flexibilidade de independência entre os fragmentos.</p><p>Recuperando os argumentos</p><p>Quando um fragmento precisa acessar seus argumentos, ele chama o método getArguments() e, em seguida, um dos métodos "get" específicos de tipo do Bundle.</p><p>Na classe CrimeFragment.java em CrimeFragment.onCreate(…) substitua seu código pela recuperação do UUID dos argumentos do fragmento.</p><p>Sabe o motivo do erro? Lembra-se a alteração de public para private que fizemos</p><p>Execute o aplicativo. O aplicativo vai se comportar da mesma forma.</p><p>Recarregando a lista</p><p>Há mais um detalhe para cuidar. Ao executar CriminalIntent pressione um item da lista e em seguida, modifique os detalhes desse crime. Estas as alterações são salvas no modelo, mas quando você retornar à lista o RecyclerView é inalterado.</p><p>O adaptador do RecyclerView precisa ser informado de que os dados sofreram uma mudança (ou pode ter mudado) para que possa refazer os dados e recarregar a lista.</p><p>Você pode trabalhar com o A pilha de trás do ActivityManager para recarregue a lista no momento certo. Quando CrimeListFragment é iniciado uma instância do CrimeActivity, o CrimeActivity é colocado no topo da pilha. Isso pausa e pára a instância de CrimeListActivity que foi inicialmente no topo.</p><p>Quando o usuário pressiona o botão Voltar para voltar para a lista, o CrimeActivity é retirado da pilha e destruído. No Nesse ponto, o CrimeListActivity é iniciado e retomado</p><p>Execute o aplicativo.</p><p>Escolha um item da lista e em seguida faça alguma modificação.</p><p>Pressione Voltar (Back) no seu dispositivo.</p><p>Quando a CrimeListActivity é retomada recebe uma ligação para onResume() feita pelo sistema operacional. Ao receber esta chamada, as chamadas onResume() chegam até FragmentManager, ou seja, nos fragmentos que a atividade está hospedando atualmente. Nesse caso,</p><p>o único fragmento é CrimeListFragment. Em CrimeListFragment, devemos anular onResume() e disparar uma chamada para updateUI() para recarregar a lista. Temos que modificar o método updateUI() para chamar notifyDataSetChanged() se o CrimeAdapter já está configurado.</p><p>Modifique a classe CrimeListFragmente.java</p><p>Atualize o método updateUI()</p><p>Por que substituir onResume() para atualizar o RecyclerView e não onStart()? Você não pode supor que sua atividade será interrompida quando outra atividade está na frente dela. Se outra atividade é transparente, a sua atividade pode apenas ser pausada. Se sua atividade está pausada e seu código de atualização está em onStart(), então a lista não será recarregada. Em geral, onResume() é o lugar mais seguro para agir atualizar a visão de um fragmento.</p><p>Execute o CriminalIntent. Selecione um crime e mude seus detalhes. Quando você retornar para a lista, você vai ver imediatamente a alteração realizada.</p><p>Na classe CrimeListFragment.java acrescente a variável estática REQUEST_CRIME</p><p>Reescreva o método onClick() do construtor CrimeHolder e escreva o método onActivityResult() da classe CrimeListFragment</p><p>Retornar resultados de um fragmento é um pouco diferente. Um fragmento pode receber um resultado de uma atividade, mas não pode ter seu próprio resultado. Apenas atividades têm resultados. Portanto, embora o Fragment tenha seus próprios métodos startActivityForResult(…) e onActivityResult(…), ele não possui nenhum método setResult(…). Em vez disso, você diz à atividade do host para retornar um valor.</p><p>Na classe CrimeListFragment.java acrescente o método returnResultID() antes do último fechamento de bloco de código }</p><p>Execute o aplicativo.</p><p>Usando ViewPager</p><p>A adição de um ViewPager à sua interface do usuário permite que os usuários naveguem entre os itens da lista passando pela tela para “avançar” (swipe left) ou “retroceder” (swipe right) nos crimes (itens da lista).</p><p>Adicione o layout activity_crime_pager.xml</p><p>Nesta tela iremos trabalhar com CrimePagerActivity.java que será uma subclasse de AppCompatActivity utilizada para criar e gerenciar o ViewPager.</p><p>Ao arrastar para o COMPONENT TREE vamos adicionar o recurso. Você usa o pacote completo do ViewPager ao adicioná-lo ao arquivo de layout e será necessário realizar a instalação desta biblioteca. Ao usar do fragmento não é necessário a instalação.</p><p>ATENÇÃO – Adicionar uma dependência ao projeto irá requerer acesso à internet</p><p>Altere os atributos do ViewPager</p><p>LEITURA</p><p>https://www.thiengo.com.br/viewpager-no-android-entendendo-e-utilizando</p><p>https://www.journaldev.com/10096/android-viewpager-example-tutorial</p><p>https://medium.com/@Abdulkadir98/android-sliding-tabs-with-viewpager-851f9c996cb5</p><p>https://techadictos.info/questions/4162/fragmentar-com-viewpager-dentro-de-fragment-e-fragmentstatep</p><p>Adicione a classe CrimePagerActivity.java</p><p>No entanto, a conversa entre ViewPager e PagerAdapter envolve mais recursos de programação do que a conversa entre RecyclerView e adaptador. Felizmente, você pode usar FragmentStatePagerAdapter, uma subclasse de PagerAdapter para tratar dos detalhes envolvidos.</p><p>FragmentStatePagerAdapter vai resumir a conversa para dois métodos simples: getCount() e getItem(int). Quando seu método getItem(int) é chamado para uma posição em sua matriz de crimes (lembre-se lista) será devolvido um CrimeFragment configurado para exibir o crime dessa posição.</p><p>Em CrimePagerActivity, definimos o adaptador do ViewPager e implementamos os métodos getCount() e métodos getItem(int).</p><p>Retorne para a classe CrimePagerActivity.java</p><p>Utilize ALT+ENTER e importe as classes ViewPager e List.</p><p>Explicando um pouco mais sobre este código. Depois de encontrar o ViewPager na visão da atividade, você obtém seu conjunto de dados do através da classe CrimeLab que contém a lista de crimes. Em seguida, você recebe a instância da atividade do FragmentManager.</p><p>Em seguida, você configura o adaptador para ser uma instância sem nome de FragmentStatePagerAdapter. Para criar o FragmentStatePagerAdapter é necessário o FragmentManager. Lembre-se que o FragmentStatePagerAdapter será o responsável por estar gerenciando a conversa com o ViewPager. Para assumir esta responsabilidade por este seu trabalho com os fragmentos temos que retornar o método getItem(int) e assim ele será capaz de incluí-los em sua atividade. Isso justifica a necessidade de uso do FragmentManager.</p><p>Os dois métodos do adaptador são simples. O método getCount()retorna o número de itens na lista da matriz de crimes (lista de crimes). O método getItem(int) é onde a mágica acontece. Ele busca a instância Crime para a posição determinada no conjunto de dados. Em seguida, ele usa essa ID do crime para criar e devolver um CrimeFragment configurado corretamente.</p><p>Fazendo a integração com a CrimePagerActivity.java</p><p>Relembrando que um Intent (do inglês para intenção) é um objeto de mensagem que usamos para solicitar uma ação de um outro componente do aplicativo. Ou seja, podemos solicitar ações de uma Activity, de um Service, de um Content Provider ou de um Broadcast Receiver.</p><p>Existem várias formas de componentes se comunicarem, mas temos três usos fundamentais:</p><p>· Iniciar uma Activity</p><p>· Iniciar um Service</p><p>· Fornecer uma transmissão, que será recebida pelos Broadcast Receivers</p><p>LEITURA</p><p>https://imasters.com.br/android/entendendo-activities-e-intentes-tutorial-para-android</p><p>https://mariovalney.com/aula-10-como-mudar-de-activity-com-intents/</p><p>Na classe CrimePagerActivity.java inclua a linha 14 da imagem abaixo (atenção para usar o seu package) e utilize ALT+ENTER para importar a classe Intent, Context e UUID (na linha 19 da imagem abaixo)</p><p>Agora ao pressionar um item da lista em CrimeListFragment será iniciada uma instância de CrimePagerActivity em vez de CrimeActivity.</p><p>Retorne para a classe CrimeListFragment.java e modifique o método CrimeHolder.onClick(View) para iniciar um CrimePagerActivity. Comente as linhas necessárias e inclua o bloco try{}catch(Exception e){}</p><p>Você também precisa adicionar CrimePagerActivity ao manifesto (AndroidManifest.xml) para que o sistema operacional possa iniciá-lo. Enquanto estiver no manifesto, remova a declaração do CrimeActivity. Para fazer isso basta renomear CrimeActivity para CrimePagerActivity no manifesto.</p><p>Execute o aplicativo. Pressione Crime #0 para ver seus detalhes. Em seguida, deslize para a esquerda e para a direita para procurar os crimes. Observe que a paginação é suave e não há atraso no carregamento. Por padrão, o ViewPager carrega o item atualmente na tela mais uma página vizinha em cada direção para que a resposta a um toque (swipe) seja imediata. Você pode ajustar quantas páginas vizinhas são carregadas chamando setOffscreenPageLimit (int). Esteja atento o seu ViewPager ainda não é perfeito.</p><p>Pressione o botão Voltar para retornar à lista de crimes e pressione um item diferente. Você verá o primeiro crime exibido novamente será o Crime #0 em vez do crime que você pediu. Por padrão, o ViewPager mostra o primeiro item em seu PagerAdapter. Você pode mostrar o crime que foi selecionado, definindo o item atual do ViewPager para o índice do crime selecionado.</p><p>No final de CrimePagerActivity.onCreate(Bundle), encontre o índice do crime a ser exibido, fazendo um loop e verificando o ID de cada crime. Quando você encontrar a instância Crime cuja mId corresponde ao crimeId na intenção extra e defina o item atual para ser o índice desse Crime.</p><p>Execute o aplicativo. Selecionando qualquer o item da lista deve exibir os detalhes do Crime correto. E é isso. Seu ViewPager está agora totalmente ajustado e operacional.</p><p>FragmentStatePagerAdapter vs FragmentPagerAdapter</p><p>Existe outro tipo de PagerAdapter que você pode usar chamado FragmentPagerAdapter. FragmentPagerAdapter é usado exatamente como FragmentStatePagerAdapter. Só difere em como descarrega seus fragmentos quando eles não são mais necessários.</p><p>Com FragmentStatePagerAdapter, seu fragmento desnecessário é destruído. Uma transação está comprometida para</p><p>remover completamente o fragmento do FragmentManager de sua atividade. O "estado" no FragmentStatePagerAdapter vem do fato de que ele salvará o Bundle de seu fragmento de onSaveInstanceState(Bundle) quando ele for destruído. Quando o usuário navega de volta, o novo fragmento será restaurado usando esse estado da instância.</p><p>FragmentPagerAdapter lida com as coisas de maneira diferente. Quando seu fragmento não é mais necessário, o FragmentPagerAdapter chama o método detach(Fragment) na transação, em vez do método remove(Fragment). Isso destrói a visualização do fragmento, mas deixa a instância de fragmento ativa no FragmentManager. Portanto, os fragmentos criados pelo FragmentPagerAdapter nunca são destruídos.</p><p>Qual tipo de adaptador você deve usar depende do seu aplicativo. FragmentStatePagerAdapter é geralmente mais frugal com a memória. CriminalIntent está exibindo o que pode ser uma longa lista de crimes, e cada um deles incluirá uma foto. Você não quer manter toda essa informação na memória, então você usa FragmentStatePagerAdapter.</p><p>Por outro lado, se a sua interface tiver um número pequeno e fixo de fragmentos, o FragmentPagerAdapter seria seguro e apropriado. O exemplo mais comum desse cenário é uma interface com guias. Algumas exibições detalhadas têm detalhes suficientes para exigir duas telas, portanto, os detalhes são divididos em várias guias.</p><p>Adicionar um ViewPager deslizável a essa interface torna o aplicativo mais fácil. Manter esses fragmentos na memória pode facilitar o gerenciamento do código do seu controlador. Além disso, como esse estilo de interface geralmente tem apenas dois ou três fragmentos por atividade, há pouco risco de ficar com pouca memória.</p><p>Diálogos</p><p>Diálogos exigem atenção e entrada do usuário. Eles são úteis para apresentar uma escolha ou informações importantes.</p><p>Iremos adicionar uma caixa de diálogo na qual os usuários podem alterar a data de um crime. Pressionando o botão de data no CrimeFragment irá apresentar este diálogo no Lollipop.</p><p>AlertDialog é a subclasse de ‘Dialog’ para todos os fins que você usará com mais frequência. Quando o Lollipop foi lançado os diálogos receberam uma reformulação visual.</p><p>AlertDialogs no Lollipop usam automaticamente esse novo estilo. Nas versões anteriores do Android, o AlertDialog voltará ao estilo antigo mostrado à esquerda (veja na imagem abaixo).</p><p>Em vez de exibir o antigo estilo de diálogo, seria bom sempre mostrar o novo estilo de diálogo, independentemente da versão do Android em que o dispositivo do usuário está. E você pode fazer isso com a classe AlertDialog da biblioteca AppCompat. Esta versão do AlertDialog é muito semelhante à incluída no sistema operacional Android, mas, como outras classes AppCompat, é compatível com versões anteriores. Para obter os benefícios da versão AppCompat, certifique-se de importar android.support.v7.app.AlertDialog quando solicitado.</p><p>Criar um fragmento para diálogo (DialogFragment)</p><p>Ao usar um AlertDialog, é uma boa ideia envolvê-lo em uma instância de DialogFragment, uma subclasse de Fragment. É possível exibir um AlertDialog sem um DialogFragment, mas isso não é recomendado. Ter o diálogo gerenciado pelo FragmentManager oferece mais opções para apresentar o diálogo.</p><p>Além disso, um AlertDialog vazio desaparecerá se o dispositivo for girado. Se o AlertDialog estiver envolto em um fragmento, a caixa de diálogo será recriada e colocada novamente na tela após a rotação.</p><p>Para o nosso aplicativo CriminalIntent, você criará uma subclasse DialogFragment chamada DatePickerFragment. Dentro de DatePickerFragment, você criará e configurará uma instância de AlertDialog que exibe um widget DatePicker.</p><p>O DatePickerFragment será hospedado por CrimePagerActivity (veja uma visão geral dessas relações).</p><p>Suas primeiras tarefas são:</p><p>· criar a classe DatePickerFragment</p><p>· construir um AlertDialog</p><p>· obter a caixa de diálogo na tela através do FragmentManager</p><p>Adicionar o título para o diálogo em values/strings.xml</p><p>Criar uma nova classe DatePickerFragment.java</p><p>Na construção do código será necessário importar algumas classes use ALT+ENTER</p><p>Nesta implementação, você usa a classe AlertDialog.Builder, que fornece uma interface fluente para a construção de uma instância AlertDialog.</p><p>Primeiro, você passa um Contexto para o construtor AlertDialog.Builder, que retorna uma instância de AlertDialog.Builder.</p><p>Em seguida, você chama dois métodos no construtor AlertDialog.Builder para configurar sua caixa de diálogo. O método setPositiveButton(…) que aceita uma string e um objeto que implementa DialogInterface.OnClickListener. No código passamos uma constante do Android para OK e null para o parâmetro do listener.</p><p>(Um botão positivo é o que o usuário deve pressionar para aceitar o que o diálogo apresenta ou tomar a ação principal do diálogo. Existem dois outros botões que você pode adicionar a um AlertDialog: um botão negativo e um neutro. Essas designações determinam as posições dos botões na caixa de diálogo.)</p><p>Finalmente, você conclui a construção da caixa de diálogo com uma chamada para AlertDialog.Builder.create() que retorna a instância AlertDialog configurada. Veja o que mais você pode fazer com AlertDialog e AlertDialog.Builder na documentação do desenvolvedor.</p><p>Mostrando um DialogFragment</p><p>Como todos os fragmentos, instâncias de DialogFragment são gerenciadas pelo FragmentManager da atividade de hospedagem.</p><p>Para obter um DialogFragment adicionado ao FragmentManager e colocá-lo na tela, você pode chamar os seguintes métodos na instância do fragmento:</p><p>public void show (FragmentManager gerenciador, tag String)</p><p>public void show (FragmentTransaction transação, tag String)</p><p>O parâmetro string identifica exclusivamente o DialogFragment na lista do FragmentManager. Se você usa o FragmentManager ou a versão do FragmentTransaction. Se você passar em um FragmentTransaction você é responsável por criar e confirmar essa transação. Se você passar um FragmentManager uma transação será automaticamente criada e confirmada para você.</p><p>Aqui, você passará em um FragmentManager. Na classe CrimeFragment.java, adicione uma constante DIALOG_DATE para a tag do DatePickerFragment.</p><p>Em seguida, em onCreateView(…), remova ou comente o código que desativa o botão de data e defina um View.OnClickListener que mostre um DatePickerFragment quando o botão de data for pressionado.</p><p>Excute o aplicativo e faça uso do botão da data.</p><p>Fig.12.4-liv232-pdf839</p><p>Adicione um novo layout com o nome dialog_date.xml</p><p>Na caixa Root element informe DatePicker</p><p>Altere os atributos do DatePicker ID para dialog_date_picker, layout_width para wrap_content e layout_height para wrap_content</p><p>Na classe DatePickerFragment.java</p><p>Excute o aplicativo e pressione o botão da data para exibir o DatePicker.</p><p>12.6-liv233</p><p>Passando dados entre dois fragmentos</p><p>Para obter dados no seu DatePickerFragment será necessário armazenar a data no pacote de argumentos do DatePickerFragment. Neste local o DatePickerFragment pode acessá-lo.</p><p>Veja a sequência de eventos que ocorrem entre CrimeFragment e DatePickerFragment</p><p>Criar e configurar argumentos de fragmento normalmente é feito em um método newInstance() que substitui o construtor de fragmento. Na classe DatePickerFragment.java adicione o método newInstance(Date)</p><p>Na classe CrimeFragment.java remova a chamada para o construtor DatePickerFragment e substitua por DatePickerFragmente.newInstance</p><p>DatePickerFragment precisa inicializar o DatePicker usando as informações contidas na ARG_DATE. No entanto, inicializando o DatePicker e requeremos números inteiros para o mês, dia e ano. A ARG_DATE é mais um registro de data e hora (TIMESTAMP) e não pode fornecer números inteiros como necessitamos diretamente.</p><p>Para obter os inteiros que você precisa, você deve criar um objeto de calendário e usar a data para configurar o calendário. Só desta forma você pode recuperar as informações necessárias do calendário.</p><p>No método onCreateDialog(Bundle) da classe DatePickerFragment.java, obtenha os dados necessários</p><p>a partir de ARG_DATE e use-os em um calendário para inicializar o DatePicker.</p><p>Faça as alterações na classe DatePickerFragment.java. Se necessário importe a classe Calendar utilizando ALT+ENTER.</p><p>O que é um Timestamp?</p><p>É uma marca temporal representa uma cadeia de caracteres denotando a hora ou data que certo evento ocorreu. A cadeia é geralmente apresentada num formato consistente, permitindo facilmente comparação entre duas marcas temporais distintas.</p><p>A maior diferença entre datetime e timestamp é a seguinte:</p><p>· datetime: representa uma data como no calendário e a hora como encontrado no relógio.</p><p>· timestamp: representa um ponto específico na linha do tempo e leva em consideração o fuso horário em questão (UTC). Por exemplo: quando foi 10/12/1968 08:00? depende, para mim é nesse momento, para o Japão foi a várias horas atrás, então basicamente o timestamp leva em consideração essas questões de fuso horário.</p><p>Outro ponto é que geralmente quando se precisa rastrear alterações feitas em registros da base de dados, opta-se pelo uso do timestamp pois permite o detalhamento perante a linha do tempo real.</p><p>LEITURA</p><p>https://www.oracle.com/technetwork/pt/articles/sql/introducao-tipo-de-dado-timestamp-1505073-ptb.html</p><p>https://bit.ly/2TH1nbv</p><p>Agora CrimeFragment está dizendo com sucesso ao DatePickerFragment que data mostrar. Execute o aplicativo CriminalIntent para certificar-se que tudo funcione como antes.</p><p>Retornando dados para CrimeFragment</p><p>Para que o CrimeFragment receba a data de DatePickerFragment, você precisa ter uma maneira de controlar o relacionamento entre os dois fragmentos. Com as atividades, você chama startActivityForResult(…) e o ActivityManager controla a relação da atividade pai-filho. Quando a atividade filho morre, o ActivityManager sabe qual atividade deve receber o resultado.</p><p>Definindo um fragmento de destino</p><p>Você pode criar uma conexão semelhante, tornando CrimeFragment o fragmento de destino de DatePickerFragment. Esta conexão é automaticamente restabelecida após o CrimeFragment e DatePickerFragment serem destruídos e recriados pelo SO. Para criar esse relacionamento, você chama o seguinte método Fragment:</p><p>public void setTargetFragment (Fragment fragmento, int requestCode)</p><p>Esse método aceita o fragmento que será o destino e um código de solicitação exatamente como aquele que você envia em startActivityForResult(…).</p><p>O fragmento de destino pode usar o código de solicitação posteriormente para identificar qual fragmento está relacionado.</p><p>O FragmentManager controla o fragmento de destino e o código de solicitação. Você pode recuperá-los chamando os métodos getTargetFragment() e getTargetRequestCode() no fragmento que configurou o destino.</p><p>Na classe CrimeFragment.java, crie uma constante para o código de solicitação e, em seguida, torne CrimeFragment o fragmento de destino da instância DatePickerFragment.</p><p>Enviando dados para o fragmento de destino</p><p>Agora que você tem uma conexão entre CrimeFragment e DatePickerFragment, você precisa enviar a data de volta para CrimeFragment. Você vai colocar a data em uma intenção como um extra.</p><p>Qual método você usará para enviar essa intenção para o fragmento de destino? Curiosamente, você terá que fazer o DatePickerFragment passá-lo em CrimeFragment.onActivityResult(int, int, Intent).</p><p>Activity.onActivityResult(…) é o método que o ActivityManager chama na atividade pai depois que a atividade filho é interrompida. Ao lidar com atividades, você mesmo não chama Activity.onActivityResult(…); esse é o trabalho do ActivityManager. Depois que a atividade recebeu a chamada, o FragmentManager da atividade chama Fragment.onActivityResult(…) no fragmento apropriado.</p><p>Ao lidar com dois fragmentos hospedados pela mesma atividade, você pode tomar emprestado o método Fragment.onActivityResult(…) e chamá-lo diretamente no fragmento de destino para passar os dados de volta e assim tem exatamente o que você precisa:</p><p>- um código de solicitação que corresponde ao código passado em setTargetFragment(…) para informar ao destino o que está retornando o resultado</p><p>- um código de resultado para determinar que ação tomar</p><p>- uma intenção que pode ter "dados extras"</p><p>Na classe DatePickerFragment.java, crie um método privado que crie uma intenção, coloque a data como um dado extra e, em seguida, chame o método CrimeFragment.onActivityResult(...)</p><p>Sendo necessário importe a classe Intent utilizando ALT+ENTER</p><p>O que faz uma Intent?</p><p>Permite iniciar uma atividade em outro aplicativo descrevendo uma ação simples que você gostaria de executar (como "exibir um mapa" ou "tirar uma fotografia").</p><p>LEITURA</p><p>https://developer.android.com/guide/components/intents-common?hl=pt-br</p><p>https://imasters.com.br/android/intents-passagem-de-parametros-entre-telas</p><p>https://elbauldelprogramador.com/programacion-android-intents-conceptos/</p><p>https://developers.google.com/maps/documentation/urls/android-intents</p><p>Agora é hora de usar este novo método sendResult(…). Quando o usuário pressiona o botão positivo na caixa de diálogo, você deseja recuperar a data do DatePicker e enviar o resultado de volta para CrimeFragment. Em onCreateDialog(…) substitua o parâmetro nulo de setPositiveButton(…) por uma implementação de DialogInterface.OnClickListener que recupere a data selecionada e chame sendResult(…).</p><p>Na classe DatePickerFragment.java no método onCreateDialog(...) faça a substituição no método setPositiveButton(...)</p><p>Sendo necessário importe as classes GregorianCalendar e Activity fazendo uso de ALT+ENTER</p><p>Na classe CrimeFragment.java, sobrescreva o método onActivityResult(…) [importante o método não existe ainda] para recuperar o dado extra para definir a data no Crime e atualizar o texto do botão de data.</p><p>Sendo necessário importe as classes Intent, Activity e Date fazendo uso de ALT+ENTER</p><p>O código que define o texto do botão é idêntico ao código que você chama em onCreateView(…). Para evitar a configuração do texto em dois locais, encapsule esse código em um método privado com o nome de updateDate () e, em seguida, chame-o em onCreateView(…) e onActivityResult(…).</p><p>Você pode fazer isso manualmente ou pode fazer com que o Android Studio faça isso por você. Selecione toda a linha de código que define o texto de mDateButton.</p><p>Clique com o botão direito do mouse sobre a linha de código selecionada</p><p>Refactor Extract Method...</p><p>Clique em OK e o Android Studio informará que encontrou outro local onde essa linha de código foi usada. Clique em REPLACE para permitir que o Android Studio atualize a outra referência e, em seguida, verifique se seu código foi extraído para um único método updateDate()</p><p>Resultado da refatoração.</p><p>O que é refatoração?</p><p>É uma técnica ou processo para modificar a estrutura interna do código-fonte sem alterar o seu comportamento externo. Refactor é uma prática comum em processos ágeis de programação com o Extreme Programing.</p><p>LEITURA</p><p>https://www.devmedia.com.br/introducao-a-refatoracao/21377</p><p>https://bit.ly/2Fhwxxx</p><p>http://www.desenvolvimentoagil.com.br/xp/praticas/refatoracao</p><p>http://ccsl.ime.usp.br/agilcoop/files/2-Refatoracao.pdf</p><p>“Agora o círculo está completo. As datas devem fluir. Quem controla as datas controla o próprio tempo.”</p><p>Execute o aplicativo CriminalIntent para garantir que você possa, de fato, controlar as datas. Altere a data de um Crime e confirme se a nova data aparece na visualização do CrimeFragment. Em seguida, volte para a lista de crimes e verifique a data do crime para garantir que a camada do modelo foi atualizada.</p><p>Mais flexibilidade na apresentação de um DialogFragment</p><p>Usar o método onActivityResult(…) para enviar dados de volta para um fragmento de destino é especialmente interessante quando você está escrevendo um aplicativo que precisa de muita informação do usuário e mais espaço para solicitá-lo - e deseja que o aplicativo funcione bem em celulares e tablets.</p><p>Em um telefone, você não tem muito espaço na tela, portanto, provavelmente usaria uma atividade com um fragmento de tela cheia para solicitar informações ao usuário. Essa atividade</p>

Mais conteúdos dessa disciplina