Fragmento da Tela Sobre e Links Sociais - Android M-Commerce

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

Email inválido.
Blog /Android /Fragmento da Tela Sobre e Links Sociais - Android M-Commerce

Fragmento da Tela Sobre e Links Sociais - Android M-Commerce

Vinícius Thiengo
(3379) (4)
Go-ahead
"O método consciente de tentativa e erro é mais bem-sucedido que o planejamento de um gênio isolado."
Peter Skillman
Prototipagem Android
Capa do curso Prototipagem Profissional de Aplicativos
TítuloAndroid: Prototipagem Profissional de Aplicativos
CategoriasAndroid, Design, Protótipo
AutorVinícius Thiengo
Vídeo aulas186
Tempo15 horas
ExercíciosSim
CertificadoSim
Acessar Curso
Quer aprender a programar para Android? Acesse abaixo o curso gratuito no Blog.
Lendo
TítuloTest-Driven Development: Teste e Design no Mundo Real
CategoriaEngenharia de Software
Autor(es)Mauricio Aniche
EditoraCasa do Código
Edição1
Ano2012
Páginas194
Conteúdo Exclusivo
Investir em Você é Barra de Ouro a R$ 2,00. Cadastre-se e receba gratuitamente conteúdos Android sem precedentes!
Email inválido

Tudo bem?

Neste artigo vamos continuar com a construção do aplicativo Android de mobile-commerce, o BlueShoes. Neste ponto do projeto construiremos uma tela importante em qualquer projeto de software, e também uma das telas mais simples: a tela Sobre.

Aqui iniciaremos os trabalhos com fragmentos e links via Intent:

Animação da tela Sobre no Android app BlueShoes

Antes de prosseguir, não deixe de se inscrever 📩 na lista de emails do Blog para ter acesso aos conteúdos exclusivos sobre desenvolvimento Android e também aos conteúdos deste projeto de m-commerce.

A seguir os tópicos abordados:

Para você que chegou agora

Se você está tendo acesso a este projeto de desenvolvimento somente agora, saiba que outras duas aulas importantes sobre ele já foram liberadas, aulas anteriores a está. É importante que primeiro você as consuma.

Seguem os links:

A importância da tela Sobre

Uma das maneiras de passar confiança ao usuário de seu software, mesmo que seja apenas um Blog, é falar sobre você (ou a sobre empresa) ou então ao menos informar os valores e missão do projeto.

Com isso, mesmo que não seja uma verdade absoluta, o usuário saberá que a empresa estará disposta a cumprir, sem receios, o que foi informado na página Sobre do software.

No caso de empresa, como uma de comércio online, são esperados ao menos:

  • Missão;
  • Visão;
  • Valores;
  • Integridade.

É ainda mais positivo se estes vierem acompanhados da história de como surgiu a empresa, os sócios, os problemas enfrentados e como estes foram superados ao longo da jornada.

As pessoas gostam de história, logo, se em seu projeto proprietário houver uma história de superação verdadeira que pode ser contada, não hesite: conte.

No projeto BlueShoes teremos conteúdos sobre os quatro itens apresentados anteriormente, estes acompanhados dos principais links sociais da empresa de mobile-commerce.

Protótipo estático

A seguir a única tela que estaremos desenvolvendo, incluindo a adição de ação aos links sociais:

Tela Sobre

Tela Sobre

 

Com isso podemos partir para a codificação.

Atualizando o projeto Android, Fragmento

Vamos primeiro atualizar os arquivos mais simples, os de conteúdos estáticos, que não exigem lógica de negócio e têm seus conteúdos disponíveis em protótipo estático.

Logo depois vamos às atualizações de fragmento e de atividade.

Antes de prosseguir, saiba que você também poderá estar acessando o projeto BlueShoes pelo GitHub dele em: https://github.com/viniciusthiengo/blueshoes-kotlin-android.

De qualquer forma, não deixe de acompanhar o artigo, onde há explicações sobre as partes adicionadas e trechos atualizados.

Arquivo de cores

Em /res/values/colors.xml adicione as cores abaixo em destaque:

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

<color name="colorLightGreenBox">#BB77D353</color>

<color name="colorOrangeInfo">#FF9052</color>
</resources>

 

Rótulos genéricos foram utilizados nas duas cores adicionadas, pois estas serão referenciadas em vários outros pontos do projeto. Busque sempre essa estratégia:

