Criando a Tela de Cadastro de Usuário - Android M-Commerce

Receba em primeira mão, e com prioridade, os conteúdos Android exclusivos do Blog. Você receberá um email de confirmação. Somente depois de confirma-lo é que poderei lhe enviar os conteúdos exclusivos.

Email inválido.
Blog /Android /Criando a Tela de Cadastro de Usuário - Android M-Commerce

Criando a Tela de Cadastro de Usuário - Android M-Commerce

Vinícius Thiengo
(854) (9)
Go-ahead
"Não espere pela perfeição. A vida não é perfeita. Faça o melhor que puder. As pessoas reais constroem, em seguida, elas testam e, em seguida, elas constroem novamente. Então você acorda um dia e você tem algo insanamente grande."
Guy Kawasaki
Kotlin Android
Capa do livro Desenvolvedor Kotlin Android - Bibliotecas para o dia a dia
TítuloDesenvolvedor Kotlin Android - Bibliotecas para o dia a dia
CategoriasAndroid, Kotlin
AutorVinícius Thiengo
Edição
Capítulos19
Páginas1035
Acessar Livro
Treinamento Oficial
Android: Prototipagem Profissional de Aplicativos
CursoAndroid: Prototipagem Profissional de Aplicativos
CategoriaAndroid
InstrutorVinícius Thiengo
NívelTodos os níveis
Vídeo aulas186
PlataformaUdemy
Acessar Curso
Receitas Android
Capa do livro Receitas Para Desenvolvedores Android
TítuloReceitas Para Desenvolvedores Android
CategoriaDesenvolvimento Android
AutorVinícius Thiengo
Edição
Ano2017
Capítulos20
Páginas936
Acessar Livro
Código Limpo
Capa do livro Refatorando Para Programas Limpos
TítuloRefatorando Para Programas Limpos
CategoriaEngenharia de Software
AutorVinícius Thiengo
Edição
Ano2017
Capítulos46
Páginas599
Acessar Livro
Quer aprender a programar para Android? Acesse abaixo o curso gratuito no Blog.
Conteúdo Exclusivo
Receba em primeira mão, e com prioridade, os conteúdos Android exclusivos do Blog.
Email inválido

Tudo bem?

Neste artigo vamos ao desenvolvimento da tela de cadastro de novo usuário do projeto Android mobile-commerce, BlueShoes.

Animação de acesso a tela de cadastro de usuário do app Android BlueShoes

Como aconteceu com o desenvolvimento da tela de recuperação de acesso, aqui também será tudo bem simples, rápido e produtivo, isso por ainda estarmos colhendo os frutos da refatoração que aplicamos ao projeto na sétima aula.

Antes de prosseguir, não esqueça de se inscrever 📩 na lista de emails do Blog para ter acesso exclusivo às aulas do projeto e a todos os outros conteúdos sobre desenvolvimento Android.

A seguir os tópicos abordados neste conteúdo:

Estou iniciando agora no projeto Android BlueShoes

Se você chegou no projeto Android BlueShoes somente agora, saiba que já existem oito aulas disponíveis que precisam ser estudadas antes da aula deste artigo:

Surgindo dúvidas, pode deixar nos comentários dos artigos ou enviar direto ao e-mail oficial do Blog e canal.

Estratégia para a tela de cadastro de novo usuário

Primeiro vale ressaltar que estamos na parte de desenvolvimento do projeto Android onde somente a interface gráfica é nosso alvo em codificação.

Os trechos de lógica, persistência de dados e outros serão desenvolvidos posteriormente à UI.

Logo, nossa estratégia para a tela de cadastro de novo usuário é já conhecida:

  • Primeiro vamos a algumas modificações em projeto que facilitem todo o desenvolvimento desta nova tela;
  • Depois vamos ao desenvolvimento de partes mais simples, de conteúdo estático, arquivos XML principalmente;
  • E por fim vamos aos trechos de código dinâmico, em Kotlin.

Antes de prosseguir com a nova aula, saiba que o projeto BlueShoes esta por completo no GitHub dele em: https://github.com/viniciusthiengo/blueshoes-kotlin-android.

Protótipo estático

