Закрыть

Присоединяйся!

Авторизуйтесь через популярные соц.сети

Вконтакте Google+
recode
0 Просмотров 1762 reCode

reCode #3: Реагирующие кнопки

Для начала хотелось бы предупредить тех, кто ждет всего и сразу. Я всё еще школьник и привык учиться программировать поэтапно, вникать в код и главное — понимать его. За последнюю неделю я не имел много свободного времени, но этот урок будет крайне интересен, в частности для меня. Каждый, кто когда-либо программировал, знает это чувство, когда уделил хоть какое-то время написанию программы и после запуска она заработала. Приятное, не так ли?

Сегодня я хочу немного рассказать вам про обработчик событий. Это будет один из тех уроков, подсказывает моё чутьё, которые будут важны для понимания принципов работы и устройства приложения. Однако здесь мы будем использовать некоторые свойства и особенности языка Java и им стоит уделить внимание.

Еще немного о Java

Одной из приятных особенностей Java является грамотно устроенная система общения файлов внутри проекта — можно использовать методы и функции одного файла в другом. Если здесь есть люди, знающие об этом больше меня, то приношу извинения за делитанский подход, поправьте меня, если я что-то не так говорю.

Обращения происходят внутри кода. Обращаться можно как к методу из какой-нибудь библиотеки в форме «<название библиотеки>.<имя метода>(<аргументы для метода>)», так и к какому-нибудь частному методу из любого файла вашего проекта: «<название файла без расширения>.<имя метода>(<аргументы для метода>)».

Теперь покажу небольшой финт ушами, когда лень писать много проверок и сравнений одной и той же переменной с разными возможными значениями. В известных мне языках это называется case (Pascal) или match (OCaml), в Java же эта штука называется switch. Работает очень просто. При вызове указывается переменная, и программа, формально говоря, сравнивает значение переменной с тем, что вы укажете. В случае совпадения выполняется код, прописанный для конкретного случая. Абстрактно этот процесс выглядит так:

[java]
switch (<переменная>) {
case (<первое возможное значение>) :
<соответствующий код>
break;
case (<второе возможное значение>) :
<соответствующий код>
break;
<…и так далее…>
}
[/java]

Небольшой пример. Существует шестнадцатиричная система исчисления. В ней цифры 0-9 имеют привычное десятичное значение, а буквы A-F имеют значение 10-15 соответственно. Для примера кода с использованием switch нам будет интересно при вводе буквы A-F узнавать её значение в десятичной системе. Как, например, B = 11 или D = 13.

[java]
import java.util.Scanner; //библиотека нужна для ввода с клавиатуры
public class reCode {
public static void main (String[] args) {

Scanner keyboard = new Scanner(System.in); //Объявляем сканер с названием keyboard.
String letter = "";
letter = keyboard.nextLine(); //Читаем строку и записываем её в переменную

//Нас интересует только одна буква, поэтому можно перезаписать строку в тип char
char ltr; //В эту переменную запишем первый символ строки letter
int value = 0; //В эту переменную запишем значение буквы в десятичной системе
ltr = letter.charAt(0); //<имя какой-то строки>.charAt(<индекс символа, первый 0>) имеет значение символа,
//стоящего на месте <индекс символа> в строке <имя какой-то строки>
//В нашем случае я запрашиваю нулевой (визуально первый) символ строки letter,
//он имеет тип char
switch (ltr) {
case ‘A’:
value = 10; //В каждом случае будем присваивать соответствующее значение переменной value
break; //пишется в конце каждого случая свитча
case ‘B’:
value = 11;
break;
case ‘C’:
value = 12;
break;
case ‘D’:
value = 13;
break;
case ‘E’:
value = 14;
break;
case ‘F’:
value = 15;
break;
}
System.out.println(ltr + " имеет значение " + value + " в десятичной системе.");
}
}
[/java]

Обработчик событий

Теперь пришло время поговорить про ту часть приложения, которая занмается обработкой различных событий, происходящих внутри приложения. Сегодня зайдем со стороны взаимодействия с приложениям посредством кнопок. Сегодня мы будем работать с двумя файлами: xml-файл, с которым мы уже работали раньше, и java-файл, который отвечает за выводимую на экран информацию. При помощи последнего также организуются обращения к элементам интерфейса, насколько я понял. В любом проекте он имеет схожее имя с xml-файлом (похожее, но не такое же) и находится по пути <название проекта>/app/src/main/java/<название пакета>.<название проекта>/. 

Параметры моего проекта:

Application name: Listener
Company Domain:
 recode
Package name: 
recode.listener
Activity Name: MyActivity