O que não é especifico de um único contexto dentro do projeto, deve ter um rótulo genérico, mas que ainda tenha significado para quem venha a ler o código. O rótulo colorOrangeInfo indica que é a "cor laranja" para "contexto de informação", algo mais genérico do que colorOrangeInfoAboutScreen, onde estaria indicando "cor laranja" apenas para o "contexto de informação" dentro da "tela Sobre".

Note que o hexadecimal colorLightGreenBox tem oito caracteres (BB77D353), isso, pois nesta cor verde está sendo trabalhada a transparência, como informado em protótipo estático:

Bloco de texto com transparência em background

Os dois primeiros caracteres, BB, indicam o nível de transparência. A transparência pode ir de 00 (totalmente transparente) a FF (totalmente opaco, sem transparência).

Arquivo de Strings

Em /res/values/strings.xml adicione as Strings em destaque:

<resources>
...

<!-- AboutFragment -->
<string name="about_frag_title">Sobre a BlueShoes</string>

<string name="about_frag_mission_title">Missão</string>
<string name="about_frag_mission_desc">
Inspirar e transformar a vida das pessoas com calçados que
permitem qualquer atividade no dia a dia.
</string>

<string name="about_frag_vision_title">Visão</string>
<string name="about_frag_vision_desc">
A melhor e mais inovadora experiência de compra do varejo
de calçados.
</string>

<string name="about_frag_values_title">Valores</string>
<string name="about_frag_values_desc">
Ética, responsabilidade, espírito de equipe, inspiração e
foco.
</string>

<string name="about_frag_ethic_title">Ética e integridade</string>
<string name="about_frag_ethic_desc">
A ética e a integridade fazem parte da nossa cultura e são
essenciais para o nosso negócio.
</string>

<string name="about_frag_social_networks_title">
Nos acompanhe nas redes sociais e não perca as promoções
</string>

<string name="ic_instagram_desc">Ícone do Instagram BlueShoes</string>
<string name="label_instagram">/BlueShoes</string>

<string name="ic_facebook_desc">Ícone do Facebook BlueShoes</string>
<string name="label_facebook">/BlueShoesFace</string>

<string name="ic_twitter_desc">Ícone do Twitter BlueShoes</string>
<string name="label_twitter">/BlueShoesTwitter</string>

<string name="ic_youtube_desc">Ícone do YouTube BlueShoes</string>
<string name="label_youtube">/BlueShoesYT</string>

<string name="ic_linkedin_desc">Ícone do LinkedIn BlueShoes</string>
<string name="label_linkedin">/BlueShoesLkIn</string>
<string name="info_linkedin">Para oportunidades de emprego!</string>

<string name="ic_cnpj_desc">Ícone do CNPJ BlueShoes</string>
<string name="label_cnpj">CNPJ 25.002.230/0001&#8211;10</string>
</resources>

 

Em label_cnpj note o uso da codificação &#8211; substituindo o uso direto de hífen, -.

Por que isso?

Essa é uma recomendação do próprio Android Studio IDE, pois segundo ele quando o hífen é necessário, porém não em contexto de demonstração de "alcance", por exemplo: de 1 a 10 pode ser simplificado como 1-10. Nesse caso, fora do contexto de alcance, pede-se ao desenvolvedor que o código &#8211; seja utilizado para não atrapalhar na leitura da String por parte de outros programadores, deixando assim o projeto mais polido.

Note que há inúmeros códigos para caracteres especiais no HTML e no XML, o código &#8211; representa o hífen.

Vale ressaltar que o arquivo de Strings, além de ajudar na correta divisão do código do projeto, é essencial à internacionalização do aplicativo.

Iniciando o fragmento AboutFragment

No pacote /view do projeto, siga o roteiro abaixo para criar o primeiro fragmento:

  • Clique com o botão direito do mouse;
  • Acesse New;
  • Então acesse Fragment;
  • Clique em Fragment (Blank);
  • Na caixa de diálogo aberta:
    • Em Fragment Name coloque AboutFragment;
    • Em Fragment Layout Name continue com fragment_about;
    • Desmarque a opção Include fragment factory method?;
    • Desmarque a opção Include callbacks?;
    • Em Source Language permaneça com Kotlin;
    • Por fim clique em Finish.

Criando fragment no Android Studio IDE

Ao final da criação do fragmento, deixe o código inicial dele como a seguir:

class AboutFragment :
Fragment() {

override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {

return inflater
.inflate(
R.layout.fragment_about,
container,
false
)
}
}

Configurações de design dos títulos e blocos de textos

Nosso primeiro passo na adição dos títulos e blocos de textos é a configuração da família de fonte que será utilizada nos títulos, não somente nos títulos da tela Sobre, mas em várias outras telas do projeto.