Abaixo o protótipo estático da tela de cadastro de novo cliente BlueShoes:

Cadastro

Cadastro

Tentativa de cadastro

Tentativa de cadastro

Erro no cadastro

Erro no cadastro

 

 

Melhorando o projeto antes da SignUpActivity

Nosso primeiro passo na construção da tela de cadastro é atualizar alguns trechos do projeto que facilitarão ainda mais a criação desta tela, mesmo se for com o objetivo de somente diminuir o número de códigos repetidos.

Update no Gradle Level de Projeto

Durante o desenvolvimento do aplicativo o IDE Android Studio passou por atualizações e assim temos que o Gradle Nível de Projeto, ou build.gradle (Project: BlueShoes), teve dois pontos atualizados (em destaque abaixo):

buildscript {
ext.kotlin_version = '1.3.30'
repositories {
...

}
dependencies {
classpath 'com.android.tools.build:gradle:3.3.2'
...
}
}
...

 

Ao final da atualização sincronize o projeto.

Atualizando novamente o estilo ButtonForm

Na aula de criação da tela de recuperação de acesso acabamos "papando mosca" e um ponto estrutural do estilo de botões de formulários não foi atualizado, digo, movido para o estilo em styles.xml.

Mais precisamente, estamos falando de android:layout_marginTop="12dp", algo comum já a dois botões do projeto, login e recuperação de senha, e que também será comum no formulário de cadastro de novo usuário.

Sendo assim, em /res/values/styles.xml, adicione ao estilo ButtonForm o trecho de código em destaque:

...
<style name="ButtonForm">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:paddingLeft">38dp</item>
<item name="android:paddingRight">38dp</item>
<item name="android:layout_marginTop">12dp</item>
<item name="android:background">@drawable/bt_nav_header_login_bg</item>
<item name="android:textColor">@android:color/white</item>
<item name="android:textAllCaps">false</item>
</style>
...

 

Agora, em /res/layout/content_login.xml, exatamente no Button, remova essa margem de topo, pois ela já está no estilo definido em styles.xml:

...
<Button
android:id="@+id/bt_login"
style="@style/ButtonForm"
app:layout_constraintTop_toBottomOf="@+id/ll_container_fields"
app:layout_constraintRight_toRightOf="@+id/ll_container_fields"
android:onClick="mainAction"
android:text="@string/sign_in"/>
...

 

Faça o mesmo com o Button de /res/layout/content_forgot_password.xml, remova a margem de topo:

...
<Button
android:id="@+id/bt_recover_password"
style="@style/ButtonForm"
app:layout_constraintTop_toBottomOf="@+id/et_email"
app:layout_constraintRight_toRightOf="@+id/et_email"
android:onClick="mainAction"
android:text="@string/recover_password"/>
...

 

E por fim, agora no layout de menu gaveta de usuário não conectado, mais precisamente no cabeçalho deste tipo de menu, adicione um android:layout_marginTop="0dp", pois aqui realmente não há margem de topo e o botão de login deste cabeçalho tem exatamente o mesmo estilo sendo aplicado.

No Button de /res/layout/nav_header_user_not_logged.xml.xml coloque o código em destaque:

...
<Button
android:id="@+id/bt_login"
style="@style/ButtonForm"
android:paddingLeft="30dp"
android:paddingRight="30dp"
android:layout_marginTop="0dp"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:text="@string/tx_login"
android:onClick="callLoginActivity"/>
...

 

Assim podemos partir para a atividade de cadastro.

Trabalhando a SignUpActivity

Como informado em início de artigo: aqui o desenvolvimento será rápido, principalmente devido aos códigos já encapsulados em outras aulas.

Não deixe de implementar passo a passo o que está sendo feito. Surgindo dúvidas, pode deixar logo abaixo nos comentários.

Arquivo de Strings

Aqui vamos primeiro a um dos arquivos que dispensam, desde o início, a presença da atividade de cadastro. Em /res/values/strings.xml adicione os trechos de código em destaque:

<resources>
...

<!-- SignUpActivity -->
<string name="title_activity_sign_up">
Cadastro
</string>

