Quem me vê no dia a dia, sabe que eu ando com um exemplar do meu livro o tempo todo. Além de utiliza-lo como forma de consulta, eu saio anotando nele:
- as novidades em APIs que saíram após o lançamento do livro;
- novos tópicos para colocar em versões futuras;
- e obviamente erros que os leitores vão reportando.
Por isso resolvi compartilhar com vocês minhas anotações, assim vocês já vão sabendo o que está errado, o que já mudou em termos de API, e o que pode mudar para a próxima ;) A medida que for achando mais problemas, vou atualizando esse post.
Ah! Antes que vocês perguntem, não tem nenhuma previsão para a próxima edição. Mas provavelmente o que vai acontecer é eu começar a trabalhar no livro após o Google I/O desse ano que vai acontecer entre 18 e 20 de maio.
Segue abaixo o que eu anotei até agora. Eu dividi em duas categorias: melhorias e erros.
Melhorias
Capítulo 0 / Pág. 29 - essa seção deve receber uma atualização com as novidades do emulador 2.0.http://tools.android.com/tech-docs/emulator
Capítulo 3 - vou adicionar mais uma seção nesse capítulo falando dos layouts percentuais PercentFrameLayout e PercentRelativeLayout que eu falei nesse post aqui.
Capítulo 4 / Pág. 132 - esqueci de falar de uma propriedade bacana do TextInpuLayout que mostra a quantidade de caracteres digitados.
http://developer.android.com/reference/android/support/design/widget/TextInputLayout.html#setCounterEnabled(boolean)
<android.support.design.widget.TextInputLayout ... app:counterEnabled="true"> <EditText ... android:maxLength="100"/>
Capítulo 4 / Pág. 163 - esqueci de mencionar que o método performFiltering() é executado em uma thread separada, enquanto que o método publishResults() é executado na UI thread.
Capítulo 6 / Pág. 254 - deveria ter criado um estilo para a Toolbar.
Capítulo 7 / Pág. 297 - era para ter enfatizado que, se uma classe implementar OnPreferenceChangeListener, caso uma SharedPreference seja modificada em qualquer ponto da aplicação, essa classe será notificada (obviamente se ela estiver instanciada).
Capítulo 7 / Pág. 310 - o trecho do método onClick() deveria estar em negrito.
Capítulo 7 / Pág. 325 - deveria estar realizando as operação com o ContentProvider utilizando a classe AsyncQueryHandler como falei nesse post aqui.
Capítulo 10 / Pág. 388 - substituir a enum Status por annotations como falei nesse post.
Capítulo 14 / Pág. 473 - no método onMessageReceived(), checar se from.equals(senderId) e se !data.isEmpty().
Capítulo 15 / Pág. 519 - o método getMap() tornou-se obsoleto (deprecated), em seu lugar, deve-se usar o método getMapAsync().
https://developers.google.com/android/reference/com/google/android/gms/maps/SupportMapFragment.html#getMapAsync(com.google.android.gms.maps.OnMapReadyCallback)
Capítulo 15 / Pág. 551 - podemos enviar localização fictícia com o emulador 2.0 do Android ou com o Genymotion.
Capítulo 20 - Falar sobre TransitionManager. Depois de ver essa palestra do Lúcio Maciel, me arrependi de não ter colocado esse assunto nesse capítulo.
https://www.youtube.com/watch?v=GKjPf0NI9ps
Capítulo 23 - Muitos fundamentos interessantes que são mostrados no treinamento de Gradle do Udacity seriam interessantes de colocar no livro. Principalmente linha de comando.
https://www.udacity.com/course/gradle-for-android-and-java--ud867
Capítulo 26 / Pág. 843 - Colocar alguns detalhes interessantes no uso da RecyclerView que eu coloquei nesse post.
Capítulo 26 / Pág. 891 - A biblioteca Otto foi recentemente marcada como deprecated em favor do RxJava e RxAndroid. Mas não se preocupem, o Otto continua funcionando. Uma outra opção seria usar o EventBus.
Capítulo 27 - Colocar um exemplo de DataBinding com listas.
http://developer.android.com/intl/pt-br/tools/data-binding/guide.html
Erros
Capítulo 1 / Pág. 39 e 49 - Quando falo das pasta res/mipmap eu menciono quatro pastas, quando na verdade são 5.Capítulo 2 / Página 81 - Ao girar a activity sem selecionar um estado, o texto do botão fica em branco. Para contornar isso, basta colocar o código a seguir no onCreate.
@Override protected void onCreate(Bundle savedInstanceState) { ... if (savedInstanceState != null) { estado = savedInstanceState.getString(STATE_ESTADO); if (estado != null) botaoEstado.setText(estado); } }
Capítulo 3 / Pág. 110 - a biblioteca de compatibilidade do GridLayout é melhor do que a versão nativa, pois ela teve vários bugs corrigidos.
http://developer.android.com/tools/support-library/features.html#v7-gridlayout
Basta adicionar a dependência no build.gradle.
compile 'com.android.support:gridlayout-v7:+'E no layout modificar para
<android.support.v7.widget.GridLayout ...
Capítulo 5 / Pág. 170 - a figura 5.6 está errada... ela deveria estar mostrando as marcações na ferramenta draw9patch. Ao invés disso está mostrando o GIMP :P
Capítulo 6 / Pág. 212 - No último parágrafo, a primeira frase deve ser "... o parâmetro savedInstanceState é igual a nulo, ..."
Capítulo 6 / Pág. 255 - o exemplo está com problema na Toolbar quando rodamos a aplicação no KitKat. A correção do bug já está no GitHub nesse commit aqui. E eu fiz até um vídeo explicando a solução :)
Capítulo 10 / Pág. 385 - na definição da tabela Hotel, o campo "estrelas" deve usar o tipo DECIMAL(2,1). Essa modificação já está no GitHub.
https://github.com/nglauber/dominando_android2/blob/master/server/hotel_service/webservice.php
Capítulo 14 / Pág. 511 - no último parágrafo, falei que após o realizar o login com a conta do Google, uma boa opção seria utilizar o ID da conta e enviar para o seu serviço web. Mas a solução recomendada pelo Google é o uso do Token.
http://android-developers.blogspot.com.br/2016/01/using-google-sign-in-with-your-server.html
Capítulo 24 / Pág. 764 - a figura 24.8 ficou "estranha".
Capítulo 25 / Pág. 839 - esse foi o pior erro do livro. Ficou faltando praticamente uma página.
Notei que um trecho grande do capítulo 26 (1ª impressão) acabou ficando de fora do livro. Creio que foi no momento da diagramação do livro na editora. Na página 839, no segundo parágrafo, após o texto "... que estamos executando." deveria vir o texto abaixo:
Biblioteca 1: ButterKnife
O ButterKnife (http://jakewharton.github.io/butterknife/) é um biblioteca desenvolvida por Jake Wharton (Google Developer Expert de Android) que facilita a atribuição de views à classes sem precisar utilizar o método findViewById(int).
Vejamos o exemplo a seguir:
public class MainActivity extends Activity { @Bind(R.id.txtTitulo) TextView mTxtTitulo; @Bind(R.id.edtNome) EditText mEdtNome; @Bind(R.id.listview) ListView mListPessoas; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bind(this); // Pronto! Pode usar os atributos! } }Perceba que anotamos os atributos da classe que representam componentes no arquivo de layout com a anotação @Bind(int) passando o id do componente. No método onCreate(Bundle) inicializamos esses atributos simplemente invocando ButterKnife.bind(this). O ButterKnife também funciona em Fragments e Adapters como veremos mais adiante. Essa biblioteca ainda possui outros recursos interessantes como definir evento de clique em botões.
@OnClick(R.id.botao1) public void onClickBotao1(View view) { } @OnClick(R.id.botao2) public void onClickBotao2() { }Perceba que no evento de clique do segundo botão, não colocamos o parâmetro, pois para a biblioteca ele é opcional. Vamos utilizar o ButterKnife em nosso aplicativo. Para isso, adicione a dependência no build.gradle.
dependencies { … compile 'com.jakewharton:butterknife:7.0.1' }
Biblioteca 2: OkHttp
No capítulo 8 vimos como acessar um servidor web utilizando a classe HttpUrlConnection. Ela funciona muito bem, o único incoveniente é quando precisamos ler o retorno do servidor,
x.x.x.x.x.x.x.x.x.x.x
Peço desculpas pelo inconveniente, mas pelos menos agora vocês vão entender porque o texto está maluco :)
------------------
Quero deixar meu muito obrigado a todos os leitores que reportam os erros encontrados no livro. E se você adquiriu ou livro, não se esqueça de se cadastrar no grupo de discussão da segunda edição do "Dominando o Android".
4br4ç05,
nglauber