No protótipo estático a fonte em uso é a League Gothic, porém como Open Source foi encontrada somente uma fonte similar, a Pathway Gothic One Regular, localizada no Google Fonts.

Google Fonts

Você também pode baixa-la no GitHub do projeto em:

Baixe a fonte indicada acima e então coloque-a no folder /res/font, onde já temos a fonte roboto_light.ttf.

Os títulos e os blocos de textos terão configurações de design iguais. Caso seja tudo colocado no layout XML e se posteriormente quisermos atualizar a cor dos títulos, por exemplo, teremos de fazer isso passo a passo em cada um dos TextViews de títulos em tela.

Tendo conhecimento deste problema, vamos criar estilos que serão pontos únicos de atualização e poderão ser referenciados não somente no layout da tela Sobre, mas em todas as outras telas que exigirem as mesmas configurações de título e bloco de texto.

Em /res/values/styles.xml adicione as marcações abaixo em destaque:

<resources>
...

<style name="TextViewContentTitle">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_marginBottom">8dp</item>
<item name="android:textColor">@color/colorText</item>
<item name="android:textSize">20sp</item>
<item name="android:textStyle">bold</item>
<item name="android:textAllCaps">true</item>
<item name="android:fontFamily">@font/pathway_gothic_one_regular</item>
</style>

<style name="AboutFragTextViewContent">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_marginBottom">38dp</item>
<item name="android:padding">12dp</item>
<item name="android:textColor">@android:color/white</item>
<item name="android:background">@color/colorLightGreenBox</item>
</style>
</resources>

 

Note que no estilo AboutFragTextViewContent não foi utilizado como rótulo um termo genérico, pois a principio teremos as caixas verdes de informações somente nesta tela do projeto.

Outro ponto a se notar é que como prefixo de rótulo de estilo não foi utilizado o nome do estilo principal do projeto, AppTheme. Isso, pois como os rótulos de estilos já estão grandes, foi preferível economizar nesta parte para não atrapalhar na leitura de código por parte de outros desenvolvedores.

Adicionando títulos e blocos de textos

Para a primeira parte de atualização da estrutura do layout de AboutFragment vamos colocar as Views de títulos e blocos de textos além de dois ViewGroups containers.

Em /res/layout/fragment_about.xml adicione as marcações a seguir:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
tools:context=".view.AboutFragment">

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">

<TextView
android:id="@+id/tv_mission_title"
style="@style/TextViewContentTitle"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:text="@string/about_frag_mission_title"/>

<TextView
android:id="@+id/tv_mission_desc"
style="@style/AboutFragTextViewContent"
android:layout_below="@+id/tv_mission_title"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:text="@string/about_frag_mission_desc"/>

<TextView
android:id="@+id/tv_vision_title"
style="@style/TextViewContentTitle"
android:layout_below="@+id/tv_mission_desc"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:text="@string/about_frag_vision_title"/>

<TextView
android:id="@+id/tv_vision_desc"
style="@style/AboutFragTextViewContent"
android:layout_below="@+id/tv_vision_title"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:text="@string/about_frag_vision_desc"/>

<TextView
android:id="@+id/tv_values_title"
style="@style/TextViewContentTitle"
android:layout_below="@+id/tv_vision_desc"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:text="@string/about_frag_values_title"/>

<TextView
android:id="@+id/tv_values_desc"
style="@style/AboutFragTextViewContent"
android:layout_below="@+id/tv_values_title"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:text="@string/about_frag_values_desc"/>

<TextView
android:id="@+id/tv_ethic_title"
style="@style/TextViewContentTitle"
android:layout_below="@+id/tv_values_desc"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:text="@string/about_frag_ethic_title"/>

<TextView
android:id="@+id/tv_ethic_desc"
style="@style/AboutFragTextViewContent"
android:layout_below="@+id/tv_ethic_title"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:text="@string/about_frag_ethic_desc"/>

<TextView
android:id="@+id/tv_social_networks_title"
style="@style/TextViewContentTitle"
android:layout_marginBottom="14dp"
android:layout_below="@+id/tv_ethic_desc"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:text="@string/about_frag_social_networks_title"/>
</RelativeLayout>
</android.support.v4.widget.NestedScrollView>

 

Note que NestedScrollView está sendo utilizado, pois é bem provável que em ao menos um aparelho Android o conteúdo total da tela Sobre não caiba na tela, sendo assim será necessário o scroll. E... este layout estará contido dentro de /res/layout/app_bar_main.xml, onde está também a barra de topo, Toolbar.