<string name="hint_email_to_login">E-mail (para login)</string>
<string name="hint_confirm_password">Confirmar senha</string>
<string name="do_login">Realizar login</string>
<string name="sign_up">Cadastrar</string>
<string name="sign_up_going">Cadastrando&#8230;</string>
<string name="invalid_sign_up_email">
E-mail já cadastrado.
</string>
<string name="invalid_confirmed_password">
Confirme a senha informada no campo acima.
</string>
</resources>

 

Lembrando que estes são códigos possíveis de serem obtidos com o estudo do protótipo estático do projeto.

Você deve ter notado, em sua instalação do Android Studio, que o IDE "reclamou" em relação ao rótulo de String sign_up, isso, pois este já está sendo utilizado em:

...
<string name="sign_up">
Criar minha conta
</string>
...

 

No bloco de Strings para a LoginActivity.

Sendo assim, para a String "Criar minha conta" aplique o renomear como a seguir:

  • Selecione o rótulo sign_up;
  • Clique com o botão direito na seleção;
  • Acesse Refactor;
  • Clique em Rename...;
  • Na caixa de texto do dialog aberto coloque create_my_account;
  • Clique em Refactor

Renomeando rótulo de String

Pronto, correção realizada.

Drawables para o campo central de formulário

Se você reparar bem no protótipo estático da tela de cadastro notará que o campo do meio do formulário não tem curvatura aplicada às pontas:

Campos do formulário de cadastro de novo usuário

Sendo assim temos de criar um conjunto de drawables que permitem também mais essa configuração de design. Confesso que será tudo muito parecido com o que criamos até o momento, mudando apenas um detalhe, o radius.

Em /res/drawable crie o arquivo bg_form_field_square.xml, pode ser com Ctrl C + Ctrl V, com o código a seguir:

<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">

<!--
Definindo a cor de background - branca.
-->
<solid android:color="@android:color/white" />

<!--
Definindo bordas de 1dp de espessura e na cor
cinza.
-->
<stroke
android:color="@color/colorViewLine"
android:width="1dp" />
</shape>

 

O arquivo anterior será utilizado no campo central do formulário quando ele não estiver com foco.

Esse arquivo agora é para quando o campo de senha estiver em foco. Ainda em /res/drawable crie o arquivo bg_form_field_square_focused.xml com o código abaixo:

<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">

<!--
Definindo a cor de background - azul claro.
-->
<solid android:color="@color/colorFieldFocused" />

<!--
Definindo bordas de 1dp de espessura e na cor
cinza.
-->
<stroke
android:color="@color/colorViewLine"
android:width="1dp" />
</shape>

 

E por fim o drawable que realmente será referenciado no atributo android:background do campo de senha do formulário de cadastro. Ainda em /res/drawable crie o arquivo bg_form_field_sqr.xml com o código XML a seguir:

<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android">

<!--
Drawable utilizado quando a View alvo está com
foco.
-->
<item
android:state_focused="true"
android:drawable="@drawable/bg_form_field_square_focused" />

<!--
Drawable utilizado quando a View alvo não está
com foco.
-->
<item
android:drawable="@drawable/bg_form_field_square" />
</selector>

Layout do formulário de novo usuário

O layout da atividade de cadastro é bem simples, lembra muito o layout da tela de login, incluindo o uso do link de políticas de privacidade.

Em /res/layout crie o arquivo content_sign_up.xml com o seguinte código XML:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:padding="16dp"
android:layout_width="match_parent"
android:layout_height="match_parent">

<LinearLayout
android:id="@+id/ll_container_fields"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent">

<EditText
android:id="@+id/et_email"
style="@style/EditTextFormField"
android:background="@drawable/bg_form_field_top"
android:inputType="textEmailAddress"
android:imeOptions="actionNext"
android:hint="@string/hint_email_to_login"/>

<EditText
android:id="@+id/et_password"
style="@style/EditTextFormField"
android:layout_marginTop="-1dp"
android:background="@drawable/bg_form_field_sqr"
android:inputType="textPassword"
android:imeOptions="actionNext"
android:hint="@string/hint_password"/>

