Migrando Para o AndroidX e Construindo a Galeria Para Foto de Perfil - Android M-Commerce
Blog /Android /Migrando Para o AndroidX e Construindo a Galeria Para Foto de Perfil - Android M-Commerce
Neste artigo vamos finalizar os trabalhos de interface na tela de formulário de perfil de usuário do projeto Android BlueShoes, nosso aplicativo de mobile-commerce.
Aqui chegamos também ao ponto de migrar o projeto da Support Library para o pacote AndroidX, isso principalmente devido a API de galeria que estaremos utilizando, mas de qualquer forma: "esse dia de mudança para o AndroidX iria chegar, cedo ou tarde".
Antes de prosseguir, não deixe de se inscrever 📫na lista de emails do Blog para ter acesso exclusivo às novas aulas do projeto e também a outros conteúdos exclusivos do Blog.
Iniciando no projeto Android BlueShoes;
Estratégia para a tela de galeria de imagens e câmera:
Por que migrar o código agora?;
Primeiros passos para a migração;
Ajustes necessários de migração:
Atualização do gradle.properties;
Atualização do Gradle Nível de Aplicativo;
Atualização do Gradle Nível de Projeto;
Atualização da classe utilitária NavMenuItemDetails;
Atualização da classe utilitária NavMenuItemDetailsLookup;
Atualização da classe NavMenuItemKeyProvider;
Atualização da classe NavMenuItemPredicate;
Atualização da atividade abstrata FormActivity;
Atualização da atividade FormEmailAndPasswordActivity;
Atualização da atividade de login;
Atualização da atividade de cadastro de novo usuário;
Atualização da atividade de itens de configuração de conta;
Atualização do adapter da AccountSettingsActivity;
Atualização da atividade de formulário de perfil de usuário;
Atualização do fragmento Sobre;
Atualização do fragmento de Contato;
Atualização do fragmento de Políticas de Privacidade;
Atualização do adapter de itens de menu gaveta;
Atualização da atividade principal.
Trabalhando a tela de galeria e de câmera:
Por que a ImagePicker API foi escolhida?;
Atualizando o Gradle de Nível de Projeto;
Atualizando o Gradle de Nível de Aplicativo;
Adicionando permissões ao AndroidMenifest;
Sobrescrevendo estilos da ImagePicker API;
O novo campo de imagem do formulário de perfil;
Configurando a galeria e a câmera.
Iniciando no projeto Android BlueShoes
Se você estiver tendo somente agora o primeiro contato com o projeto Android BlueShoes, nosso projeto de mobile-commerce, saiba que é preciso primeiro consumir algumas outras aulas para depois poder prosseguir com está 14ª aula do projeto.
13ª aula - Construindo o Formulário de Atualização de Perfil - Android M-Commerce.
Ressaltando que as aulas são liberadas semanalmente para a lista de e-mails 📩 do Blog, logo, não esqueça de se inscrever nela, é gratuito.
Estratégia para a tela de galeria de imagens e câmera
Apesar de o desenvolvimento da tela de galeria e câmera ser simples, pois vamos utilizar uma API especifica para isso, ainda será preciso bastante atualização em projeto, principalmente devido à migração para o AndroidX.
Vamos prosseguir com o seguinte roteiro:
Primeiro vamos a migração de todo o código para ele passar a utilizar o pacote AndroidX;
Em seguida vamos a configuração das partes estáticas de projeto que serão utilizadas, ou fazem parte da configuração, da área de galeria e câmera;
Por fim vamos às configurações em código dinâmico para que seja possível utilizar a API responsáveis pelo correto trabalho com a galeria de imagens e câmera.
A seguir o protótipo estático da área de galeria de imagens e de câmera do formulário de perfil de usuário:
Antes de partirmos para as explicações mais detalhadas sobre o AndroidX é importante informar que o processo de migração do código do projeto, da conhecida Support Library, para o AndroidX é algo que em algum momento do desenvolvimento nós teríamos de fazer.
O momento chegou, pois uma das APIs úteis em projeto necessita que ele já esteja utilizando o AndroidX para ela funcionar como esperado.
O AndroidX é, resumidamente, a melhoria do pacote Support Library. E como a Support Library, o AndroidX é separado do sistema operacional (SO) Android e, ainda melhor:
Ele é compatível com versões antigas do Android, como a Support Library;
As atualizações de pacotes internos agora é independente, algo que não ocorria na Support Library.
O AndroidX é o local onde se encontram as bibliotecas do Jetpack Android. O Jetpack é um conjunto de componentes Android, também separados do Android SO, que buscam facilitar o desenvolvimento de aplicativos nesta plataforma, permitindo ao desenvolvedor maior foco em código de domínio de problema.
Um informe importante sobre a necessidade de migrar projetos Android para o AndroidX, informe direto da documentação oficial:
Todo novo desenvolvimento da Support Library ocorrerá na biblioteca do AndroidX. Isso inclui a manutenção dos artefatos originais da Support Library e a introdução de novos componentes do Jetpack.
Por que migrar o código agora?
Para trabalho com a galeria de imagens e câmera, para permitir que o usuário do aplicativo facilmente escolhesse uma imagem de perfil, fomos atrás de uma API adequada para está funcionalidade.
A mais consistente, também em relação ao layout definido em protótipo estático, completa e utilizando a Apache License 2.0 é uma API que já exige em projeto o trabalho com o AndroidX, caso contrário ela simplesmente não funciona.
Bom, vamos falar a verdade, se trabalhássemos um pouco mais seria sim possível utilizar essa API de seleção de imagem ainda com o projeto utilizando a Support Library, mas sabendo que a migração para a AndroidX ocorreria, uma hora ou outra, então escolhemos o caminho certo e que seria inevitável.
Felizmente o Google Android têm todo o conteúdo de migração de um projeto Android Support Library para um projeto Android com AndroidX, incluindo todo o conteúdo em português.
Confesso que a migração automática, utilizando o Android Studio, é "meia boca", mas já adianta muito do trabalho manual que será necessário.
Importante: Antes de partirmos para a migração automática é preciso que o SDK de compilação do projeto (compileSdkVersion) seja colocado na versão 28 (Pie) ou superior do Android. Essa atualização ocorre no Gradle Nível de Aplicativo (build.gradle (Module: app)). Isso, pois o AndroidX é compatível a partir deste SDK em compilação.
Assim, com o Android Studio aberto (assumindo que você está com uma versão deste IDE igual ou superior a versão 3.2) acesse o menu de topo:
Clique em Refactor;
Logo depois clique em Migrate to AndroidX....
Por segurança, aceite realizar o backup do projeto em um arquivo ZIP:
Por fim clique em Migrate.
Please, you do not be so happy! Sim, não fique feliz achando que esses poucos cliques foram o suficiente. A precisão do Android Studio ainda não é das melhores, ao menos na versão 3.4.1 deste IDE (que é a versão que eu estou utilizando no momento da construção desta parte do projeto), pois teremos de migrar alguns trechos na "unha".
Ajustes necessários de migração
Os ajustes extras vão vir com auxílio da página de migração para o AndroidX: Como migrar para o AndroidX.
Vamos primeiro aos arquivos de configuração do projeto, depois vamos por classes e layouts, se houver algum layout vinculado a classe em mudança.
A partir deste ponto nós vamos verificar as modificações necessárias em projeto. Caso em seu aplicativo, depois da migração automática ainda falte alguma importação ou referência apresentada nos próximos tópicos, então atualize como apresentado aqui.
Note que em muitos conjuntos de importação apresentados haverá o nome de pacote thiengo.com.br.blueshoes, pois este é o package name de minha versão do projeto BlueShoes, em seu caso certamente será outro nome, sendo assim, nessas partes, continue com o seu nome de pacote.
Atualização do gradle.properties
No arquivo gradle.properties (propriedades de projeto) adicione as duas linhas a seguir caso elas já não estejam presentes:
A função de cada uma destas configurações é:
android.useAndroidX: quando definida como true, o plug-in do Android usa a biblioteca do AndroidX adequada em vez de uma Support Library. Por padrão o valor é false;
android.enableJetifier: quando definida como true, o plug-in do Android migra automaticamente as bibliotecas de terceiros existentes para usar o AndroidX, reescrevendo os respectivos binários. Por padrão o valor é false.
Atualização do Gradle Nível de Aplicativo
No bloco dependencies do Gradle Nível de Aplicativo, build.gradle (Module: app), certifique-se de que as dependências de projeto estão como abaixo, ao menos os trechos em destaque, com o pacote AndroidX sendo utilizado, caso contrário (alguns poderão não estar) atualize para que fique:
/* SelectionTracker API */
/* RoundedImageView API */
/* AndroidUtilCode API */
implementation 'com.blankj:utilcode:1.23.7'
Note que todas as referências que continham com.android.support foram atualizadas para referências androidx, mas, diferente do que a documentação de migração para o AndroidX apresenta, isso não é padrão.
Ainda não há a necessidade de sincronização do projeto, temos de atualizar / verificar mais pontos do código do app.
Atualização do Gradle Nível de Projeto
Apesar de não ser uma atualização devido ao uso do AndroidX, neste ponto do projeto foi liberada uma atualização da versão do Kotlin.
Importante: não deixe de aplicar todas as atualizações que o Android Studio IDE indica assim que ele é inicializado.
No Gradle Nível de Projeto, build.gradle (Project: BlueShoes), atualize o ext.kotlin_version como a seguir:
Ainda não sincronize o projeto.
Atualização da classe utilitária NavMenuItemDetails
A configuração de imports da classe NavMenuItemDetails agora é como a seguir:
import androidx.recyclerview.selection.ItemDetailsLookup
import thiengo.com.br.blueshoes.domain.NavMenuItem
Note que, em todo o artigo, o que foi atualizado estará em destaque.
Atualização da classe utilitária NavMenuItemDetailsLookup
A seguir a nova configuração de imports da classe NavMenuItemDetailsLookup:
import thiengo.com.br.blueshoes.view.NavMenuItemsAdapter
Importante ressaltar que em toda esta atualização de projeto para o AndroidX somente alguns imports e algumas referências em layout é que serão alteradas, os códigos dinâmicos continuarão sendo os mesmos.
Atualização da classe NavMenuItemKeyProvider
Abaixo a nova configuração de importações da classe NavMenuItemKeyProvider:
import androidx.recyclerview.selection.ItemKeyProvider
Atualização da classe NavMenuItemPredicate
Assim a configuração de importações da classe NavMenuItemPredicate:
import androidx.recyclerview.selection.SelectionTracker
import thiengo.com.br.blueshoes.data.NavMenuItemsDataBase
import thiengo.com.br.blueshoes.view.MainActivity
Atualização da atividade abstrata FormActivity
Agora, já no pacote /view (em meu projeto é /view, em alguns outros é /ui), vamos a atualização da configuração de imports da atividade ancestral de atividades que contêm formulário, FormActivity.
Deixe as importações desta atividade como a seguir:
Note que no caso do componente SnackBar o import era android.support.design.widget.Snackbar e agora é com.google.android.material.snackbar.Snackbar, e é isso mesmo, sem o androidx como parte do namespace, mas não deixa de se parte do AndroidX.
A FormActivity já é uma das classes que referencia também a layouts. Com isso vamos a verificação (e a atualização, caso não tenha ocorrido no processo de migração automática do Android Studio) destes layouts.
Os trechos atualizados para a versão AndroidX estarão em destaque.
Primeiro o layout /res/layout/activity_form.xml:
Agora o layout de barra de topo /res/layout/app_bar.xml:
AppBarLayout é outra das novas referências que não utiliza como parte do namespace o termo androidx.
E por fim o layout de bloco de conteúdo /res/layout/content_form.xml:
Note que dentro dos conjuntos de layouts apresentados há outros layouts, porém eles continuam com a mesma configuração de quando utilizando a Support Library, logo, nós não os mostraremos aqui, pois não há necessidade.
Atualização da atividade FormEmailAndPasswordActivity
Ainda no contexto de formulários, vamos a atualização de outra classe abstrata, a FormEmailAndPasswordActivity. As importações ficam como a seguir:
Apesar de ser uma atividade, a FormEmailAndPasswordActivity não trabalha diretamente com nenhum arquivo de layout.
Atualização da atividade de login
Para a LoginActivity as importações agora ficam como a seguir:
import com.blankj.utilcode.util.ActivityUtils
No layout desta atividade, /res/layout/content_login.xml, somente a referência a ConstraintLayout é que é atualizada:
Novamente: os layouts referenciados internamente e que não têm necessidade de atualizações não serão citados.
Atualização da atividade de cadastro de novo usuário
Para a SignUpActivity as importações ficam como abaixo:
E o único trecho de atualização no layout da atividade de cadastro, /res/layout/content_sign_up.xml, é o mesmo da atividade de login:
Atualização da atividade de itens de configuração de conta
Na AccountSettingsActivity as importações ficam como a seguir:
import kotlinx.android.synthetic.main.content_account_settings.*
import thiengo.com.br.blueshoes.data.AccountSettingsItemsDataBase
import thiengo.com.br.blueshoes.domain.User
No layout /res/layout/activity_account_settings.xml temos a seguinte nova configuração:
E no layout /res/layout/content_account_settings.xml temos a seguinte nova referência em <RecyclerView>:
Ainda temos a classe adaptadora de itens do framework de lista em AccountSettingsActivity.
Atualização do adapter da AccountSettingsActivity
Em AccountSettingsItemsAdapter teremos a seguinte configuração de importações:
import thiengo.com.br.blueshoes.domain.AccountSettingItem
O layout de item, /res/layout/account_settings_item.xml, continua o mesmo como quando com a Support Library.
Atualização da atividade de formulário de perfil de usuário
Para a ConfigProfileActivity teremos a seguinte configuração de imports:
import kotlinx.android.synthetic.main.content_config_profile.*
Para o layout de ConfigProfileActivity, /res/layout/content_config_profile.xml, temos a referência a ConstraintLayout sendo atualizada:
Atualização do fragmento Sobre
Agora vamos às entidades ligadas diretamente a MainActivity. Começando pelos imports do fragmento AboutFragment:
Assim a única atualização do layout deste fragmento, /res/layout/fragment_about.xml:
Atualização do fragmento de Contato
Agora os imports do fragmento ContactFragment:
import kotlinx.android.synthetic.main.fragment_contact.*
import kotlinx.android.synthetic.main.info_block.*
Assim, como em AboutFragment, a única atualização do layout deste fragmento, /res/layout/fragment_contact.xml:
Atualização do fragmento de Políticas de Privacidade
Assim os imports do fragmento PrivacyPolicyFragment:
import android.text.Annotation
import android.text.SpannedString
import kotlinx.android.synthetic.main.fragment_privacy_policy.*
import thiengo.com.br.blueshoes.util.CustomTypefaceSpan
Por fim a simples atualização do layout deste fragment, o layout /res/layout/fragment_privacy_policy.xml:
Atualização do adapter de itens de menu gaveta
Agora a atualização da classe adaptadora de itens de menu gaveta, a classe NavMenuItemsAdapter.
As importações desta classe ficam como a seguir:
import thiengo.com.br.blueshoes.util.NavMenuItemDetails
O layout de item desta classe adaptadora continua o mesmo como antes da atualização para o AndroidX.
Por fim a atualização da MainActivity. A seguir a nova configuração de imports desta classe:
import androidx.recyclerview.selection.StorageStrategy
import kotlinx.android.synthetic.main.nav_header_user_logged.*
import kotlinx.android.synthetic.main.nav_header_user_not_logged.*
import kotlinx.android.synthetic.main.nav_menu.*
import thiengo.com.br.blueshoes.util.NavMenuItemDetailsLookup
import thiengo.com.br.blueshoes.util.NavMenuItemKeyProvider
import thiengo.com.br.blueshoes.util.NavMenuItemPredicate
Assim as atualizações de layouts referenciados a partir da MainActivity e ainda não atualizados.
Primeiro o layout principal, /res/layout/activity_main.xml:
Agora o layout de menu gaveta, /res/layout/nav_menu.xml:
Por fim o layout que contém a área de topo e de conteúdo da MainActivity, /res/layout/app_bar_main.xml:
Agora sim é um bom momento para sincronizar o projeto. Não deverá ter erros ao final da sincronia.
Trabalhando a tela de galeria e de câmera
Vamos agora ao desenvolvimento da tela de galeria, tela que terá também a responsabilidade de permitir que o usuário tire uma foto para poder coloca-la como foto de perfil.
Primeiro vamos aos trechos que não exigem lógica de negócio: explicações, configurações e arquivos estáticos. Posteriormente vamos aos códigos dinâmicos.
Por que a ImagePicker API foi escolhida?
Primeiro: trabalhar com todo o código nativo do Android para poder solicitar permissões necessárias em tempo de execução, apresentar imagens do SDCard e ainda permitir a fotografia, todo o código que representa estas necessidades tomaria muito de nosso tempo.
O nosso domínio de problema é: vendas pelo aplicativo mobile BlueShoes. Ou seja, temos de investir mais tempo no processo de apresentação e compra dos calçados.
O que temos de fazer em todos os outros pontos do aplicativo é permitir que o usuário acesse qualquer funcionalidade de maneira consistente e amigável.
Junte a isso tudo a possibilidade de o nosso código de seleção de imagens não ser tão bom quanto o código de uma API construída especificamente para isso e já utilizada por inúmeros desenvolvedores.
Com o que foi explicado nos parágrafos acima já dá para entender a importância de escolhermos uma API de terceiro para a funcionalidade de galeria do projeto.
Agora o porquê de termos escolhido a ImagePicker API é simples:
É uma API ainda mantida pelo principal desenvolvedor dela - atualizada de acordo com as atualizações do Android SDK;
Eu já trabalhei com ela em outros projetos, onde o funcionamento foi exatamente como esperado;
Ela já tem código embutido para a solicitação de permissão em tempo de execução;
A configuração e personalização da galeria é simples.
Há inúmeras outras APIs de seleção de imagens, incluindo APIs com 20 vezes mais estrelas no GitHub do que a ImagePicker API, porém com um código, em meu ponto de vista, pouco eficiente em relação ao contexto de: acesso a imagens e a câmera do aparelho.
Se quiser saber mais sobre a ImagePicker API, não deixe de acessar a documentação oficial dela (em inglês): nguyenhoanglam/ImagePicker.
Atualizando o Gradle de Nível de Projeto
Explicado o porquê de estarmos utilizando a ImagePicker API, agora vamos a integração dela ao aplicativo. No Gradle Nível de Projeto, build.gradle (Projeto: BlueShoes), adicione os trechos em destaque:
Atualizando o Gradle de Nível de Aplicativo
Agora no Gradle Nível de Aplicativo, build.gradle (Module: app), adicione as dependências em destaque:
/* Image Gallery e Camera API */
Assim, sincronize o projeto.
Adicionando permissões ao AndroidMenifest
Apesar de a documentação oficial da ImagePicker API não informar sobre a necessidade de colocarmos em AndroidManifest as permissões necessárias de acesso ao SDCard e de acesso à câmera do dispositivo, eu fortemente recomendo que você faça como em nosso projeto e sempre adicione as permissões que poderão ser solicitadas.
No AndroidManifest.xml adicione os códigos em destaque:
Todas as permissões definidas acima são "dangerous permissions", mas vale ressaltar que todo o código de solicitação de permissão em tempo de execução é também administrado pela ImagePicker API.
Agora vamos a um dos arquivos mais editados do projeto, o arquivo de Strings, /res/values/strings.xml. Vamos adicionar rótulos e sobrescrever um especifico do layout de galeria da ImagePicker:
<!-- Image Picker API - Adição e sobreposição de String -->
<string name="imagepicker_msg_no_images">
Não há imagens na galeria.
<string name="imagepicker_gallery_activity">Galeria</string>
<string name="imagepicker_cam_photos_activity">
Fotos câmera BlueShoes
<string name="imagepicker_selection_limit">
Apenas uma imagem pode ser selecionada.
Um dos pontos negativos da API: ela não tem o arquivo /strings.xml para o português do Brasil. Sendo assim é preciso também a sobrescrita, que não deixa de ser um passo simples.
Ok, Thiengo. Mas como você sabe que os rótulos utilizados no layout da ImagePicker API são esses definidos no strings.xml do projeto?
Na verdade eu somente tive de descobrir um rótulo, o imagepicker_msg_no_images, pois a API não me dá um método para a atualização deste texto, que aparece quando não há imagens no SDCard do aparelho.
Eu encontrei este rótulo navegando pela documentação da API, pois na descrição para desenvolvedores não havia essa informação.
Todos os outros rótulos, mesmo que com o prefixo imagepicker_, foram criados por mim em conformidade com os rótulos já utilizados internamente pela API, porém estes são utilizados em código dinâmico por meio de métodos que a própria API fornece para mudança de alguns textos dentro dela.
Sobrescrevendo estilos da ImagePicker API
Sem a sobrescrita de tema o que obteríamos como barra de topo da ImagePicker API seria:
Sendo que no protótipo estático temos a seguinte exigência:
E, acredite, a sobrescrita é de um mesmo tema, imagepicker_ToolbarTitleText (também encontrado por meio da navegação do projeto no GitHub), porém em mais de um folder, para atender a diferentes versões do Android.
Em /res/values/styles.xml adicione os trechos em destaque:
Sobrescrevendo o tema imagepicker_ToolbarTitleText da
ImagePicker API para que o estilo de título em barra de
topo do aplicativo BlueShoes também seja aplicado às
atividades desta API.
name="imagepicker_ToolbarTitleText"
parent="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title">
Agora em /res/values-v21/styles.xml adicione os trechos em destaque:
parent="@android:style/TextAppearance.Material.Widget.ActionBar.Title">
O estilo em styles.xml v21 também foi necessário, pois a ImagePicker também tem uma versão de estilo no styles.xml v21 dela.
O novo campo de imagem do formulário de perfil
Infelizmente não é inteligente manter o uso do ImageView como campo de imagem de perfil no formulário de usuário, pois para mantermos a imagem selecionada pelo usuário com o shape arredondado será mais crítico do que se estivéssemos apenas utilizando uma RoundedImageView, API já presente em projeto.
Sendo assim, vamos às mudanças necessárias para passarmos a utilizar uma RoundedImageView no formulário de perfil.
Primeiro a imagem padrão, ou hint image, quando não há imagem nenhuma no campo. Antes tínhamos apenas um ícone de fotografia, agora todo o campo é uma imagem. Imagem que pode ser descarregada diretamente da documentação oficial de nosso projeto:
/res/drawable-mdpi/profile_hint.png;
/res/drawable-hdpi/profile_hint.png;
/res/drawable-xhdpi/profile_hint.png;
/res/drawable-xxhdpi/profile_hint.png.
Coloque as imagens em seus respectivos folders drawable.
Agora a atualização em layout, /res/layout/content_config_profile.xml, onde a RoundedImageView entrará no lugar do ImageView (o ID da View também será atualizado):
android:id="@+id/riv_profile"
android:src="@drawable/profile_hint"
android:onClick="callGallery"
app:riv_border_color="@color/colorViewLine"
app:riv_border_width="1dp"
app:riv_corner_radius="108dp"
app:riv_mutate_background="false"
app:riv_oval="true"
app:riv_tile_mode="clamp"/>
app:layout_constraintTop_toTopOf="@+id/riv_profile"
app:layout_constraintBottom_toBottomOf="@+id/riv_profile"
app:layout_constraintLeft_toRightOf="@+id/riv_profile"
Note que não mais estamos utilizando o arquivo de background bg_image_view_profile.xml, logo, delete-o do projeto. Delete também todas as versões do ícone ic_photo_black_24dp.png.
Abaixo o novo diagrama do layout content_config_profile.xml:
Ainda são necessárias algumas poucas atualizações em ConfigProfileActivity para que riv_profile seja utilizado no lugar de iv_profile:
class ConfigProfileActivity : ... {
override fun blockFields( ... ){
riv_profile.isEnabled = !status
private fun changeTargetViewConstraints( ... ){
val photoProfileId = riv_profile.id
val parent = riv_profile.parent as ConstraintLayout
E uma última atualização, nesta seção, para que o formulário de atualização de perfil já inicie com alguma imagem de perfil caso o objeto user tenha alguma presente:
riv_profile.setImageResource(
user?.image ?: R.drawable.profile_hint
O algoritmo acima, ao final do método onCreate() da ConfigProfileActivity, é temporário até o momento que começarmos a trabalhar com a imagem de perfil em back-end Web, onde certamente teremos o path dela e assim uma API como a Picasso será utilizada para o carregamento remoto.
Assim podemos partir para a configuração final da galeria.
Configurando a galeria e a câmera
Ainda na atividade ConfigProfileActivity, mas agora no método callGallery(), adicione os códigos ImagePicker em destaque:
fun callGallery( view: View ){
val colorPrimary = ColorUtils.int2ArgbString(
ColorUtils.getColor(R.color.colorPrimary)
val colorPrimaryDark = ColorUtils.int2ArgbString(
ColorUtils.getColor(R.color.colorPrimaryDark)
val colorText = ColorUtils.int2ArgbString(
ColorUtils.getColor(R.color.colorText)
val colorWhite = ColorUtils.int2ArgbString(
.with( this ) /* Inicializa a ImagePicker API com um context (Activity ou Fragment) */
.setToolbarColor( colorPrimary )
.setStatusBarColor( colorPrimaryDark )
.setToolbarTextColor( colorText )
.setToolbarIconColor( colorText )
.setProgressBarColor( colorPrimaryDark )
.setBackgroundColor( colorWhite )
.setMultipleMode( false )
.setFolderMode( true )
.setShowCamera( true )
.setFolderTitle( getString(R.string.imagepicker_gallery_activity) ) /* Nome da tela de galeria da ImagePicker API (funciona quando FolderMode = true). */
.setLimitMessage( getString(R.string.imagepicker_selection_limit) )
.setSavePath( getString(R.string.imagepicker_cam_photos_activity) ) /* Folder das imagens de câmera, tiradas a partir da ImagePicker API. */
.setKeepScreenOn( true ) /* Mantém a tela acionada enquanto a galeria estiver aberta. */
Os métodos que não estão seguidos de comentários têm os rótulo autoexplicativos sobre eles. Há inúmeras outras opções de configuração, mas as definidas no código anterior são as que atendem a nossa necessidade em projeto.
Por fim a configuração do método onActivityResult() para podermos trabalhar a resposta da tela de galeria:
data: Intent? ) {
if( requestCode == RC_PICK_IMAGES
&& data != null ){
val images = data.getParcelableArrayListExtra<Image>( EXTRA_IMAGES )
if( images.isNotEmpty() ){
riv_profile.setImageURI(
Uri.parse( images.first().path )
* Note que em nossa lógica de negócio, se não houver imagem
* selecionada, o que estiver atualmente presente como imagem
* de perfil continua sendo a imagem de perfil.
* A invocação a super.onActivityResult() tem que
* vir após a verificação / obtenção da imagem.
super.onActivityResult( requestCode, resultCode, data )
Como sempre estaremos esperando 0 ou 1 imagem, é seguro trabalharmos com images.first().path, digo, o método first() na collection images.
Em seu Android Studio, acesse o menu de topo e logo depois acesse "Build", então clique em "Rebuid project". Ao final do rebuild execute o aplicativo em seu emulador Android.
Acessando a tela de atualização de dados de perfil e então seguindo à galeria, temos:
Agora acessando a câmera por meio da galeria, temos:
Com isso finalizamos mais um passo importante para o projeto Android mobile-commerce: a atualização para o AndroidX e a finalização da UI de edição de dados de perfil de usuário.
Antes de prosseguir, não esqueça de se inscrever na 📫 lista de emails do Blog para receber também todas as aulas do projeto Android BlueShoes.
A seguir os vídeos com o passo a passo de atualização do projeto para uso do AndroidX e a integração da ImagePicker API para as funcionalidades de galeria e câmera:
Em resumo, e já um clichê, temos: não reinvente a roda. Se a funcionalidade em trabalho em seu projeto não é uma funcionalidade diretamente ligada ao domínio de problema dele, então busque alguma API para a fácil integração, mas busque uma API consistente, mesmo que ela seja pouco conhecida.
Sobre o AndroidX, como informado anteriormente: adiantamos uma dor que seria inevitável, a dor da migração de código. Porém agora nosso projeto está mais atual.
Agora é focar nas próximas partes de UI de nosso Android mobile-commerce para logo logo entrarmos na área de lógica, onde também teremos a parte Web.
Get color resource as string - Resposta de N J
androidx.constraintlayout.widget.constraintlayout don't have chains that you can drag - Resposta de Arvin Rokni
Android; Check if file exists without creating a new one - Resposta de Maikel Bollemeijer
Show Image View from file path? - Resposta de Paresh Mayani
Kotlin documentation - Null Safety
Como Entrar na Europa Como Profissional de TI e Com o Tech VisaEmpreendedorismo
android - e-commerce - support library - câmera - mobile-commerce - perfil de usuário - galeria - imagepicker - androidx