O atributo android:scrollbars="vertical" foi adicionado ao NestedScrollView para que a barra de rolagem vertical seja apresentada quando houver a rolagem de tela.

Com a configuração atual de layout, temos o seguinte diagrama:

Diagrama da primeira versão do layout fragment_about.xml

Note o uso do atributo style nos TextViews. Caso não tivéssemos adotado essa estratégia, cada conjunto de TextView de título e TextView de descrição teria, além das definições de posicionamento e ID, a seguinte configuração:

...
<TextView
...
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:textColor="@color/colorText"
android:textSize="20sp"
android:textStyle="bold"
android:textAllCaps="true"
android:fontFamily="@font/pathway_gothic_one_regular" />

<TextView
...
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="38dp"
android:padding="12dp"
android:textColor="@android:color/white"
android:background="@color/colorLightGreenBox" />
...

Configurações de design dos links sociais

Como foi feito para os títulos e blocos de textos da tela Sobre, para os links sociais, e os ícones que os acompanham, também teremos estilos em /res/values/styles.xml. Adicione os trechos em destaque:

<resources>
...

<style name="ImageViewLink">
<item name="android:layout_width">17dp</item>
<item name="android:layout_height">17dp</item>
<item name="android:layout_marginBottom">8dp</item>
<item name="android:layout_marginRight">4dp</item>
<item name="android:layout_marginEnd">4dp</item>
<item name="android:scaleType">centerInside</item>
<item name="android:tint">@color/colorLink</item>
</style>

<style name="TextViewLink">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:textColor">@color/colorLink</item>
<item name="android:layout_marginTop">-2dp</item>
</style>
</resources>

 

Lembrando que com os estilos definidos também economizaremos em muito na codificação XML do layout.

Ícones dos links sociais

Como informado na sessão anterior, os links sociais serão acompanhados por ícones que têm mais a função de indicar a rede social da empresa que será aberta.

Os ícones foram baixados do Material Design Icons, no mesmo roteiro apresentado no segundo artigo da construção do aplicativo BlueShoes. Roteiro como a seguir:

  • Entre em Material Design Icons;
  • Informe, na caixa de busca, um termo em inglês para buscar pelos ícones desejados. Aqui os termos foram:
    • Instagram;
    • Facebook;
    • Twitter;
    • YouTube;
    • LinkedIn.
  • Quando você escolher um ícone, clique nele e logo depois clique em Icon Package;
  • Então selecione Android 5.x.

Com os ícones descarregados, fique somente com aqueles de 18dp dos folders drawable: mdpi; hdpi; xhdpi; e xxhdpi.

Para adiantar o projeto, você pode baixar os ícones direto do repositório do aplicativo, nos links a seguir:

Coloque os ícones em seus respectivos folders drawable.

Caso você esteja pensando sobre a possibilidade de uso de vetores ao invés de várias versões de ícones em folders drawable. Saiba que certamente estaremos passando por este ponto nas primeiras refatorações do projeto.

Para qualquer projeto de software, pense em primeiro fazê-lo funcionar, posteriormente, já com usuários fazendo uso do aplicativo ou com as funcionalidades iniciais já bem avançadas, venha melhorando também o código.

Adicionando os links sociais

No layout /res/layout/fragment_about.xml adicione as marcações em destaque:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView
...>

<RelativeLayout
...>

...

<ImageView
android:id="@+id/iv_instagram"
style="@style/ImageViewLink"
android:layout_below="@+id/tv_social_networks_title"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:contentDescription="@string/ic_instagram_desc"
android:src="@drawable/ic_instagram_black_18dp"/>
<TextView
android:id="@+id/tv_instagram"
style="@style/TextViewLink"
android:layout_alignTop="@+id/iv_instagram"
android:layout_toEndOf="@+id/iv_instagram"
android:layout_toRightOf="@+id/iv_instagram"
android:text="@string/label_instagram"/>

<ImageView
android:id="@+id/iv_facebook"
style="@style/ImageViewLink"
android:layout_below="@+id/iv_instagram"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:contentDescription="@string/ic_facebook_desc"
android:src="@drawable/ic_facebook_box_black_18dp"/>
<TextView
android:id="@+id/tv_facebook"
style="@style/TextViewLink"
android:layout_alignTop="@+id/iv_facebook"
android:layout_toEndOf="@+id/iv_facebook"
android:layout_toRightOf="@+id/iv_facebook"
android:text="@string/label_facebook"/>