<EditText
android:id="@+id/et_confirm_password"
style="@style/EditTextFormField"
android:layout_marginTop="-1dp"
android:background="@drawable/bg_form_field_bottom"
android:inputType="textPassword"
android:imeOptions="actionDone"
android:hint="@string/hint_confirm_password"/>
</LinearLayout>

<TextView
android:id="@+id/tv_login"
style="@style/TextViewLink"
android:layout_marginTop="12dp"
app:layout_constraintTop_toBottomOf="@+id/ll_container_fields"
app:layout_constraintLeft_toLeftOf="@+id/ll_container_fields"
android:text="@string/do_login"/>

<Button
android:id="@+id/bt_sign_up"
style="@style/ButtonForm"
app:layout_constraintTop_toBottomOf="@+id/ll_container_fields"
app:layout_constraintRight_toRightOf="@+id/ll_container_fields"
android:onClick="mainAction"
android:text="@string/sign_up"/>

<include layout="@layout/text_view_privacy_policy_login"/>

</android.support.constraint.ConstraintLayout>

 

Note que como mainAction() é um método já conhecido para atividades do projeto que contenham formulários, aqui já o colocamos em Button.

Thiengo, uma dúvida: com o link de políticas sendo utilizado, na mesma posição que quando no layout da LoginActivity, isso quer dizer que todos aqueles códigos de posicionamento de link de políticas de privacidade serão novamente necessários?

Sim, porém agora na atividade de cadastro de novo usuário.

A seguir o diagrama do layout content_sign_up.xml:

Diagrama do layout content_sign_up.xml

Criando a SignUpActivity

Como fizemos na aula de criação da atividade de recuperação de acesso, ForgotPasswordActivity, aqui também agilizaremos a criação da atividade de cadastro.

Copie e cole, no mesmo pacote /view, a atividade LoginActivity, porém agora com o rótulo SignUpActivity.

O código dinâmico desta nova atividade será como a seguir:

class SignUpActivity :
FormActivity(),
KeyboardUtils.OnSoftInputChangedListener {

override fun onCreate( savedInstanceState: Bundle? ) {
super.onCreate( savedInstanceState )

/*
* Colocando a View de um arquivo XML como View filha
* do item indicado no terceiro argumento.
* */
View.inflate(
this,
R.layout.content_sign_up,
fl_form
)

/*
* Com a API KeyboardUtils conseguimos de maneira
* simples obter o status atual do teclado virtual (aberto /
* fechado) e assim prosseguir com algoritmos de ajuste de
* layout.
* */
KeyboardUtils.registerSoftInputChangedListener( this, this )

/*
* Colocando configuração de validação de campo de email
* para enquanto o usuário informa o conteúdo deste campo.
* */
et_email.validate(
{
it.isValidEmail()
},
getString( R.string.invalid_email )
)

/*
* Colocando configuração de validação de campo de senha
* para enquanto o usuário informa o conteúdo deste campo.
* */
et_password.validate(
{
it.isValidPassword()
},
getString( R.string.invalid_password )
)

/*
* Colocando configuração de validação de campo de
* confirmação de senha para enquanto o usuário informa o
* conteúdo deste campo.
* */
et_confirm_password.validate(
{
/*
* O toString() em et_password.text.toString() é
* necessário, caso contrário a validação falha
* mesmo quando é para ser ok.
* */
(et_password.text.isNotEmpty()
&& it.equals( et_password.text.toString() ))
|| et_password.text.isEmpty()
},
getString( R.string.invalid_confirmed_password )
)

et_confirm_password.setOnEditorActionListener( this )
}

override fun onDestroy() {
KeyboardUtils.unregisterSoftInputChangedListener( this )
super.onDestroy()
}

override fun mainAction( view: View? ){
blockFields( true )
isMainButtonSending( true )
showProxy( true )
backEndFakeDelay(
false,
getString( R.string.invalid_sign_up_email )
)
}

override fun blockFields( status: Boolean ){
et_email.isEnabled = !status
et_password.isEnabled = !status
et_confirm_password.isEnabled = !status
bt_sign_up.isEnabled = !status
}

override fun isMainButtonSending( status: Boolean ){
bt_sign_up.text =
if( status )
getString( R.string.sign_up_going )
else
getString( R.string.sign_up )
}

override fun onSoftInputChanged( height: Int ) {
changePrivacyPolicyConstraints(
KeyboardUtils.isSoftInputVisible( this )
)
}

private fun changePrivacyPolicyConstraints(
isKeyBoardOpened: Boolean
){

val privacyId = tv_privacy_policy.id
val parent = tv_privacy_policy.parent as ConstraintLayout
val constraintSet = ConstraintSet()

/*
* Definindo a largura e a altura da View em
* mudança de constraints, caso contrário ela
* fica com largura e altura em 0dp.
* */
constraintSet.constrainWidth(
privacyId,
ConstraintLayout.LayoutParams.WRAP_CONTENT
)
constraintSet.constrainHeight(
privacyId,
ConstraintLayout.LayoutParams.WRAP_CONTENT
)

/*
* Centralizando a View horizontalmente no
* ConstraintLayout.
* */
constraintSet.centerHorizontally(
privacyId,
ConstraintLayout.LayoutParams.PARENT_ID
)

if( isKeyBoardOpened || ScreenUtils.isLandscape() ){
/*
* Se o teclado virtual estiver aberto, então
* mude a configuração da View alvo
* (tv_privacy_policy) para ficar vinculada a
* View acima dela (tv_sign_up).
* */
constraintSet.connect(
privacyId,
ConstraintLayout.LayoutParams.TOP,
bt_sign_up.id,
ConstraintLayout.LayoutParams.BOTTOM,
(12 * ScreenUtils.getScreenDensity()).toInt()
)
}
else{
/*
* Se o teclado virtual estiver fechado, então
* mude a configuração da View alvo
* (tv_privacy_policy) para ficar vinculada ao
* fundo do ConstraintLayout ancestral.
* */
constraintSet.connect(
privacyId,
ConstraintLayout.LayoutParams.BOTTOM,
ConstraintLayout.LayoutParams.PARENT_ID,
ConstraintLayout.LayoutParams.BOTTOM
)
}

constraintSet.applyTo( parent )
}


/* Listeners de clique */
fun callPrivacyPolicyFragment( view: View ){
val intent = Intent(
this,
MainActivity::class.java
)

/*
* Para saber qual fragmento abrir quando a
* MainActivity voltar ao foreground.
* */
intent.putExtra(
MainActivity.FRAGMENT_ID,
R.id.item_privacy_policy
)

/*
* Removendo da pilha de atividades a primeira
* MainActivity aberta (e a LoginActivity), para
* deixar somente a nova MainActivity com uma nova
* configuração de fragmento aberto.
* */
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP

startActivity( intent )
}
}

 

O que tem de diferente em relação a LoginActivity?

Primeiro o carregamento do layout correto logo no onCreate() da atividade de cadastro:

...
View.inflate(
this,
R.layout.content_sign_up,
fl_form
)
...

 

Assim o código de validação do campo de confirmação de senha e código de vinculo deste campo ao listener de ActionDone, ainda no onCreate() da atividade de cadastro:

...
et_confirm_password.validate(
{

/*
* O toString() em et_password.text.toString() é
* necessário, caso contrário a validação falha
* mesmo quando é para ser ok.
* */
(et_password.text.isNotEmpty()
&& it.equals( et_password.text.toString() ))
|| et_password.text.isEmpty()
},
getString( R.string.invalid_confirmed_password )
)

et_confirm_password.setOnEditorActionListener( this )
...

 

Os métodos abstratos de FormActivity: mainAction(), blockFields()isMainButtonSending(). Estes também têm todos os seus próprios códigos:

...
override fun mainAction( view: View? ){
blockFields( true )
isMainButtonSending( true )
showProxy( true )
backEndFakeDelay(
false,
getString( R.string.invalid_sign_up_email )
)
}

override fun blockFields( status: Boolean ){
et_email.isEnabled = !status
et_password.isEnabled = !status
et_confirm_password.isEnabled = !status
bt_sign_up.isEnabled = !status
}

override fun isMainButtonSending( status: Boolean ){
bt_sign_up.text =
if( status )
getString( R.string.sign_up_going )
else
getString( R.string.sign_up )
}
...

 

