Quem me conhece saber que não sou muito fã de frameworks e bibliotecas, gosto de procurar ao máximo uma solução nativa da plataforma ao qual estou trabalhando. E uma coisa que me deixava muito chateado no Android era a não retrocompatibilidade da ActionBar com versões anteriores à 3.0 (quando ela foi lançada).
Felizmente esse problema acabou com a biblioteca SherlockActionBar, que traz o recurso da ActionBar para aparelhos com Android 2.3 ou inferior, e mantém os nomes de métodos iguais à plataforma nativa. E o que é melhor, quando a aplicação está rodando em versões 3.0 ou superior, o Sherlock só faz chamar a API padrão, ou seja, utiliza a ActionBar nativa.
Vou fazer um exemplo que utiliza dois recursos da ActionBar: Menus e Abas. Faça o download em http://actionbarsherlock.com e descompacte em algum local do seu computador. No Eclipse, importe o projeto library para dentro do seu workspace, para tal acesse File/New.../Project, e na janela que for exibida selecione Android/Android Project From existing code selecione o diretório onde você descompactou o Sherlock. Aparecerá além do projeto library, os demos do Sherlock, por agora só importe o projeto library.
Crie um novo projeto selecionando o Build SDK 4.1 (o Sherlock utiliza Temas e Estilos dessa versão do Android) e o Minimum Required para 2.2. Depois de criado, vá até a pasta lib do projeto e apague o arquivo android-support-v4.jar (o Sherlock já inclui esse arquivo). Agora adicione a referência ao projeto library do Sherlock, para tal, clique com o botão direito no projeto e selecione Properties.
Selecione Android, e na parte inferior direita, clique em Add... e selecione o projeto library e clique em OK. Agora, deixe a Activity do seu projeto conforme abaixo:
import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentTransaction; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import com.actionbarsherlock.app.*; import com.actionbarsherlock.app.ActionBar.*; import com.actionbarsherlock.view.Menu; public class ExemploSherlockActivity extends SherlockFragmentActivity implements TabListener { private Fragmento1 f1; private Fragmento2 f2; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setTheme(R.style.Theme_Sherlock_Light); setContentView(R.layout.activity_exemplo_sherlock); f1 = (Fragmento1)getSupportFragmentManager() .findFragmentById(R.id.fragmento1); f2 = (Fragmento2)getSupportFragmentManager() .findFragmentById(R.id.fragmento2); getSupportActionBar().setNavigationMode( ActionBar.NAVIGATION_MODE_TABS); Tab aba1 = getSupportActionBar().newTab() .setText("Aba 1") .setTabListener(this); Tab aba2 = getSupportActionBar().newTab() .setText("Aba 2") .setTabListener(this); getSupportActionBar().addTab(aba1); getSupportActionBar().addTab(aba2); } @Override public boolean onCreateOptionsMenu(Menu menu) { getSupportMenuInflater().inflate( R.menu.activity_exemplo_sherlock, menu); return super.onCreateOptionsMenu(menu); } @Override public void onTabSelected(Tab tab, FragmentTransaction ft) { if (tab.getPosition() == 0){ ft.show(f1).hide(f2); } else { ft.show(f2).hide(f1); } } @Override public void onTabUnselected( Tab tab, FragmentTransaction ft) {} @Override public void onTabReselected( Tab tab, FragmentTransaction ft) {} public static class Fragmento1 extends Fragment { @Override public View onCreateView(LayoutInflater infltr, ViewGroup container, Bundle savedState){ TextView txt = new TextView(getActivity()); txt.setText("Fragmento 1"); return txt; } } public static class Fragmento2 extends Fragment { @Override public View onCreateView(LayoutInflater infltr, ViewGroup container, Bundle savedState){ TextView txt = new TextView(getActivity()); txt.setText("Fragmento 2"); return txt; } } }Como estamos trabalhando com Fragment, nossa classe herda de SherlockFragmentActivity. Implementamos a interface TabChangeListener para detectarmos quando houver a alternância entre abas. Declaramos dois fragmentos que serão nas abas, essa classes estão declaradas no final do arquivo, obviamente o ideal é que cada fragmento fique em um arquivo separado.
No onCreate setamos o tema do Sherlock, e em seguida setamos o arquivo de layout da Activity (que está logo abaixo). Depois inicializamos os fragmentos e definimos a forma de navegação da ActionBar para o modo de abas. E por fim, criamos e adicionamos as abas na ActionBar.
Abaixo temos o arquivo de layout da aplicação (res/layout/activity_exemplo_sherlock.xml):
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/FrameLayout1" android:layout_width="match_parent" android:layout_height="match_parent" > <fragment android:id="@+id/fragmento1" android:name="ngvl.android.exemplosherlock.ExemploSherlockActivity$Fragmento1" android:layout_width="match_parent" android:layout_height="match_parent" /> <fragment android:id="@+id/fragmento2" android:name="ngvl.android.exemplosherlock.ExemploSherlockActivity$Fragmento2" android:layout_width="match_parent" android:layout_height="match_parent" /> </FrameLayout>
Note que o nome da classe é composto do pacote da aplicação + o nome da classe. Como estamos usando uma Inner Class, o sinal de $ é usado. Se você definir os Fragmentos em arquivos separados (o que é o normal) coloque apenas o nome completo da classe.
E abaixo o arquivo de menu da aplicação (res/menu/activity_exemplo_sherlock.xml) ele é carregado no método onCreateOptionsMenu. Para tratar cada opção adicione o método onMenuItemSelected.
<menu xmlns:android="http://schemas.android.com/apk/res/android" > <item android:id="@+id/menu_new" android:showAsAction="always|withText" android:icon="@android:drawable/ic_menu_add" android:title="Novo"/> <item android:id="@+id/menu_edit" android:showAsAction="ifRoom|withText" android:icon="@android:drawable/ic_menu_edit" android:title="Editar"/> <item android:id="@+id/menu_listar" android:showAsAction="ifRoom" android:icon="@android:drawable/ic_menu_my_calendar" android:title="Listar Itens"/> </menu>O primeiro item sempre aparece com ícone e texto. No segundo, o ícone sempre aparece, mas texto só aparece (na barra) se houver espaço. O último só aparecerá se houver espaço, para vê-lo, você deverá pressionar a tecla menu (ou nos dispositivo que não tenham, esse item ficará "colapsed" mas a direita).
Ao mandar executar a aplicação devemos ter uma tela similar a abaixo.
Esse post é em homenagem aos meus alunos da FA7, que me obrigaram a aprender essa biblioteca durante a aula :) Abraço a todos!
Qualquer dúvida, deixem seus comentários.
4br4ç05,
nglauber
13 comentários:
Parabéns professor ótimo post!!
Abraços
Ai sim eu vi vantagem! :D
Olá, estou com a seguinte duvida ! tenho um splashscreen que é uma activity e gostaria de navegar para a sherlockActivity como faço a chamada para poder ir de uma pagina pra outra ?
Oi João Victor,
Normal... A SherlockActivity herda de Activity. Então vc pode chamar normalmente com startActivity.
4br4ç05,
nglauber
Poderia postar esse projeto pra download?
Estou com erro na library
Oi Fausto,
Eu não tenho mais esse código. Então vou ter que dar Ctrl+C e Ctrl+V daqui do blog.
Tenta fazer o mesmo ;)
4br4ç05,
nglauber
Amigo, estou querendo inserir, colocar a barra (inferior) com os 3 botões de navegação no android 2.2 para substituir os botões mecânicos.
Como faço ou onde posso encontrar?
Um forte abraço.
oi Antonio,
O ideal é que você mantenha a usabilidade do aparelho. Se o mesmo tem as teclas físicas de back e home, não é uma boa abordagem implementar esse mesmo comportamento na sua app.
4br4ç05,
nglauber
Como mostrar a ABA2 através de um botão na ActionBar? Estou precisando fazer isso.
Oi Unknown,
Bem, se a aba já está criada, é só fazer isso..
getSupportActionBar().setSelectedNavigationItem(position);
4br4ç05,
nglauber
Já está criada. Que método seria esse? Só colocar no código do botão da barra?
E sem ser a Sherlock, como seria?
Olá Unknown,
Com a SherlockActionBar e com a API de compatibilidade que eu mostrei aqui (http://nglauber.blogspot.com.br/2013/07/actionbar-na-api-de-compatibilidade.html) é da forma que eu mostrei no comentário anterior.
Sem elas, você terá que rodar no Android 3 ou superior e a única diferença é que você usará getActionBar(). E o código, você coloca onde precisar...
4br4ç05,
nglauber
Postar um comentário