<ImageView
android:id="@+id/iv_twitter"
style="@style/ImageViewLink"
android:layout_below="@+id/iv_facebook"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:contentDescription="@string/ic_twitter_desc"
android:src="@drawable/ic_twitter_black_18dp"/>
<TextView
android:id="@+id/tv_twitter"
style="@style/TextViewLink"
android:layout_alignTop="@+id/iv_twitter"
android:layout_toEndOf="@+id/iv_twitter"
android:layout_toRightOf="@+id/iv_twitter"
android:text="@string/label_twitter"/>

<ImageView
android:id="@+id/iv_youtube"
style="@style/ImageViewLink"
android:layout_below="@+id/iv_twitter"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:contentDescription="@string/ic_youtube_desc"
android:src="@drawable/ic_youtube_black_18dp"/>
<TextView
android:id="@+id/tv_youtube"
style="@style/TextViewLink"
android:layout_alignTop="@+id/iv_youtube"
android:layout_toEndOf="@+id/iv_youtube"
android:layout_toRightOf="@+id/iv_youtube"
android:text="@string/label_youtube"/>

<ImageView
android:id="@+id/iv_linkedin"
style="@style/ImageViewLink"
android:layout_below="@+id/iv_youtube"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:contentDescription="@string/ic_linkedin_desc"
android:src="@drawable/ic_linkedin_box_black_18dp"/>
<TextView
android:id="@+id/tv_linkedin"
style="@style/TextViewLink"
android:layout_alignTop="@+id/iv_linkedin"
android:layout_toEndOf="@+id/iv_linkedin"
android:layout_toRightOf="@+id/iv_linkedin"
android:text="@string/label_linkedin"/>
</RelativeLayout>
</android.support.v4.widget.NestedScrollView>

 

Lembrando que, como discutido no primeiro artigo deste projeto de mobile-commerce, os rótulos e ícones em azul serão links em nosso domínio de problema. Ou seja, ainda colocaremos os códigos dinâmicos vinculados aos rótulos e ícones de link.

Com o adicionado em layout até aqui, temos o seguinte novo diagrama de fragment_about.xml:

Diagrama da segunda versão do layout fragment_about.xml

Informe do LinkedIn

Se notar no protótipo estático, tem um informe ao lado do link do LinkedIn:

Informe do LinkedIn

Para adicionar essa View primeiro temos de criar o drawable de background que coloca bordas a ela.

Em /res/drawable crie um novo arquivo de recurso com o rótulo bg_orange_info.xml e coloque o código XML como a seguir:

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

<!--
Se o background transparente não for definido, o fundo
do shape, em versões antigas do Android, ficará preto.
-->
<solid android:color="@android:color/transparent" />

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

<!--
Definindo bordas arredondadas na View retangular.
-->
<corners android:radius="5dp" />
</shape>

 

Esse tipo de design de informe será utilizado em vários pontos do projeto, logo, vamos colocar as configurações de design dele em /res/values/styles.xml. Adicione a este arquivo o código em destaque:

<resources>
...

<style name="TextViewOrangeInfo">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:paddingTop">3dp</item>
<item name="android:paddingBottom">3dp</item>
<item name="android:paddingLeft">7dp</item>
<item name="android:paddingRight">7dp</item>
<item name="android:layout_marginLeft">10dp</item>
<item name="android:layout_marginStart">10dp</item>
<item name="android:background">@drawable/bg_orange_info</item>
<item name="android:textColor">@color/colorOrangeInfo</item>
<item name="android:textSize">12sp</item>
<item name="android:maxLines">1</item>
<item name="android:ellipsize">end</item>
</style>
</resources>

 

Agora em /res/layout/fragment_about.xml adicione o trecho em destaque:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView
...>

<RelativeLayout
...>

...

<TextView
android:id="@+id/tv_linkedin_info"
style="@style/TextViewOrangeInfo"
android:layout_alignTop="@+id/tv_linkedin"
android:layout_toEndOf="@+id/tv_linkedin"
android:layout_toRightOf="@+id/tv_linkedin"
android:text="@string/info_linkedin"/>
</RelativeLayout>
</android.support.v4.widget.NestedScrollView>

 

Com isso temos o seguinte novo diagrama para o layout de AboutFragment:

Diagrama da terceira versão do layout fragment_about.xml

E o CNPJ?

Antes de partirmos para a codificação dinâmica da AboutFragment, ainda temos um trecho estático a adicionar no layout fragment_about.xml.

Neste layout XML, ao final dele, adicione os trechos em destaque:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView
...>

<RelativeLayout
...>

...

<LinearLayout
android:layout_marginTop="24dp"
android:layout_below="@+id/iv_linkedin"
android:layout_centerHorizontal="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">