O método onSoftInputChanged() não tem mais o bloco condicional de verificação de tela em posicionamento portrait, isso, pois o código de changePrivacyPolicyConstraints() será também útil quando o aparelho estiver em landscape:

...
override fun onSoftInputChanged( height: Int ) {
changePrivacyPolicyConstraints(
KeyboardUtils.isSoftInputVisible( this )
)
}
...

 

Por fim uma atualização simples no método changePrivacyPolicyConstraints(), mais precisamente no primeiro bloco condicional deste. Ao invés de somente:

...
if( isKeyBoardOpened ){
...
constraintSet.connect(
privacyId,
ConstraintLayout.LayoutParams.TOP,
tv_sign_up.id,
ConstraintLayout.LayoutParams.BOTTOM,
(12 * ScreenUtils.getScreenDensity()).toInt()
)
}
else{
...
}
...

 

Agora temos:

if( isKeyBoardOpened || ScreenUtils.isLandscape() ){
...
constraintSet.connect(
privacyId,
ConstraintLayout.LayoutParams.TOP,
bt_sign_up.id,
ConstraintLayout.LayoutParams.BOTTOM,
(12 * ScreenUtils.getScreenDensity()).toInt()
)
}
else{
...
}
...

Ouvidor de clique para voltar a tela de login

Ainda temos de definir um listener de clique para que o link "Realizar login" permita ao usuário voltar a tela de login. Não que essa volta já não seja possível por outro caminho, mas para respeitar o que foi definido em protótipo estático.

Em SignUpActivity adicione o método a seguir, logo acima de callPrivacyPolicyFragment():

...
fun callLoginActivity( view: View ){
finish()
}
...

 

O código de callLoginActivity() é simples assim, pois a LoginActivity é o único caminho possível de acesso à SignUpActivity.

Agora no TextView de ID tv_login presente em /res/layout/content_sign_up.xml adicione o onClick em destaque:

...
<TextView
android:id="@+id/tv_login"
style="@style/TextViewLink"
android:layout_marginTop="12dp"
app:layout_constraintTop_toBottomOf="@+id/ll_container_fields"
app:layout_constraintLeft_toLeftOf="@+id/ll_container_fields"
android:text="@string/do_login"
android:onClick="callLoginActivity"/>
...

As importações da atividade de cadastro

Como há nas atividades de cadastro e de login Views com IDs semelhantes, é importante mostrar como fica realmente os imports de SignUpActivity:

...
import android.content.Intent
import android.os.Bundle
import android.support.constraint.ConstraintLayout
import android.support.constraint.ConstraintSet
import android.view.View
import com.blankj.utilcode.util.KeyboardUtils
import com.blankj.utilcode.util.ScreenUtils
import kotlinx.android.synthetic.main.content_form.*
import kotlinx.android.synthetic.main.content_sign_up.*
import kotlinx.android.synthetic.main.text_view_privacy_policy_login.*
import thiengo.com.br.blueshoes.R
import thiengo.com.br.blueshoes.util.isValidEmail
import thiengo.com.br.blueshoes.util.isValidPassword
import thiengo.com.br.blueshoes.util.validate
...

Atualizando o AndroidManifest

A atividade de cadastro ainda precisa ser configurada no AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest
...>

<application
...>

...

<activity
android:name=".view.SignUpActivity"
android:label="@string/title_activity_sign_up"
android:theme="@style/AppTheme.NoActionBar"/>
</application>
</manifest>

Atualizando o método callSignUpActivity() da LoginActivity

Para a última atualização de código, agora na LoginActivity, mais precisamente no método callSignUpActivity(), coloque o código a seguir em destaque:

...
fun callSignUpActivity( view: View ){
val intent = Intent(
this,
SignUpActivity::class.java
)

startActivity( intent )
}
...

Por que ainda vamos manter os códigos repetidos?

Você provavelmente deve ter notado que há muitos códigos na SignUpActivity que também estão presentes na LoginActivity e que a principio não devem estar na FormActivity, pois são códigos utilitários somente às atividades de login e de cadastro.

Muitos destes códigos não têm a refatoração simples, pois estão juntos a pequenos trechos de mudança.