В моем случае нужный нам java-файл находится по пути /Listener/app/src/main/java/recode.listener/. Но об этом позже.

Для начала нам надо добавить пару элементов интерфейса, с которыми мы будем работать. Нам понадобится две кнопки и одно текстовое поле.

Так как нам придется работать с этими элементами интерфейса, то надо знать их идентификаторы, то есть имена, при помощи которых мы будем вызывать их в коде приложения. Узнать и поменять их можно в том же xml-файле, но в режиме кода. Переключиться в него можно маленькой кнопкой Text внизу справа.

Screen Shot 2014-06-19 at 14.30.05

В коде xml-файла у каждого элемента интерфейса есть своё описание, заканчивающееся полем id. Идентификатором элемента будет слово, стоящее в этом поле после символов «@+id/». Например мое текстовое поле имеет идентификатор medText, а соответствующая строка кода выглядит так

[xml]
android:id="@+id/medText"
[/xml]

Дальше по тексту я буду использовать идентификаторы button и button2 для двух кнопок. Таким образом мой xml-файл выглядит так:

[xml]
<LinearLayout
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:text="Medium Text"
        android:id="@+id/medText" />

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

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button 2"
        android:id="@+id/button2" />
</LinearLayout>
[/xml]

Пришло время поработать в  java-файле. Открываем его и, для того, чтобы у нас была возможность подцепить кнопки и текстовое поле, добавляем к списку уже имеющихся библиотек вот эти четыре:

[java]
import android.widget.TextView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
[/java]

После этого нужно инициализировать добавленные нами элементы. Сразу после открытия класса (перед всеми методами) инициализируем элементы интерфейса:

[java]
TextView medText;
Button button;
Button button2;
[/java]

После этого их можно вызывать по соответствующим id. Теперь перейдем в метод onCreate. Чтобы дальше в методе можно было работать с кнопками и текстовым полем, «найдём» их после строки «setContentView(R.layout.activity_my);» :

[java]
medText = (TextView) findViewById(R.id.medText);
button = (Button) findViewById(R.id.button);
button2 = (Button) findViewById(R.id.button2);
[/java]

 

Пока мой файл MyActivity.java выглядит как-то так:

[java]
package recode.listener;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MyActivity extends Activity {
TextView medText;
Button button;
Button button2;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
medText = (TextView) findViewById(R.id.medText);
button = (Button) findViewById(R.id.button);
button2 = (Button) findViewById(R.id.button2);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.my, menu);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
[/java]

Мы изменяли только метод onCreate и кое-что перед ним, поэтому на остальной код не обращаем внимания. Теперь пришло время создать обработчик. Его мы припишем к методу onCreate, то есть после всего того, что мы уже добавили. Сначала объявляем его и открываем тело:

[java]
OnClickListener oclButton = new OnClickListener() {
};
[/java]

Теперь нужно описать его. В теле создаем метод onClick и описываем его. Далее по комментариям в коде:

[java]
@Override
public void onClick(View v) { //создали метод, в параметре v будет передаваться элемент интерфейса, с которым произошло взаимодействие
switch (v.getId()) { //v.getId() имеет значение идентификатора элемента интерфейса, который мы писали и определяли раньше
case R.id.button: //в нашем случае кнопки две, поэтому мы определяем, какая из них была нажата
medText.setText("Была нажата кнопка 1"); //в зависимости от нажатой кнопки изменяем текст в текстовом поле
break;
case R.id.button2:
medText.setText("Была нажата кнопка 2");
break;
}
}
[/java]

 

В методе onClick мы работали с переменной oclButton, пришло время присвоить её значение обеим кнопкам. Сразу после обработчика пишем:

[java]
button.setOnClickListener(oclButton);
button2.setOnClickListener(oclButton);
[/java]

Это всё, для небольшой проверки — код моего java-файла выглядит так:

[java]
package recode.listener;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MyActivity extends Activity {
TextView medText;
Button button;
Button button2;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
medText = (TextView) findViewById(R.id.medText);
button = (Button) findViewById(R.id.button);
button2 = (Button) findViewById(R.id.button2);
OnClickListener oclButton = new OnClickListener() {
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button:
medText.setText("Была нажата кнопка 1");
break;
case R.id.button2:
medText.setText("Была нажата кнопка 2");
break;
}
}
};
button.setOnClickListener(oclButton);
button2.setOnClickListener(oclButton);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.my, menu);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
[/java]

Теперь можно запускать приложение и проверять кнопки. По всем вопросам, как всегда, в комментарии или ко мне в твиттер. До скороой встречи!

Комментариев 0

Авторизуйтесь через популярные соц.сети

Вконтакте Google+