<ImageView
android:id="@+id/iv_cnpj"
style="@style/ImageViewLink"
android:layout_marginBottom="0dp"
android:tint="@color/colorText"
android:contentDescription="@string/ic_cnpj_desc"
android:src="@drawable/ic_domain_black_18dp"/>
<TextView
android:id="@+id/tv_cnpj"
style="@style/TextViewLink"
android:textColor="@color/colorText"
android:text="@string/label_cnpj"/>
</LinearLayout>
</RelativeLayout>
</android.support.v4.widget.NestedScrollView>

 

Note que estamos aproveitando os estilos ImageViewLinkTextViewLink e então colocando algumas configurações necessárias direto nos TextViews para conseguir o informado em protótipo estático. Ou seja, as definições de design feitas diretamente na View têm maior prioridade ante as definições feitas em configuração de estilo no arquivo /res/values/styles.xml.

Com isso temos o diagrama final de fragment_about.xml:

Diagrama final do layout fragment_about.xml

Adicionando ação aos links sociais

Em AboutFragment adicione os códigos em destaque:

class AboutFragment :
Fragment(),
View.OnClickListener {
...

/*
* Para que não tenhamos problemas de Views ainda não
* carregadas em tela para possível acesso em código
* dinâmico, as Views do layout de AboutFragment estão
* sendo acessadas somente em método posterior ao
* método onCreateView(), no caso o método onActivityCreated(),
* digo, Views sendo acessadas via sintaxe
* kotlin-android-extensions.
* */
override fun onActivityCreated( savedInstanceState: Bundle? ) {
super.onActivityCreated( savedInstanceState )

iv_instagram.setOnClickListener( this )
tv_instagram.setOnClickListener( this )

iv_facebook.setOnClickListener( this )
tv_facebook.setOnClickListener( this )

iv_twitter.setOnClickListener( this )
tv_twitter.setOnClickListener( this )

iv_youtube.setOnClickListener( this )
tv_youtube.setOnClickListener( this )

iv_linkedin.setOnClickListener( this )
tv_linkedin.setOnClickListener( this )
}

override fun onClick( v: View ) {
when( v.id ){
R.id.tv_instagram,
R.id.iv_instagram -> {
openNetwork(
"com.instagram.android",
"http://instagram.com/_u/cbf_futebol",
"http://instagram.com/cbf_futebol"
)
}
R.id.tv_facebook,
R.id.iv_facebook -> {
openNetwork(
"com.facebook.katana",
"fb://facewebmodal/f?href=https://www.facebook.com/thiengoCalopsita",
"https://www.facebook.com/thiengoCalopsita"
)
}
R.id.tv_twitter,
R.id.iv_twitter-> {
openNetwork(
"com.twitter.android",
"https://twitter.com/thiengoCalops",
"https://twitter.com/thiengoCalops"
)
}
R.id.tv_youtube,
R.id.iv_youtube-> {
openNetwork(
"com.google.android.youtube",
"https://www.youtube.com/user/thiengoCalopsita",
"https://www.youtube.com/user/thiengoCalopsita"
)
}
else -> {
openNetwork(
"com.linkedin.android",
"https://www.linkedin.com/in/vin%C3%ADcius-thiengo-5179b180/",
"https://www.linkedin.com/in/vin%C3%ADcius-thiengo-5179b180/"
)
}
}
}

private fun openNetwork(
appPackage: String,
appAddress: String,
webAddress: String ){

val uri = Uri.parse( appAddress )
val intent = Intent( Intent.ACTION_VIEW, uri )

intent.setPackage( appPackage )

try{
activity!!.startActivity( intent )
}
catch( e: ActivityNotFoundException ){
/*
* Se não houver o aplicativo da rede
* social acionada, então abra a página
* no navegador padrão do aparelho, Web.
* */
activity!!.startActivity(
Intent(
Intent.ACTION_VIEW,
Uri.parse( webAddress )
)
)
}
}
}

 

Note que as Strings presentes em onClick() não foram enviadas ao arquivo strings.xml, pois para elas não cabe a possível internacionalização, se manterão sempre com o mesmo conteúdo. E também porque este é, a princípio, o único ponto do projeto que terá referencia a elas.

Thiengo, por que não foi utilizado o atributo android:onClick nas Views do layout de AboutFragment?

Isso é possível, mas como o layout está em um fragmento nós teríamos de também criar um código de interceptação de clique na MainActivity, ou seja, muito mais codificação do que a atual presente em AboutFragment.