Sendo assim, vamos deixar para uma próxima aula a refatoração destas duas atividades, onde possivelmente estaremos entrando com o uso de padrões de projeto.

Testes e resultados

Abra a sua instalação do Android Studio, acesse no menu de topo a opção "Build", em seguida clique em "Rebuid project". Ao final do rebuild execute o aplicativo em seu aparelho ou emulador Android de testes.

Não esqueça de colocar em teste o usuário com o status "não conectado", objeto presente na MainActivity:

...
val user = User(
"Thiengo Vinícius",
R.drawable.user,
false /* Não conectado. */
)
...

 

Acessando a área de cadastro de novo usuário e trabalhando com os campos, temos:

Animação do teste e uso da tela de cadastro de novo usuário

Assim finalizamos mais essa aula do projeto Android de mobile-commerce, BlueShoes, terminando a interface gráfica da tela de cadastro de novo usuário.

Antes de prosseguir, não esqueça de se inscrever na 📩 lista de emails do Blog para receber todas as aulas do app Android de mobile-commerce.

Se inscreva também no canal do Blog em: YouTube Thiengo.

Vídeos

A seguir os vídeos com o passo a passo do desenvolvimento da tela de cadastro de novo usuário e atualização de outras partes do projeto:

O projeto também pode ser acessado pelo GitHub dele em: https://github.com/viniciusthiengo/blueshoes-kotlin-android.

Conclusão

Novamente conseguimos usufruir das refatorações aplicadas em aulas anteriores do projeto Android BlueShoes, porém nesta tela de cadastro chegamos a um ponto do projeto onde somente encapsular trechos repetidos de código tende a não ser a melhor escolha.

Com isso vamos permitir que aqui alguns scripts se mantenham iguais até o momento onde provavelmente padrões de projeto serão utilizados.

Como principal diferencial tivemos mais uma série de arquivos drawables sendo criados para o campo central, campo de senha, do formulário da atividade de cadastro.

Caso você tenha dicas ou dúvidas para este projeto Android, deixe logo abaixo nos comentários ou envie direto ao e-mail oficial do Blog e canal.

Curtiu o conteúdo? Não esqueça de compartilha-lo. E, por fim, não deixe de se inscrever na 📩 lista de emails, respondo às suas dúvidas também por lá.

Abraço.

Receba em primeira mão, e com prioridade, os conteúdos Android exclusivos do Blog.
Email inválido

Relacionado

BottomNavigationView Android, Como e Quando UtilizarBottomNavigationView Android, Como e Quando UtilizarAndroid
Trabalhando Análise Qualitativa em seu Aplicativo AndroidTrabalhando Análise Qualitativa em seu Aplicativo AndroidAndroid
Lottie API Para Animações no AndroidLottie API Para Animações no AndroidAndroid
Android Mobile-Commerce, Apresentação e Protótipo do ProjetoAndroid Mobile-Commerce, Apresentação e Protótipo do ProjetoAndroid

Compartilhar

Comentários Facebook

Comentários Blog (9)

Para código / script, coloque entre [code] e [/code] para receber marcação especifica.
Forneça seu nome válido.
Forneça seu email válido.
Forneça o comentário.
Enviando, aguarde...
Alan Lucena (1) (0)
14/05/2019
Uma pergunta professor, eu terei maior aproveitamento lendo o artigo ou acompanhando as vídeo aulas, qual sua opinião quanto a isso?
Responder
Vinícius Thiengo (0) (0)
14/05/2019
Alan,

Minha recomendação sempre é: primeiro estude e implemente pelo artigo, por fim assista aos vídeos para pegar ainda mais detalhes.

Nos vídeos, muitas vezes, falo coisas gerais de desenvolvimento que podem lhe ser útil em algum momento, por isso também indico, ao final, o estudo também pelos vídeos.

Mas se você estiver com o tempo muito curto, então siga pelo artigo, ele é mais completo e simples de voltar caso você tenha ficado com dúvida em algo.

