w Define o método para processar reviews
CICLO DE VIDA DA ACTIVITY
3.2 Trabalhando com views
3.2.7 Entendendo os eventos
Os eventos são usados para mudar o foco e muitas outras ações. Nós já implemen- tamos diversos métodos onClickListener() para botões na Listagem 3.2. Aquelas instâncias OnClickListener estavam conectadas ao apertar de botões. Elas indica- vam eventos que diziam “Ei, alguém me pressionou”. Os eventos de foco passam por esse mesmo processo quando anunciam ou respondem a eventos OnFocusChange.
Eventos têm duas metades: o componente que dá origem ao evento e o componen- te (ou componentes) que respondem ao evento. Essas duas metades são conhecidas como Observable e Observer em termos do padrão de design, ou às vezes como subject e observer. A Figura 3.7 é um diagrama de classe das relações nesse padrão.
Um componente Observable fornece um modo para as instâncias Observer
registrarem. Quando ocorre um evento, o Observable notifica todos os Observ ers que algo aconteceu. Os Observers podem então responder àquela notificação
registerObserver() : void unregisterObserver(): void notifyObserver(): void
observerCollection : Collection<Observer> (Listeners)Observable (Source)
notify() : void Observer (Listener) ObserverImpl ObserveableImpl * 0..1 Para observer em observerCollection: notifyObserver()
Figura 3.7 Um diagrama de classe mostrando o padrão de
design Observer. Cada componente Observable possui
zero ou muitos Observers, que são notificados de mudan-
sempre que for necessário. As interfaces são geralmente usadas pelos vários tipos de eventos em uma API em particular.
Um Button Android representa isso do seguinte modo:
Observable—Button.setOnClickListener(OnClickListener listener). Observer—listener.onClick(View v).
Esse padrão afeta os itens View Android, uma vez que muitas coisas são Observ able e permitem que outros componentes se anexem e monitorem eventos. Por exemplo, a maioria dos métodos da classe View que começam com on são relacio- nados a eventos: onFocusChanged(), onSizeChanged(), onLayout(), onTouch Event() e similares.
Eventos ocorrem tanto na IU como em toda a plataforma. Por exemplo, quando uma chamada telefônica é recebida ou uma localização de GPS muda devido ao mo- vimento físico, muitas reações diferentes podem ocorrer. Mais de um componente pode querer ser notificado quando o telefone toca ou quando a localização muda — não só naquele que você está trabalhando — e a lista de Observers não se limita necessariamente a objetos orientados a IU.
Views suportam eventos em muitos níveis. Quando um evento de interface ocorre, como um usuário pressionando um botão, rolando ou selecionando uma parte de uma janela, o evento é despachado para a view apropriado. Eventos de clique, eventos de teclado, eventos de toque e eventos de foco são os tipos de even- tos com que você vai trabalhar principalmente na IU.
Lembre-se que a interface de usuário do Android possui somente um thread. Se você chamar um método em uma view, precisará estar no thread da IU. Lembre-se que é por isso que usamos um handler na Listagem 3.3 — para obter dados fora do thread da IU e para notificar o thread da IU para atualizar a View depois que os dados foram recuperados. Os dados foram enviados de volta para o Handler como uma Message por meio do evento setMessage().
Nossa cobertura dos eventos em geral e como eles se relacionam ao layout, en- cerra a maior parte da nossa discussão sobre views, mas ainda temos um conceito relacionado importante para discutir — recursos. Na próxima seção, vamos abordar todos os aspectos dos recursos, incluindo views definidas por XML.
3.3
Usando recursos
Já vimos vários exemplos de recursos no livro. Agora vamos explorá-los detalhada- mente e implementar a terceira e última Activity no RestaurantFinder — a tela
ReviewDetail.
Quando você começar a trabalhar com o Android, vai perceber logo muitas re- ferências a uma classe chamada R. Essa classe foi apresentada no Capítulo 1 e nós a usamos em nossos exemplos anteriores de Activity neste capítulo. O Android gera automaticamente essa classe para cada um dos seus projetos para fornecer acesso aos recursos. Recursos são itens sem código que a plataforma inclui automa- ticamente em seu projeto.
Para começar a estudar os recursos, vamos primeiro explorar os vários tipos dis- poníveis e, em seguida, mostrar exemplos de cada tipo de recurso.
Usando recursos 91 3.3.1 Tipos de recursos suportados
Os recursos de cada projeto Android estão localizados no diretório res. Nem todo projeto usará todos os tipos, mas qualquer recurso deve corresponder a um dos tipos disponíveis:
res/anim — Representações XML de animações quadro a quadro.
res/drawable — Elementos gráficos, como imagens PNG e JPG, imagens nine- -patch extensíveis e gradientes.
res/layout — Representações XML de hierarquia de objetos View.
res/values — Representação XML de strings, cores, estilos, dimensões e arrays. res/xml — Arquivos XML definidos pelo usuário compilados em uma represen-
tação binária compacta.
res/raw — Arquivos arbitrários e não compilados.
Recursos são tratados especialmente no Android porque são tipicamente com- pilados em um tipo binário eficiente, com as notáveis exceções de itens que já são binários e o tipo raw, que não é compilado. Animações, layouts e views, valores de string e cores, e arrays podem todos ser definidos no formato XML na plataforma. Esses recursos XML são então processados pela ferramenta aapt, que vimos no Ca- pítulo 2, e compilados. Depois que os recursos forem compilados, eles estarão aces- síveis em Java por meio da classe R, gerada automaticamente.
3.3.2 Referenciando recursos em Java
A primeira parte da ActivityReviewDetail, mostrada na listagem a seguir, reutili- za muitos dos princípios de Activity que você já aprendeu e usa diversos subcom- ponentes que vêm de R.java.
lisTagem 3.6 Primeira parte de ReviewDetail mostrando múltiplos usos da classe R
public class ReviewDetail extends Activity {
private static final int MENU_CALL_REVIEW = Menu.FIRST + 2; private static final int MENU_MAP_REVIEW = Menu.FIRST + 1; private static final int MENU_WEB_REVIEW = Menu.FIRST; private String imageLink;
private String link; private TextView location; private TextView name; private TextView phone; private TextView rating; private TextView review; private ImageView reviewImage;
private Handler handler = new Handler() { public void handleMessage(Message msg) {
if ((imageLink != null) && !imageLink.equals("")) { try {
URL url = new URL(imageLink);
URLConnection conn = url.openConnection(); conn.connect();
BufferedInputStream bis = new
Define itens View descompactáveis
q
BufferedInputStream(conn.getInputStream());
Bitmap bm = BitmapFactory.decodeStream(bis); bis.close();
reviewImage.setImageBitmap(bm); } catch (IOException e) {
// faz log ou tratamento aqui
} } else { reviewImage.setImageResource(R.drawable.no_review_image); } } }; @Override
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
setContentView(R.layout.review_detail);
name = (TextView) findViewById(R.id.name_detail); rating = (TextView) findViewById(R.id.rating_detail); location = (TextView) findViewById(R.id.location_detail); phone = (TextView) findViewById(R.id.phone_detail); review = (TextView) findViewById(R.id.review_detail); reviewImage = (ImageView) findViewById(R.id.review_image); RestaurantFinderApplication application =
(RestaurantFinderApplication) getApplication(); Review currentReview = application.getCurrentReview(); link = currentReview.link; imageLink = currentReview.imageLink; name.setText(currentReview.name); rating.setText(currentReview.rating); location.setText(currentReview.location); review.setText(currentReview.content);
if ((currentReview.phone != null) && !currentReview.phone. equals("")) { phone.setText(currentReview.phone); } else { phone.setText("NA"); } } @Override
public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); menu.add(0, ReviewDetail.MENU_WEB_REVIEW, 0, R.string.menu_web_review).setIcon( android.R.drawable.ic_menu_info_details); menu.add(0, ReviewDetail.MENU_MAP_REVIEW, 1, R.string.menu_map_review).setIcon( android.R.drawable.ic_menu_mapmode); #3 menu.add(0, ReviewDetail.MENU_CALL_REVIEW, 2, R.string.menu_call_review).setIcon( android.R.drawable.ic_menu_call); return true; } .. }