Note que o operador "force NullPointerException", !!, está sendo utilizado junto a propriedade activity, pois em código nativo ela pode ser null, mesmo sabendo que depois de inúmeros testes ela nunca é null para fragmentos vinculados a alguma atividade.

Atualização da atividade principal

Neste ponto vamos:

  • Modificar o layout de conteúdo para poder receber fragmentos;
  • Adicionar o algoritmo de abertura de fragmento de acordo com o item escolhido em menu gaveta;
  • Adicionar o algoritmo de mudança de título na barra de topo da atividade principal.

Atualizando o layout de conteúdo

Em /res/layout/app_bar_main.xml adicione o seguinte FrameLayout no lugar de <include layout="@layout/content_main"/>:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
...>
...

<FrameLayout
android:id="@+id/fl_fragment_container"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:layout_width="match_parent"
android:layout_height="match_parent" />

</android.support.design.widget.CoordinatorLayout>

 

Logo depois remova do projeto o arquivo /res/layout/content_main.xml.

Note a importância de mantermos o atributo app:layout_behavior="@string/appbar_scrolling_view_behavior" para que a sincronia de movimento entre AppBarLayout (barra de topo) e conteúdo se mantenha consistente.

Algoritmo de abertura de fragmento

Os métodos responsáveis pela obtenção e gerência do fragmento foram divididos para que não houvesse repetição de código e também para que não houvesse o fornecimento de várias responsabilidades para um único método.

Na atividade principal adicione os seguintes métodos e constante:

...
companion object {
const val FRAGMENT_TAG = "frag-tag"
}
...

private fun initFragment(){
val supFrag = supportFragmentManager
var fragment = supFrag.findFragmentByTag( FRAGMENT_TAG )

/*
* Se não for uma reconstrução de atividade, então não
* haverá um fragmento em memória, então busca-se o
* inicial.
* */
if( fragment == null ){
fragment = getFragment( R.id.item_about.toLong() )
}

replaceFragment( fragment )
}

private fun getFragment( fragmentId: Long ) =
when( fragmentId ){
R.id.item_about.toLong() -> AboutFragment()
else -> AboutFragment()
}

private fun replaceFragment( fragment: Fragment ){
supportFragmentManager
.beginTransaction()
.replace(
R.id.fl_fragment_container,
fragment,
FRAGMENT_TAG
)
.commit()
}
...

 

Note os rótulos sendo utilizados nos métodos, rótulos autocomentados que dispensam a necessidade de comentários.

Até aqui temos somente um fragmento, por isso pode parecer sem sentido o método getFragment(), mas em novos artigos do projeto ele começará a crescer devido aos vários outros fragmentos que teremos de adicionar, fragmentos de mesmo nível.

"... mesmo nível"?

Sim. São fragmentos que têm o mesmo grau de importância e acesso dentro do aplicativo, por exemplo: o algoritmo de acesso a AboutFragment, o algoritmo do método getFragment(), terá também como opção os fragmentos de Contato e de Política de privacidade, ou seja, o bloco condicional, when(), terá de ser utilizado para identificar qual fragmento criar / acessar, é ai que entra a importância do identificador único para cada fragmento de nosso projeto, nosso domínio de problema, não somente para os itens de menu gaveta.

Ainda temos de colocar initFragment() no onCreate() da atividade principal para que já na entrada do app tenha um conteúdo principal em tela, que neste artigo será o da tela Sobre.

Na atividade principal, no método onCreate(), adicione o código em destaque:

...
override fun onCreate( ... ) {
...

initFragment()
}
...

 

Por fim, ainda temos de colocar o código de obtenção de fragmento no método onItemStateChanged() da classe SelectObserverNavMenuItems, classe interna a MainActivity. Neste método, adicione o código abaixo em destaque:

...
override fun onItemStateChanged(
key: Long,
selected: Boolean ) {
...

val fragment = getFragment( key )
replaceFragment( fragment )


/*
* Fechando o menu gaveta.
* */
drawer_layout.closeDrawer( GravityCompat.START )
}
...

 

Note a vantagem de trabalhar com IDs em XML. Se tivermos de mudar os valores, mesmo sendo os rótulos, mudaremos somente em um local: em /res/values/nav_menu_items_ids.xml.

Algoritmo de mudança de título em barra de topo

Para a mudança de título em barra de topo, primeiro adicione o seguinte método a MainActivity:

...
fun updateToolbarTitleInFragment( titleStringId: Int ){
toolbar.title = getString( titleStringId )
}
...

 

Então, em AboutFragment, adicione o seguinte código em destaque:

class AboutFragment :
... {
...

/*
* Método do ciclo de vida do fragmento somente
* utilizado aqui, como hackcode, para permitir
* a atualização do título da toolbar sem que
* seja lançado um erro em tempo de execução.
* */
override fun onResume() {
super.onResume()

(activity as MainActivity)
.updateToolbarTitleInFragment( R.string.about_frag_title )
}
}

 

Assim podemos partir para os testes com este primeiro fragmento.

Testes e resultados

Abra o Android Studio, vá em "Build", então clique em "Rebuid project". Ao final do rebuild execute o aplicativo em seu aparelho ou emulador Android de testes.

Assumindo em teste o usuário com o status "conectado" (objeto presente na MainActivity):

...
val user = User(
"Thiengo Vinícius",
R.drawable.user,
true
)
...

 

Temos:

Animação mostrando a tela Sobre do app Android BlueShoes

Tentando acessar o Facebook, que não tem app instalado em device de teste, por meio do link na tela, temos:

Animação de abertura do Facebook pelo app Android BlueShoes

Agora tentando acessar o YouTube, que tem o app no aparelho de teste, temos:

Animação de abertura do YouTube pelo app Android BlueShoes

Com isso finalizamos essa segunda parte do projeto Android de mobile-commerce, BlueShoes. Não deixe de se inscrever na 📩 lista de emails do Blog para continuar acompanhando o desenvolvimento.

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

Vídeos

A seguir os vídeos com a construção da AboutFragment nesta terceira parte do projeto BluesShoes Android mobile-commerce:

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

Conclusão

O projeto Android BlueShoes vem ganhando forma a cada novo conteúdo. Neste artigo iniciamos outro ponto importante em projeto: o trabalho com fragmentos. A adição de outros fragmentos será ainda mais simples devido a parte de código já pré-construído.

Importante notar o trabalho com os algoritmos de links, onde é primeiro tentada a abertura utilizando o aplicativo nativo da rede social acionada, pois a usabilidade tende a ser melhor, mas caso o app não esteja instalado no aparelho a página da empresa na rede selecionada é aberta no navegador padrão do device.

Caso você tenha dúvidas ou dicas para este projeto, deixe logo abaixo nos comentários.

Curtiu o conteúdo? Não esqueça de compartilha-lo. E, por fim, não deixe de se inscrever na 📩 lista de emails.

Abraço.

Fontes 

Control Flow: if, when, for, while

Guide to the when{} Block in Kotlin

Intent to open Instagram user profile on Android - Resposta de jhondge e de Loolooii

Open Facebook page from Android app? - Resposta de Jared Rummler

Open page in Twitter app from other app - Android - Resposta de fg.radigales e de j0k

intent to youtube app profile/channel - Resposta de laaptu

Unable to open Linkedin profile using intent in android - Resposta de Syed Faisal

Where should 'app:layout_behavior' be set? - Resposta de Mohsen e de AnV

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

Relacionado

Como Impulsionar o App Android - Compartilhamento NativoComo Impulsionar o App Android - Compartilhamento NativoAndroid
Android About Page API Para Construir a Tela SobreAndroid About Page API Para Construir a Tela SobreAndroid
Android Mobile-Commerce, Apresentação e Protótipo do ProjetoAndroid Mobile-Commerce, Apresentação e Protótipo do ProjetoAndroid
Início de Projeto e Menu Gaveta Customizado - Android M-CommerceInício de Projeto e Menu Gaveta Customizado - Android M-CommerceAndroid

Compartilhar

Comentários Facebook

Comentários Blog (4)

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...
Ronald Otávio (1) (0)
19/02/2019
Bom dia Vinícius, tem como passar o link da aula 2. Não recebi. Obrigado.
Responder
Vinícius Thiengo (0) (0)
20/02/2019
Ronald, tudo bem?

Segue o link da segunda aula:

-> Início de Projeto e Menu Gaveta Customizado - Android M-Commerce: https://www.thiengo.com.br/inicio-de-projeto-e-menu-gaveta-customizado-android-m-commerce

Abraço.
Responder
18/02/2019
Bom dia, percebi hoje que seus e-mails estão indo para o lixo eletrônico e parei para colocar o seu blog em dia =D

Meus parabéns pelo conteúdo, nota 10... Usei seus artigos para concluir um projeto da faculdade a alguns anos e hoje recomendo seu site para todos os meus alunos, espero que continue com o projeto. Meus parabéns de verdade por distribuir o conteúdo dessa forma.
Responder
Vinícius Thiengo (0) (0)
18/02/2019
David, muito obrigado.

Vou sim continuar com o projeto.

Abraço.
Responder