MójDroid.pl

#6 Twórz aplikacje na Androida z Mojdroid.pl - Reakcje na kliknięcie

2012-09-17
|
Damian P.

W piątej części szybko poznaliśmy prostą reakcję na wybranie elementu z listy. W kolejnym poradniku chciałbym omówić reakcję na każde kliknięcie, niezależnie czy jest to przycisk, własna lista czy tekst. Proste zadanie z równie prostym wytłumaczeniem.

Informacja: Nie radzisz sobie z kodem? Coś Ci nie wychodzi lub nie działa? Zgubiłeś się? W tym miejscu zobaczysz pełen kod aplikacji, a tutaj go pobierzesz na dysk.

1. OnClickListener

Jest to nic innego jak definicja reakcji na pewne zdarzenie, w tym wypadku dotknięcie klikalnego elementu. To ważne - czasami coś może blokować nasze intencje klikania lub sami chcemy pozbyć się takiej odpowiedzi. Zazwyczaj jednak problem ten nam nie dokucza, a jeżeli przypadkiem coś takiego się nam zdarzy, to wystarczy ponownie ustalić hierarchię "klikalności" przez ustawienie setClickable(true) i/lub setEnabled(true) na View/elemencie. Oczywiście działa to również w drugą stronę - w ten sposób szybko możemy blokować niektóre elementy. Wróćmy jednak do samego reagowania na kliknięcie. Tutaj ważna uwaga - kliknięcie nie jest równe dotknięciu elementu, bo wywołać ten Listener możemy również poprzez tapnięcie kursora czy wprowadzanie tekstu przez klawiaturę w tablecie. Na samo dotknięcie reagować będziemy inaczej, implementując inny Listener, ale o tym jeszcze nie teraz. OnClickListenera możemy przypisać do elementu na dwa sposoby: używając implementacji w całej klasie lub tworząc pojedynczy, jeden nowy obiekt Listener do elementu. Czym się one różnią? Porządkiem i zarządzaniem pamięcią. Jeżeli w naszej aplikacji będzie dużo elementów, które będą mieć ustawionego onClickListenera, lepiej zastosować implementację do klasy, bo całość będzie w jednym miejscu, gdzie pisząc nowe Listenery do każdego elementu zrobimy sobie bałagan, a na dodatek OnClickListener jest deklarowany w pamięci raz, a nie kilkanaście.

2. Tworzymy reakcję na kliknięcie

Na początek stwórzmy nowe Activity, nowy element w naszej prostej liście (aby móc przejść do testów tego poradnika), nowy szablon w folderze layout oraz dodajmy wpis do AndroidManifest (z zarejestrowaniem nowego Activity). U mnie klasa będzie nazywać się View_Listener_Click, a wygląd - view_listener_click. Mój XML z wyglądem prezentuje się tak: A jego kod tak:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Large Text"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button" />

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_launcher" />

</LinearLayout>
W tym layoucie dodałem kilka podstawowych elementów (te omówię w kolejnym wpisie), takich jak przycisk (Button), tekst (TextView) oraz obraz (ImageView). Nic szczególnego. Przejdźmy teraz do naszego nowo utworzonego Activity. Tutaj rzecz jasna musimy zadeklarować każdy z elementów oraz ustawić na niego nasz omawiany Listener. Zacznijmy od pierwszej części:
package com.example.moja.pierwsza.aplikacja;

import android.app.Activity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

public class View_Listener_Click extends Activity {

	TextView text;
	Button button;
	ImageView image;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);

	setContentView(R.layout.view_listener_click);

	text = (TextView) findViewById(R.id.tv_click_listener);
	button = (Button) findViewById(R.id.bt_click_listener);
	image = (ImageView) findViewById(R.id.iV_click_listener);

    }

}
Od razu podzielmy to jakoś, abym mógł wam pokazać dwie wcześniej wymienione możliwości "użycia". Obraz na przykład niech będzie podłączony to nowego onClickListenera, gdzie tekst i przycisk będą korzystać z tego implementowanego łącznie z Activity. Jako część naszego Activity będzie to wyglądało tak:
package com.example.moja.pierwsza.aplikacja;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class View_Listener_Click extends Activity implements OnClickListener {

    TextView text;
    Button button;
    ImageView image;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);

	setContentView(R.layout.view_listener_click);

	text = (TextView) findViewById(R.id.tv_click_listener);
	button = (Button) findViewById(R.id.bt_click_listener);
	image = (ImageView) findViewById(R.id.iV_click_listener);

	text.setOnClickListener(this);
	button.setOnClickListener(this);

    }

    public void onClick(View v) {

	switch (v.getId()) {
	case R.id.tv_click_listener:
	    text.setText("Test");
	    break;
	case R.id.bt_click_listener:
	    Toast.makeText(this, "Kliknąłeś przycisk!", Toast.LENGTH_SHORT).show();
	    break;
	}

    }

}
Implementujemy OnClickListener na całą klasę, po czym dodajemy wymaganą metodę. W niej rozróżniamy kliknięty element po jego ID z pliku XML. W tej funkcji wykonujemy już odpowiednią reakcję na dotyk, niech będzie to zmiana tekstu oraz wyświetlenie prostego powiadomienia. Zauważcie tutaj, że w tym przypadku wymagane jest dodatkowo połączenie przycisku z Listenerem - sama implementacja OnClickListener nie wystarczy! Nieco łatwiej sprawa ma się z definiowaniem nowego OnClickListenera, z tym że posiada on wady (wymienione wcześniej):
package com.example.moja.pierwsza.aplikacja;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class View_Listener_Click extends Activity implements OnClickListener {

    TextView text;
    Button button;
    ImageView image;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);

	setContentView(R.layout.view_listener_click);

	text = (TextView) findViewById(R.id.tv_click_listener);
	button = (Button) findViewById(R.id.bt_click_listener);
	image = (ImageView) findViewById(R.id.iV_click_listener);

	text.setOnClickListener(this);
	button.setOnClickListener(this);

	image.setOnClickListener(new OnClickListener() {

	    public void onClick(View v) {
		v.setVisibility(View.GONE);
	    }

	});

    }

    public void onClick(View v) {

	switch (v.getId()) {
	case R.id.tv_click_listener:
	    text.setText("Test");
	    break;
	case R.id.bt_click_listener:
	    Toast.makeText(this, "Kliknąłeś przycisk!", Toast.LENGTH_SHORT).show();
	    break;
	}

    }

}
Zauważcie również, że onClickListener nie zwraca żadnej wartości (niektóre mogą, np true/false).

3. Pozostałe ClickListenery

OnClickListener nie jest jedyną definicją na kliknięcie - Android bez problemu obsługuje również dotknięcie, długie przytrzymanie czy zaznaczenie. Poszczególne Listenery nie różnią się od siebie za bardzo i możemy je implementować w podobny sposób. Więcej o zdarzeniach w tym miejscu.