Abraço.
Responder
Alan Lucena (1) (0)
14/05/2019
Agradecido eternamente pelo que tem feito por mim e por outros tantos que ainda irão por vir!
Responder
Alan Lucena (1) (0)
08/05/2019
Bom dia professor, fazendo uns testes aqui como se fosse um usuário do app, constatei que o mesmo esta com um pequeno "bug", ao clicar para vermos, "Meus Pedidos" e depois clicamos em "Configurações" e depois na seta para voltar o app fecha inesperadamente, ja procurei o que poderia ser porém sem êxito, desde ja agradeço sua atenção professor, tenha um ótimo dia!
Responder
Vinícius Thiengo (0) (0)
14/05/2019
Alan, tudo bem?

Na verdade é um "bug aceitável", pois as opções de menu gaveta que permitem este problema ("Meus pedidos" e "Sair") não poderão nunca ser uma opção selecionada depois da volta de alguma opção de atividade.

Resumo: sempre que o usuário acessar a opção "Meus pedidos" a opção "Minhas configurações", na volta destas atividades somente opções de fragmento é que poderão estar novamente selecionadas.

A opção "Sair" não entra na explicação, pois ela acionará o recarregamento da atividade com o usuário desconectado, com o menu gaveta de "usuário não conectado" acionado, menu este que nem mesmo tem item que aciona alguma atividade.

Logo, o erro encontrado atualmente não deve ser corrigido, pois quando a atividade de "Meus pedidos" estiver pronta e a opção "Sair" estiver funcional ele não mais ocorrerá.

Na aula 12 do projeto eu pretendo falar mais sobre este "problema".

Abraço.
Responder
Alan Lucena (1) (0)
14/05/2019
Muito obrigado pelas explicações professor!
Responder
Alan Lucena (1) (0)
07/05/2019
Boa noite professor tudo bem com senhor, tira uma curiosidade por gentileza, ja temos uma previsão de quando iremos finalizar este app.
A curiosidade vai de encontra com o que comentou sobre webService do mesmo, pois tu indicou um curso sobre este que iriamos precisar "Curso do professor Boniek" pois ainda nem sei muita coisa para poder incrementar na integração do app com Web Site, por um acaso o senhor irá incrementar algo sobre o site deste app? Desde ja agradeço sua atenção!
Responder
Vinícius Thiengo (0) (0)
14/05/2019
Alan, tudo bem?

Não consigo lhe dar uma data de quando o projeto vai acabar, mas ele tem um fim, que é: criarmos todo o aplicativo funcional como definido em protótipo estático.

Estou engajado no projeto, confesso que até eu estou descobrindo algumas coisas novas, principalmente do Kotlin.

Pretendo seguir neste ritmo, ao menos uma aula por semana. Sei que é um tanto "desconfortável" não ter em mãos a data final, de entrega do projeto, mas minha prioridade aqui é a qualidade em um projeto que não é simples. Aos poucos vamos caminhando para o fim dele.

Sobre o curso do Bonieky: certamente ele será útil a ti, pois o back-end será em PHP. O que ainda estou em dúvida é se utilizarei ou não o MySQL. Pode ser que o Firebase Database seja utilizado. Mas vou definir isso mais para frente no projeto, já na parte Web.

Alan, o risco de eu não continuar com o projeto existe. Quando não há audiência não tem porque continuar. Mas enquanto houver um número legal de interação e acessos, vou prosseguir.

De vez em quando vou abordar assuntos extra projeto, para não ficar somente nisso, mas o foco será com aulas sequencias do app BlueShoes.

Abraço.
Responder
Alan Lucena (1) (0)
14/05/2019
Mais engraçado professor que o senhor esta dando uma puta oportunidade para que muitos possam usar o app para aprender e entrar no mercado de trabalho e são poucos de dão o real valor no excelente conteúdo que está dando para nós gratuitamente, fico chateado com isso pois era pra ser o maior canal de TI que o youtube teria, ai povo fica reclamando de crise perdendo tempo com isso ao invés de estudar o imensurável material que esta deixando para nós, da minha parte sempre terá o apoio necessário professor, dou aulas a quase 20 anos e sei bem o que é não ser reconhecido como deveríamos, mas nossa parte esta sendo feita, e nosso legado deixado, basta as pessoas desejarem ser alguém nessa vida e continuar o legado que tu está deixando, sucesso e que DEUS continue lhe abençoando grandiosamente!
Responder