Java + Android
Java + Android
1

LEKCJA ORGANIZACYJNA
2
O MNIE
• Wykształcenie:
• Doświadczenie zawodowe:
• Self-employed Web Developer - in2dev (od 2022) Obraz autorstwa storyset na Freepik
• 1x sprawdzian
• odpowiedź ustna
• praca na lekcji**
• nieprzygotowanie 2x
• II semestr
• 1x sprawdzian
• odpowiedź ustna
• praca na lekcji**
4
UWAGI DO ZASAD OCENIANIA -
WYKŁAD
• Szczęśliwy numerek i nieprzygotowanie zwalnia z
odpowiedzi ustnej i innych niezapowiedzianych form
sprawdzenia wiedzy, ale NIE z zapowiedzianej
kartkówki, sprawdzianu i aktywności na
zajęciach
5
fi
ZASADY OCENIANIA - PRACOWNIE
• I semestr
• 1x sprawdzian
• zadania z lekcji
• praca na lekcji*
• nieprzygotowanie 2x
• II semestr
• 1x sprawdzian
• zadania z lekcji
• praca na lekcji*
• projekt**
Obraz autorstwa storyset na Freepik
• nieprzygotowanie 2x
6
UWAGI DO ZASAD OCENIANIA -
PRACOWNIE
• Zadania z lekcji będą sprawdzane wyrywkowo na kolejnych
zajęciach. Nieobecność na lekcji nie zwalnia z wykonania
zadania.
7
fi
KONTAKT Z PROWADZĄCYM
• E-dziennik
• [email protected] (zalecany)
• Teams
8
TEMATYKA ZAJĘĆ
9
TEMATYKA ZAJĘĆ
• Wprowadzenie do języka Java
• Style i tematy
• Aktywności i fragmenty
10
TEMATYKA ZAJĘĆ
• Powiadomienia
• Obrazy i animacje
13
TROCHĘ DANYCH TECHNICZNYCH
• Pojawienie się: 1995
• Jego właścicielem jest Oracle, a sama Java działa na ponad 3 miliardach urządzeń.
• Aplikacji desktopowych
• Aplikacji internetowych
• Gier
15
DLACZEGO UŻYWAMY JAVY?
• Java działa na różnych platformach (Windows, Mac, Linux, Raspberry Pi itp.).
• Java jest językiem obiektowym, który nadaje programom przejrzystą strukturę i pozwala na ponowne wykorzystanie kodu,
obniżając koszty rozwoju.
16
JRE - JAVA RUNTIME ENVIRONMENT
• Przeznaczenie:
• Opis:
• Opis:
20
IDE DLA JĘZYKA JAVA
• IntelliJ IDEA
• Eclipse
• NetBeans
• i inne…
21
INTELLIJ IDEA
22
SKŁADNIA JĘZYKA JAVA
23
OUTPUT - PRINTLN
System.out.println("Hello World!");
System.out.println("I am learning Java.");
System.out.println("It is awesome!”);
// Output:
// Hello World!
// I am learning Java.
// It is awesome!
24
OUTPUT - PRINT
// Output:
// Hello World! I will print on the same line.
25
KOMENTARZE
// This is a comment
System.out.println("Hello World"); // This is also a comment
/* This is a
multi-line comment */
26
ZMIENNE
• Zmienne są kontenerami do przechowywania wartości danych.
• String - przechowuje tekst, taki jak „Hello”. Wartości String są otoczone podwójnymi cudzysłowami
• int - przechowuje liczby całkowite bez miejsc po przecinku, takie jak 123 lub -123
• oat - przechowuje liczby zmiennoprzecinkowe z miejscami dziesiętnymi, takie jak 19.99 lub -19.99
• char - przechowuje pojedyncze znaki, takie jak „a” lub „B”. Wartości char są otoczone pojedynczymi cudzysłowami
• Deklarowanie zmiennej:
27
fl
DEFINIOWANIE ZMIENNYCH
public class Main {
public static void main(String[] args) {
String name = "John";
System.out.println("Hello, " + name + "!"); // Output: Hello, John!
int myNum = 5;
System.out.println(myNum); // Output: 5
int myOtherNum;
myOtherNum = 10;
System.out.println(myOtherNum); // Output: 10
myNum = 20;
System.out.println(myNum); // Output: 20
}
}
28
ZMIENNA FINAL
29
TYPY DANYCH
30
TYPY PRYMITYWNE
Typ Rozmiar Opis
32
fl
TYPY LICZBOWE
public class Main {
public static void main(String[] args) {
byte myByte = 100;
System.out.println(myByte);
short myShort = 5000;
System.out.println(myShort);
int myInt = 100000;
System.out.println(myInt);
long myLong = 1000000000L;
System.out.println(myLong);
float myFloat = 5.75f;
System.out.println(myFloat);
double myDouble = 19.99d;
System.out.println(myDouble);
}
}
33
TYPY LICZBOWE - ZAPIS NAUKOWY
34
TYP CHAR
35
TYPY NIEPRYMITYWNE
• Nieprymitywne typy danych są nazywane typami referencyjnymi, ponieważ odnoszą się do obiektów.
• Typy prymitywne są prede niowane (już zde niowane) w Javie. Typy nieprymitywne są tworzone przez programistę
i nie są zde niowane przez Javę (z wyjątkiem String).
• Typy nieprymitywne mogą być używane do wywoływania metod w celu wykonania pewnych operacji, podczas gdy
typy prymitywne nie mogą.
• Typ prymitywny zawsze ma wartość, podczas gdy typy nieprymitywne mogą mieć wartość null.
• Typ prymitywny zaczyna się małą literą, podczas gdy typy nieprymitywne zaczynają się wielką literą.
• byte -> short -> char -> int -> long -> oat -> double
• double -> oat -> long -> int -> char -> short -> byte
37
fl
fl
RZUTOWANIE ROZSZERZAJĄCE
System.out.println(myInt); // Outputs 9
System.out.println(myDouble); // Outputs 9.0
}
}
38
RZUTOWANIE ZAWĘŻAJĄCE
39
OPERATORY
40
OPERATORY ARYTMETYCZNE
41
OPERATORY PRZYPISANIA
Operator Przykład Równoważny zapis
= x=5 N/D
+= x += 3 x=x+3
-= x -= 3 x=x-3
*= x *= 3 x=x*3
42
OPERATORY PRZYPISANIA
Operator Przykład Równoważny zapis
/= x /= 3 x=x/3
%= x %= 3 x=x%3
|= x |= 3 x=x|3
43
OPERATORY PRZYPISANIA
^= x ^= 3 x=x^3
44
OPERATORY BITOWE
Operator Nazwa Opis Przykład
Ustawia bit wynikowy na 1, jeżeli oba
& Bitowy AND x&y
bity są równe 1
Ustawia bit wynikowy na 1, jeżeli co
| Bitowy OR x|y
najmniej jeden bit jest równy 1
Ustawia bit wynikowy na 1, jeżeli
^ Bitowy XOR x^y
jeden z bitów to 1, a drugi 0
Przesunięcie bitowe w Przesunięcie bitów w prawo, skrajne
>> x >> 2
prawo prawe bity „spadają”
Przesunięcie bitowe w Przesunięcie bitów w lewo i
<< x << 2
lewo wypełnienie zerami
~ Negacja bitowa Odwraca bity ~x
45
BITOWY AND
46
BITOWY OR
47
BITOWY XOR
48
PRZESUNIĘCIE BITOWE W PRAWO
49
PRZESUNIĘCIE BITOWE W LEWO
50
NEGACJA BITOWA
51
OPERATORY PORÓWNANIA
== Równe x == y
!= Nie równe x != y
52
OPERATORY PORÓWNANIA
53
OPERATORY LOGICZNE
55
MATH.MAX()
56
MATH.MIN()
57
MATH.SQRT()
58
MATH.ABS()
59
MATH.RANDOM()
60
INSTRUKCJE WARUNKOWE
61
IF
public class Main {
public static void main(String[] args) {
int x = 20;
int y = 18;
if (x > y) {
System.out.println("x is greater than y");
}
62
ELSE
public class Main {
public static void main(String[] args) {
int time = 20;
if (time < 18) {
System.out.println("Good day.");
} else {
System.out.println("Good evening.");
}
// Outputs "Good evening."
}
}
63
ELSE IF
public class Main {
public static void main(String[] args) {
int time = 22;
if (time < 10) {
System.out.println("Good morning.");
} else if (time < 18) {
System.out.println("Good day.");
} else {
System.out.println("Good evening.");
}
65
OPERATOR TRÓJARGUMENTOWY (ELVIS)
public class Main {
public static void main(String[] args) {
int time = 20;
if (time < 18) {
System.out.println("Good day.");
} else {
System.out.println("Good evening.");
}
// Simplified version
System.out.println(time < 18 ? "Good day." : "Good evening.");
}
}
66
SWITCH
public class Main {
public static void main(String[] args) {
int day = 4;
switch (day) {
case 1:
System.out.println("Monday");
break;
case 2:
System.out.println("Tuesday");
break;
case 3:
System.out.println("Wednesday");
break;
case 4:
System.out.println("Thursday");
break;
case 5:
System.out.println("Friday");
break;
case 6:
System.out.println("Saturday");
break;
case 7:
System.out.println("Sunday");
break;
}
// Output: Thursday
}
}
67
SŁOWO KLUCZOWE BREAK
• Po osiągnięciu słowa kluczowego break, Java przerywa wykonywanie
bloku switch.
69
PĘTLE
70
PĘTLA WHILE
public class Main {
public static void main(String[] args) {
int i = 0;
while (i < 5) {
System.out.println(i);
i++;
}
// Output:
// 0
// 1
// 2
// 3
// 4
}
}
71
PĘTLA DO…WHILE
public class Main {
public static void main(String[] args) {
int i = 0;
do {
System.out.println(i);
i++;
}
while (i < 5);
// Output:
// 0
// 1
// 2
// 3
// 4
}
}
72
73
74
PĘTLA FOR
public class Main {
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
System.out.println(i);
}
// Output:
// 0
// 1
// 2
// 3
// 4
}
}
75
PĘTLA FOR
public class Main {
public static void main(String[] args) {
int i = 0;
for (; i < 5;) {
System.out.println(i);
i++;
}
// Output:
// 0
// 1
// 2
// 3
// 4
}
}
76
PĘTLA FOR
77
ZAGNIEŻDŻONE PĘTLE
public class Main {
public static void main(String[] args) {
for (int i = 1; i <= 2; i++) {
System.out.println("Outer: " + i); // Executes 2 times
// Inner loop
for (int j = 1; j <= 3; j++) {
System.out.println(" Inner: " + j); // Executes 6 times (2 * 3)
}
}
// Output:
// Outer: 1
// Inner: 1
// Inner: 2
// Inner: 3
// Outer: 2
// Inner: 1
// Inner: 2
// Inner: 3
}
}
78
PĘTLA FOR-EACH
public class Main {
public static void main(String[] args) {
String[] cars = {"Volvo", "BMW", "Ford", "Mazda"};
for (String i : cars) {
System.out.println(i);
}
// Output:
// Volvo
// BMW
// Ford
// Mazda
}
}
79
TABLICE
80
TABLICE
public class Main {
public static void main(String[] args) {
// Declare arrays
String[] cars;
String[] cars2 = {"Volvo", "BMW", "Ford", "Mazda"};
int[] myNum = {10, 20, 30, 40};
// Empty array
String[] cars3 = new String[4];
// Accessing elements
System.out.println(cars2[0]); // Output: Volvo
// Array length
System.out.println(cars2.length); // Output: 4
}
}
81
TABLICE WIELOWYMIAROWE
public class Main {
public static void main(String[] args) {
// Declare array
int[][] myNumbers = { {1, 2, 3, 4}, {5, 6, 7} };
// Access elements
int[][] myNumbers2 = { {1, 2, 3, 4}, {5, 6, 7} };
System.out.println(myNumbers2[1][2]); // Outputs 7
83
METODY
• Metoda to blok kodu, który jest uruchamiany tylko wtedy, gdy zostanie
wywołany.
• Dlaczego warto używać metod? Aby ponownie użyć kodu: zde niuj kod raz i
używaj go wiele razy.
84
fi
METODY
public class Main {
// Defining a method
static void myMethod() {
System.out.println("I just got executed!");
}
86
WARTOŚCI ZWROTNE
87
WARTOŚCI ZWROTNE
88
PRZECIĄŻANIE METOD
public class Main {
static int plusMethod(int x, int y) {
return x + y;
}
• Blok kodu odnosi się do całego kodu pomiędzy nawiasami klamrowymi {}.
• Zmienne zadeklarowane wewnątrz bloków kodu są dostępne tylko przez kod znajdujący
się pomiędzy nawiasami klamrowymi, który następuje po linii, w której zmienna została
zadeklarowana.
90
ZAKRES METODY
public class Main {
public static void main(String[] args) {
int x = 100;
91
ZAKRES BLOKOWY
public class Main {
public static void main(String[] args) {
{ // This is a block
int x = 100;
}
}
92
REKURENCJA
• Rekurencja to technika wywoływania funkcji samej w sobie. Technika ta zapewnia sposób na
rozbicie skomplikowanych problemów na proste problemy, które są łatwiejsze do rozwiązania.
• Rekurencja może być nieco trudna do zrozumienia. Najlepszym sposobem na poznanie jej
działania jest eksperymentowanie.
• Podobnie jak pętle mogą napotkać problem nieskończonej pętli, funkcje rekurencyjne mogą
napotkać problem nieskończonej rekurencji. Nieskończona rekurencja ma miejsce, gdy funkcja
nigdy nie przestaje wywoływać samej siebie. Każda funkcja rekurencyjna powinna mieć
warunek zatrzymania, czyli warunek, w którym funkcja przestaje wywoływać samą siebie.
93
REKURENCJA
public class Main {
static int factorial(int n) {
if (n == 0) {
return 1;
}
return n * factorial(n - 1);
}
95
TWORZENIE KLASY
// MyClass.java
96
TWORZENIE OBIEKTU
97
ATRYBUTY I METODY
// MyClass.java
// Methods
public void myMethod() {
System.out.println("Hello World");
}
}
98
KONSTRUKTOR
// MyClass.java
100
MODYFIKATORY DOSTĘPU
101
MODYFIKATORY DOSTĘPU DLA KLAS
Klasa jest dostępna tylko dla klas w tym samym pakiecie. Jest
default
używana, gdy nie określono mody katora.
102
fi
fi
MODYFIKATORY DOSTĘPU DLA METOD I
ATRYBUTÓW
Mody kator Opis
104
MODYFIKATORY INNE NIŻ DOSTĘPU
DLA KLAS
Mody kator Opis
// Public method
public void myPublicMethod() {
System.out.println("Public methods must be called by creating objects");
}
// Main method
public static void main(String[ ] args) {
myStaticMethod(); // Call the static method
// myPublicMethod(); This would output an error
109
ABSTRACT
// AbstractStudent.java
110
ABSTRACT
// Student.java
111
ABSTRACT
public class Main {
public static void main(String[ ] args) {
// create an object of the Student class (which inherits
attributes and methods from AbstractStudent)
Student myObj = new Student();
113
ENKAPSULACJA
// Person.java
// Getter
public String getName() {
return name;
}
// Setter
public void setName(String newName) {
this.name = newName;
}
}
114
ENKAPSULACJA
115
DLACZEGO ENKAPSULACJA?
• Lepsza kontrola nad atrybutami i metodami klas
• Atrybuty klasy mogą być tylko do odczytu (jeśli używasz tylko metody
get) lub tylko do zapisu (jeśli używasz tylko metody set).
117
PAKIETY I API
• Pakiet w Javie służy do grupowania powiązanych klas. Można to
porównać do folderu w katalogu plików. Używamy pakietów, aby uniknąć
kon iktów nazw i pisać lepszy w utrzymaniu kod. Pakiety dzielą się na
dwie kategorie:
• Aby użyć klasy lub pakietu z biblioteki, należy użyć słowa kluczowego import.
119
PAKIETY WBUDOWANE
// import class
import java.util.Scanner;
// import package
import java.util.*;
120
PAKIETY WBUDOWANE
// import class
import java.util.Scanner;
└── root
└── mypack
└── MyPackageClass.java
122
PAKIETY DEFINIOWANE PRZEZ
UŻYTKOWNIKA
package mypack;
123
DZIEDZICZENIE
• W Javie możliwe jest dziedziczenie atrybutów i metod z jednej klasy
do drugiej. Koncepcję dziedziczenia dzielimy na dwie kategorie:
// Vehicle.java
class Vehicle {
protected String brand = "Ford"; // Vehicle attribute
public void honk() { // Vehicle method
System.out.println("Tuut, tuut!");
}
}
125
DZIEDZICZENIE
// Car.java
126
DZIEDZICZENIE
public class Main {
public static void main(String[ ] args) {
// Create a myCar object
Car myCar = new Car();
// Call the honk() method (from the Vehicle class) on the myCar
object
myCar.honk();
128
fi
fi
POLIMORFIZM
// Animal.java
class Animal {
public void animalSound() {
System.out.println("The animal makes a sound");
}
}
129
POLIMORFIZM
// Pig.java
130
POLIMORFIZM
// Dog.java
131
POLIMORFIZM
public class Main {
public static void main(String[ ] args) {
Animal myAnimal = new Animal(); // Create a Animal object
Animal myPig = new Pig(); // Create a Pig object
Animal myDog = new Dog(); // Create a Dog object
// Output:
// The animal makes a sound
// The pig says: wee wee
// The dog says: woof woof
}
}
132
KLASA WEWNĘTRZNA
133
KLASA WEWNĘTRZNA
// OuterClass.java
class OuterClass {
int x = 10;
class InnerClass {
int y = 5;
}
}
134
KLASA WEWNĘTRZNA
135
PRYWATNA KLASA WEWNĘTRZNA
// OuterClass.java
class OuterClass {
int x = 10;
136
PRYWATNA KLASA WEWNĘTRZNA
public class Main {
public static void main(String[ ] args) {
OuterClass outerObject = new OuterClass();
OuterClass.InnerClass innerObject = outerObject.new
InnerClass();
System.out.println(outerObject.x + innerObject.y);
// Main.java:4: error: OuterClass.InnerClass has private
access in OuterClass
// OuterClass.InnerClass innerObject = outerObject.new
InnerClass();
// ^
}
}
137
STATYCZNA KLASA WEWNĘTRZNA
// OuterClass.java
class OuterClass {
int x = 10;
138
STATYCZNA KLASA WEWNĘTRZNA
139
DOSTĘP DO KLASY ZEWNĘTRZNEJ Z
KLASY WEWNĘTRZNEJ
// OuterClass.java
class OuterClass {
int x = 10;
class InnerClass {
public int myInnerMethod() {
return x;
}
}
}
140
DOSTĘP DO KLASY ZEWNĘTRZNEJ Z
KLASY WEWNĘTRZNEJ
141
KLASY I METODY ABSTRAKCYJNE
• Abstrakcja danych to proces ukrywania pewnych szczegółów i pokazywania użytkownikowi tylko
niezbędnych informacji.
• Słowo kluczowe abstract jest mody katorem niedostępnym, używanym dla klas i metod:
• Klasa abstrakcyjna: jest ograniczoną klasą, która nie może być używana do tworzenia
obiektów (aby uzyskać do niej dostęp, musi być dziedziczona w innej klasie).
• Metoda abstrakcyjna: może być używana tylko w klasie abstrakcyjnej i nie ma ciała. Treść jest
dostarczana przez podklasę.
142
fi
KLASY I METODY ABSTRAKCYJNE
// Animal.java
// Abstract class
abstract class Animal {
// Abstract method (does not have a body)
public abstract void animalSound();
// Regular method
public void sleep() {
System.out.println("Zzz");
}
}
143
KLASY I METODY ABSTRAKCYJNE
// Pig.java
144
KLASY I METODY ABSTRAKCYJNE
145
INTERFEJSY
• Innym sposobem na osiągnięcie abstrakcji w Javie są interfejsy.
// Animal.java
interface Animal {
void animalSound(); // interface method (does not have a
body)
void sleep(); // interface method (does not have a body)
}
147
INTERFEJSY
// Pig.java
149
UWAGI DOTYCZĄCE INTERFEJSÓW
• Podobnie jak klasy abstrakcyjne, interfejsy nie mogą być używane do tworzenia obiektów.
• Metody interfejsu nie mają ciała - ciało jest dostarczane przez klasę „implementującą”.
• Interfejs nie może zawierać konstruktora (ponieważ nie może być używany do tworzenia
obiektów).
150
DLACZEGO I KIEDY UŻYWAĆ
INTERFEJSÓW?
• Aby osiągnąć bezpieczeństwo - ukryć pewne szczegóły i pokazać
tylko ważne szczegóły obiektu (interfejsu).
151
IMPLEMENTACJA WIELU INTERFEJSÓW
// FirstInterface.java
interface FirstInterface {
public void myMethod(); // interface method
}
152
IMPLEMENTACJA WIELU INTERFEJSÓW
// SecondInterface.java
interface SecondInterface {
public void myOtherMethod(); // interface method
}
153
IMPLEMENTACJA WIELU INTERFEJSÓW
// DemoClass.java
154
IMPLEMENTACJA WIELU INTERFEJSÓW
155
ENUMERATORY
156
ENUMERATORY
// Level.java
enum Level {
LOW,
MEDIUM,
HIGH
}
157
ENUMERATORY
158
ENUM WEWNĄTRZ KLASY
public class Main {
enum Level {
LOW,
MEDIUM,
HIGH
}
// Output:
// LOW
// MEDIUM
// HIGH
}
}
160
PRZYJMOWANIE DANYCH OD
UŻYTKOWNIKA
161
PRZYJMOWANIE DANYCH OD
UŻYTKOWNIKA
• Aby użyć klasy Scanner, należy utworzyć obiekt tej klasy i użyć
dowolnej z dostępnych metod znajdujących się w dokumentacji klasy
Scanner.
162
PRZYJMOWANIE DANYCH OD
UŻYTKOWNIKA
import java.util.Scanner; // Import the Scanner class
class Main {
public static void main(String[] args) {
Scanner myObj = new Scanner(System.in); // Create a Scanner
object
System.out.println("Enter username");
164
fl
TYPY PRZYJMOWANYCH DANYCH
Metoda Opis
165
TYPY PRZYJMOWANYCH DANYCH
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner myObj = new Scanner(System.in);
// String input
String name = myObj.nextLine();
// Numerical input
int age = myObj.nextInt();
double salary = myObj.nextDouble();
166
TYPY PRZYJMOWANYCH DANYCH
167
OBSŁUGA DAT
168
OBSŁUGA DAT
169
WYŚWIETLANIE BIEŻĄCEJ DATY
import java.time.LocalDate;
170
WYŚWIETLANIE BIEŻĄCEGO CZASU
import java.time.LocalTime;
171
WYŚWIETLANIE BIEŻĄCEJ DATY I
GODZINY
import java.time.LocalDateTime;
172
FORMATOWANIE DATY I CZASU
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
173
ARRAYLIST
174
ARRAYLIST
• Klasa ArrayList to tablica o zmiennym rozmiarze, którą można znaleźć
w pakiecie java.util.
import java.util.ArrayList;
176
DODAWANIE ELEMENTÓW
import java.util.ArrayList;
System.out.println(cars);
}
}
cars.set(0, "Opel");
cars.remove(0);
cars.clear();
System.out.println(cars); // Output: []
}
}
182
ROZMIAR ARRAYLIST
import java.util.ArrayList;
System.out.println(cars.size()); // Output: 3
}
}
183
PRZEJŚCIE PĘTLĄ
import java.util.ArrayList;
• Aby użyć innych typów, takich jak int, należy określić równoważną klasę wrapper:
Integer.
187
SORTOWANIE
import java.util.ArrayList;
import java.util.Collections; // Import the Collections class
188
LINKEDLIST
189
LINKEDLIST
import java.util.LinkedList;
• Jednakże, podczas gdy klasa ArrayList i LinkedList mogą być używane w ten sam
sposób, są one zbudowane zupełnie inaczej.
191
JAK DZIAŁA ARRAYLIST?
192
JAK DZIAŁA LINKEDLIST?
193
METODY LINKEDLIST
Metoda Opis
addFirst() Dodaje element na początku listy
addLast() Dodaje element na koniec listy
removeFirst() Usuwa element z początku listy
removeLast() Usuwa element z końca listy
getFirst() Pobierz element z początku listy
getLast() Pobiera element z końca listy
194
HASHMAP
195
HASHMAP
196
DODAWANIE ELEMENTÓW
// Import the HashMap class
import java.util.HashMap;
197
DOSTĘP DO ELEMENTU
// Import the HashMap class
import java.util.HashMap;
198
USUWANIE ELEMENTU
// Import the HashMap class
import java.util.HashMap;
capitalCities.remove("England");
System.out.println(capitalCities);
}
}
// Output: {USA=Washington DC, Norway=Oslo, Germany=Berlin}
199
CZYSZCZENIE HASHMAP
// Import the HashMap class
import java.util.HashMap;
capitalCities.clear();
System.out.println(capitalCities);
}
}
// Output: {}
200
ROZMIAR HASHMAP
// Import the HashMap class
import java.util.HashMap;
System.out.println(capitalCities.size());
}
}
// Output: 4
201
PĘTLA PRZEZ HASHMAP
// Print keys
for (String i : capitalCities.keySet()) {
System.out.println(i); // Output: England, Germany, Norway, USA
}
// Print values
for (String i : capitalCities.values()) {
System.out.println(i); // Output: London, Berlin, Oslo, Washington DC
}
203
HASHSET
204
HASHSET
// Import the HashSet class
import java.util.HashSet;
cars.remove("Volvo");
cars.clear();
System.out.println(cars); // Output: []
}
}
208
ROZMIAR HASHSET
// Import the HashSet class
import java.util.HashSet;
System.out.println(cars.size()); // Output 4
}
}
209
PĘTLA PRZEZ HASHSET
210
ITERATOR
211
ITERATOR
• Iterator to obiekt, który może być używany do zapętlania kolekcji,
takich jak ArrayList i HashSet. Nazywany jest „iteratorem”, ponieważ
„iterowanie” jest technicznym określeniem pętli.
213
PĘTLA Z UŻYCIEM ITERATORA
while(it.hasNext()) {
System.out.println(it.next());
}
214
CZYSZCZENIE KOLEKCJI Z UŻYCIEM
ITERATORA
ArrayList<Integer> numbers = new ArrayList<Integer>();
numbers.add(12);
numbers.add(8);
numbers.add(2);
numbers.add(23);
Iterator<Integer> it = numbers.iterator();
while(it.hasNext()) {
Integer i = it.next();
if(i < 10) {
it.remove();
}
}
System.out.println(numbers); // Output: [12, 23]
215
WRAPPER CLASSES
216
WRAPPER CLASSES
217
WRAPPER CLASSES
Typ prymitywny Wrapper Class
byte Byte
short Short
int Integer
long Long
oat Float
double Double
boolean Boolean
char Char
218
fl
PO CO?
import java.util.ArrayList;
219
TWORZENIE WRAPPER OBJECTS
import java.util.ArrayList;
222
OBSŁUGA BŁĘDÓW
223
TRY…CATCH
try {
// Block of code to try
}
catch(Exception e) {
// Block of code to handle errors
}
224
TRY…CATCH
225
TRY…CATCH
public class Main {
public static void main(String[ ] args) {
try {
int[] myNumbers = {1, 2, 3};
System.out.println(myNumbers[10]);
} catch (Exception e) {
System.out.println("Something went wrong.");
}
}
}
228
THROW
public class Main {
static void checkAge(int age) {
if (age < 18) {
throw new ArithmeticException("Access denied - You must be at least 18 years
old.");
}
else {
System.out.println("Access granted - You are old enough!");
}
}
229
WYRAŻENIA REGULARNE
230
CO TO JEST WYRAŻENIE REGULARNE?
• Wyrażenie regularne to ciąg znaków, który tworzy wzorzec wyszukiwania.
Podczas wyszukiwania danych w tekście można użyć tego wzorca
wyszukiwania, aby opisać to, czego szukasz.
235
WĄTKI
236
TWORZENIE WĄTKU
237
TWORZENIE WĄTKU
238
URUCHAMIANIE WĄTKU
239
URUCHAMIANIE WĄTKU
public class Main implements Runnable {
public static void main(String[] args) {
Main obj = new Main();
Thread thread = new Thread(obj);
thread.start();
System.out.println("This code is outside of the thread");
}
public void run() {
System.out.println("This code is running in a thread");
}
}
240
RÓŻNICE MIĘDZY „ROZSZERZANIEM” I
„IMPLEMENTOWANIEM” WĄTKÓW
241
PROBLEMY ZE WSPÓŁBIEŻNOŚCIĄ
• Ponieważ wątki działają w tym samym czasie, co inne części programu, nie ma sposobu,
aby dowiedzieć się, w jakiej kolejności kod zostanie uruchomiony. Gdy wątki i program
główny odczytują i zapisują te same zmienne, ich wartości są nieprzewidywalne.
Wynikające z tego problemy nazywane są problemami współbieżności.
242
PROBLEMY ZE WSPÓŁBIEŻNOŚCIĄ
public class Main extends Thread {
public static int amount = 0;
244
LAMBDA
245
WYRAŻENIA LAMBDA
• Wyrażenia lambda zostały dodane w Javie 8.
249
ZAPIS LAMBDY DO ZMIENNEJ
import java.util.ArrayList;
import java.util.function.Consumer;
// Output: 5 9 8 1
250
ZAPIS LAMBDY DO ZMIENNEJ
251
ZAPIS LAMBDY DO ZMIENNEJ
interface StringFunction {
String run(String str);
}
// Output:
// Hello!
// Hello?
252
WPROWADZENIE DO ANDROID
STUDIO
253
INSTALACJA ŚRODOWISKA ANDROID
STUDIO
254
WYMAGANIA SYSTEMOWE - WINDOWS
Parameter Minimalne Zalecane
255
INSTALACJA - WINDOWS
• Aby zainstalować Android Studio w systemie Windows, wykonaj te czynności:
• Jeśli masz pobrany plik .exe (zalecane), kliknij dwukrotnie aby ją uruchomić.
• Uruchom studio64.exe (w przypadku systemów 64-bitowych) lub studio.exe (w wersji 32-bitowej) komputery).
• Postępuj zgodnie z kreatorem kon guracji w Android Studio i zainstaluj zalecane rozwiązania. Pakiety SDK.
256
fi
INSTALACJA - WINDOWS
257
WYMAGANIA SYSTEMOWE - MACOS
Parameter Minimalne Zalecane
Procesor Apple M1 lub Intel Core 2 generacji bądź nowszy z Najnowszy układ krzemowy
Procesor
obsługą Hypervisor Platform Apple
258
INSTALACJA - MACOS
• Aby zainstalować Android Studio na Macu, wykonaj te czynności:
260
WYMAGANIA SYSTEMOWE - LINUX
Parameter Minimalne Zalecane
dowolna 64-bitowa dystrybucja Linuksa, która obsługuje środowiska Najnowsza 64-bitowa wersja
System operacyjny Gnome, KDE lub Unity DE; GNU C Library (glibc) w wersji 2.31 lub Linuksa
nowszej.
261
INSTALACJA - LINUX
• Aby zainstalować Android Studio w Linuksie, wykonaj te czynności:
• Rozpakuj pobrany plik .tar.gz do odpowiednie miejsce dla Twoich aplikacji, na przykład w /usr/local/ w
Twoim pro lu użytkownika lub na /opt/ użytkowników, którym udostępniono treści.W 64-bitowej
wersji Linuksa najpierw zainstaluj biblioteki wymagane dla komputerów 64-bitowych,
• Wykonaj kreator kon guracji Android Studio, co obejmuje pobranie Komponenty Android SDK
wymagane do programowania.
262
fi
fi
BIBLIOTEKI WYMAGANE W PRZYPADKU
MASZYN 64-BITOWYCH - LINUX
• Jeśli używasz 64-bitowej wersji Ubuntu, musisz zainstalować kilka 32-
bitowych za pomocą tego polecenia:
264
INTERFEJS ANDROID STUDIO
265
INTERFEJS ANDROID STUDIO
266
EDYTOR KODU
Uruchomienie
aktywności
Edycja UI
Kod źródłowy
267
WIDOK PROJEKTU - ANDROID
Kod Java/Kotlin
Elementy UI
Prede niowane stałe
(teksty, kolory, itp.)
Motywy
268
fi
WIDOK PROJEKTU - STRUKTURA
PLIKÓW
269
PASEK GÓRNY - LEWA STRONA
Wybór projektu
Narzędzia GIT
270
PASEK GÓRNY - PRAWA STRONA
Uruchomienie Budowanie
Wybrany emulator
projektu
271
fi
MENADŻER URZĄDZEŃ
272
AKTYWNY EMULATOR
273
TWORZENIE PIERWSZEGO PROJEKTU
274
EKRAN STARTOWY ANDROID STUDIO
Tworzenie
nowego
projektu
275
WYBÓR SZABLONU
Aktualnie Empty
Activity = Kotlin +
Jetpack Compose
276
SZCZEGÓŁY PROJEKTU
Nazwa aplikacji
Lokalizacja na
Nazwa pakietu dysku
Język
programowania Minimalne
(Java/Kotlin) Android SDK
Kon guracja
Zakończenie
budowania
kon guracji
277
fi
fi
MINIMALNE ANDROID SDK
278
KONFIGURACJA EMULATORA AVD
(Android Virtual Device)
279
DODANIE NOWEGO EMULATORA
Dodawanie urządzenia
280
WYBÓR URZĄDZENIA
281
WYBÓR WERSJI SYSTEMU OPERACYJNEGO
Pobieranie obrazu SO
282
SPRAWDZENIE KONFIGURACJI
283
URUCHAMIANIE EMULATORA
Uruchamianie
284
URUCHOMIONY EMULATOR
285
PODSTAWY TWORZENIA INTERFEJSU
UŻYTKOWNIKA
286
EDYTOR UKŁADÓW
287
EDYTOR UKŁADÓW
3
5
2
288
1. PALETA
289
2. DRZEWO KOMPONENTÓW
290
3. PASEK NARZĘDZIOWY
291
4. EDYTOR
292
5. WŁAŚCIWOŚCI
293
PRZEŁĄCZNIK TRYBÓW WIDOKU
294
WIDOK XML
295
WIDOK SPLIT (XML + DESIGN)
296
PASEK NARZĘDZIOWY - PRZYCISKI
1 2 3 4 5 6
297
1. TRYB WIDOKU
• Tryb widoku — określa, w jaki sposób
pokazywany jest nasz układ.
299
3. TYP URZĄDZENIA ORAZ ROZMIAR
• Typ urządzenia oraz rozmiar — pozwala na
wybranie typu urządzenia (np. telefonu, tabletu,
telewizora) oraz jego rozmiaru wraz z gęstością
pikseli.
300
fi
4. WERSJA API
301
5. TEMAT APLIKACJI (THEME)
302
6. JĘZYK APLIKACJI
303
PRACA Z UKŁADAMI
304
PRACA Z UKŁADAMI
305
UKŁADY DOSTĘPNE W OKNIE PALETY
• Do dyspozycji mamy pięć
podstawowych układów (pozycja
TableRow nie jest układem, ale
wierszem w układzie tabelarycznym,
zaś Space to lekka podklasa widoku,
która może być używana do tworzenia
przerw między komponentami w
układach ogólnego przeznaczenia.)
306
UKŁADY DOSTĘPNE W OKNIE PALETY
• ConstraintLayout — pozwala na tworzenie złożonych układów o płaskiej
strukturze, czyli bez zagnieżdżania w nim innych układów;
307
UKŁADY DOSTĘPNE LEGACY
• GridLayout — układ siatki podzielony
niewidocznymi liniami na wiersze i kolumny
tworzące komórki (ang. cells), w których
możemy umieszczać komponenty;
309
LINEAR LAYOUT (HORIZONTAL)
310
STRUKTURA PLIKU XML
• W pierwszej linii de niujemy wersję XML-a (wersja 1.0) oraz sposób
kodowania znaków (kodowanie UTF-8).
312
fi
fi
fi
fi
fi
LINEAR LAYOUT (VERTICAL)
313
LINEAR LAYOUT (VERTICAL)
<?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">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Button" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Button" />
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Button" />
<Button
android:id="@+id/button4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Button" />
<Button
android:id="@+id/button5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Button" />
</LinearLayout>
314
ANDROID:ID
<Button • android:id to jednoznaczny identy kator
android:id="@+id/
button" komponentu, przez który będziemy się do
niego odwoływać w kodzie programu. Znak @
android:layout_width="wrap_ oznacza odwołanie do pliku zasobów (ang.
content"
resources). Natomiast znak + oznacza, że
android:layout_height="wrap chcemy dodać identy kator właśnie w tym
_content" miejscu. Tych dwóch znaków (@,+) używamy
tylko raz w momencie de niowania
android:layout_weight="1"
android:text="Button" / identy katora. Natomiast odwołanie do niego
> realizujemy za pomocą samego znaku @.
315
fi
fi
fi
fi
OSTRZEŻENIA DOTYCZĄCE LAYOUTU
316
BUTTON SHOULD BE BORDERLESS
317
BUTTON SHOULD BE BORDERLESS
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/
android"
android:layout_width="match_parent"
android:layout_height="match_parent"
style="?android:attr/buttonBarStyle"> <!-- 1 -->
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Button"
style="?android:attr/buttonBarButtonStyle" /> <!-- 2 -->
318
BUTTON SHOULD BE BORDERLESS
• Linia oznaczona cyfrą 1 dodaje styl do układu. Natomiast linia oznaczona
cyfrą 2 dodaje odpowiedni styl do przycisku. Ten wpis powinien być
wprowadzony do każdego przycisku.
320
HARDCODED TEXT
• Ostrzeżenie to informuje nas, że nasz napis (ang. string) jest zapisany bezpośrednio w pliku XML
naszej aktywności (activity_main.xml), a powinien być zapisany w pliku zasobów.
• To istotna uwaga i warto się do niej zastosować. Jeżeli tekst wyświetlany użytkownikowi zapiszemy w
pliku zasobów (strings.xml), to będziemy mieli pewien logiczny układ, którym łatwiej zarządzać. Na
przykład kiedy dany tekst jest wyświetlany w kilku różnych miejscach, wystarczy nam jeden zasób. W
takiej sytuacji zmiana napisu będzie wymagała zmiany tylko w jednej lokalizacji (w pliku zasobów).
• Poza tym jeżeli będziemy chcieli naszą aplikację dystrybuować w kilku językach, to powinniśmy wpisy
umieszczać w pliku strings.xml. Dzięki temu w łatwy sposób przygotujemy napisy lokalizacyjne w
innych językach.
321
DEFINIOWANIE ZASOBU TEKSTOWEGO -
TRYB GRAFICZNY
322
DEFINIOWANIE ZASOBU TEKSTOWEGO -
TRYB GRAFICZNY
323
DEFINIOWANIE ZASOBU TEKSTOWEGO -
TRYB GRAFICZNY
324
DEFINIOWANIE ZASOBU TEKSTOWEGO -
TRYB GRAFICZNY
325
DEFINIOWANIE ZASOBU TEKSTOWEGO -
TRYB EXTRACT
326
DEFINIOWANIE ZASOBU TEKSTOWEGO -
TRYB EXTRACT
327
ZAWARTOŚĆ PLIKU STRINGS.XML
<resources>
<string name="app_name">My Application</string>
<string name="button_1_text">Button 1</string>
<string name="button_2_text">Button 2</string>
</resources>
328
LINEAR LAYOUT (VERTICAL)
329
LINEAR LAYOUT (VERTICAL)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/
android"
android:layout_width="match_parent"
android:layout_height="match_parent"
style="?android:attr/buttonBarStyle"
android:orientation="vertical"> <!-- Orientacja układu -->
330
LINEAR LAYOUT (VERTICAL)
331
SZEROKOŚĆ PRZYCISKÓW
<Button
android:id="@+id/button"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/button_1_text" />
333
SZEROKOŚĆ PRZYCISKÓW
334
LAYOUT_WEIGHT
• Mamy jeszcze kilka innych opcji, które służą do określania rozmiaru komponentów. Zwróćmy
uwagę na brak wolnej przestrzeni na poprzednim zrzucie ekranu. Tą przestrzenią możemy
rozdysponować pomiędzy naszymi komponentami za pomocą atrybutu
android:layout_weight. Domyślnie (bez ustawiania tej wartości) każdy komponent
przyjmuje wartość tego atrybutu równą 0. Oznacza to, że nie jest mu udostępniana żadna
dodatkowa przestrzeń. Jeżeli zmienimy tę wartość na inną, różną od 0, to zajmie on całą
dostępną przestrzeń. Co się natomiast stanie w sytuacji, kiedy kilka komponentów będzie chciało
skorzystać z tej wartości? Z pomocą przychodzi nam odpowiedni wzór:
• sip (Scale-independent Pixels) lub sp — oznacza to samo co dp, z tym że odnosi się do tekstów, czyli bierze pod uwagę
ustawienia rozmiaru tekstów zde niowane w systemie przez użytkownika.
337
fi
fi
fi
fi
WŁASNY ROZMIAR KOMPONENTÓW
• Podsumowując, rekomendowane opcje to dp do rozmiarów
komponentów oraz sp do rozmiarów tekstów. Na koniec
omawiania jednostek podajmy jeszcze wzór, który pozwoli nam na
obliczenie rzeczywistej liczby pikseli zajmowanych przez dany element
(którego wielkość podawana jest w jednostce dp).
340
LAYOUT_GRAVITY
341
LAYOUT_GRAVITY
• Opisy opcji left i start są do siebie bardzo podobne (tak jak right i
end). Których powinniśmy używać?
• android:layout_weight — określa wagowy przydział dodatkowej przestrzeni dostępnej dla danego komponentu;
343
INNE WŁAŚCIWOŚCI WSPÓLNE DLA
KOMPONENTÓW WIZUALNYCH
• android:layout_marginTop — określa ilość dodatkowego wolnego miejsca od góry,
344
TABLE LAYOUT
345
TABLE LAYOUT
346
fi
TABLE LAYOUT
347
PRZYKŁAD WYKORZYSTANIA TABLE
LAYOUT
348
PRZYKŁAD WYKORZYSTANIA TABLE
LAYOUT - XML
349
PRZYKŁAD WYKORZYSTANIA TABLE
LAYOUT - XML
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="0"
android:text="@string/username" />
<EditText
android:id="@+id/editTextText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="1"
android:ems="10"
android:inputType="text" />
</TableRow>
350
PRZYKŁAD WYKORZYSTANIA TABLE
LAYOUT - XML
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="0"
android:text="@string/password" />
<EditText
android:id="@+id/editTextTextPassword"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textPassword" />
</TableRow>
351
PRZYKŁAD WYKORZYSTANIA TABLE
LAYOUT - XML
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent" >
<CheckBox
android:id="@+id/checkBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="1"
android:text="@string/remember_me" />
</TableRow>
352
PRZYKŁAD WYKORZYSTANIA TABLE
LAYOUT - XML
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:id="@+id/button7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/sign_in" />
</TableRow>
</TableLayout>
353
FRAME LAYOUT
354
FRAME LAYOUT
355
FRAME LAYOUT
356
FRAME LAYOUT - PRZYKŁAD UŻYCIA
357
FRAME LAYOUT - PRZYKŁAD UŻYCIA
(XML)
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="@string/todo"
tools:src="@tools:sample/backgrounds/scenic" />
<TextView
android:id="@+id/textView3"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textSize="50sp"
android:textColor="@color/red"
android:textStyle="bold"
android:text="@string/textview" />
</FrameLayout>
358
RELATIVE LAYOUT
359
RELATIVE LAYOUT
• Tak jak już mówiliśmy, wartości różnych atrybutów typu left są tożsame z wartościami
atrybutów typu start tylko w odniesieniu do tekstów pisanych od lewej
do prawej (czyli tak jak w języku polskim i innych językach zapisywanych alfabetem
łacińskim). Natomiast w przypadku języków, w których teksty pisane są od prawej do
lewej (np. języku arabskim czy hebrajskim), musimy zamiast atrybutu typu left użyć
atrybutu typu start. To samo dotyczy pary atrybutów typu right oraz end.
363
ATRYBUTY ODPOWIEDZIALNE ZA
POŁOŻENIE WZGLĘDEM RODZICA
364
RELATIVE LAYOUT
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 1"
android:id="@+id/button"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true" /> <!-- 1 -->
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 2"
android:id="@+id/button2"
android:layout_centerInParent="true" /> <!-- 2 -->
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 3"
android:id="@+id/button3"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true" /> <!-- 3 -->
</RelativeLayout>
365
RELATIVE LAYOUT
366
ATRYBUTY ODPOWIEDZIALNE ZA
POŁOŻENIE WZGLĘDEM SIEBIE
• android:layout_above — ustawia dolną krawędź komponentu powyżej wskazanego
komponentu,
370
GRID LAYOUT
• Układ GridLayout jest bardzo dobrze zintegrowany z edytorem gra cznym, dzięki
czemu w łatwy sposób można z niego korzystać.
371
fi
GRID LAYOUT
372
GRID LAYOUT - PRZYKŁAD
373
GRID LAYOUT - PRZYKŁAD (XML)
<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1"
android:id="@+id/button"
android:layout_row="0"
android:layout_column="0" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="2"
android:id="@+id/button2"
android:layout_row="0"
android:layout_column="1" />
374
GRID LAYOUT - PRZYKŁAD (XML)
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="3"
android:id="@+id/button3"
android:layout_row="0"
android:layout_column="2"
android:layout_rowSpan="2"
android:layout_gravity="center_vertical" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="4"
android:id="@+id/button4"
android:layout_row="1"
android:layout_column="0"
android:layout_columnSpan="2"
android:layout_gravity="center_horizontal" />
</GridLayout>
375
ZAGNIEŻDŻANIE UKŁADÓW
376
ZAGNIEŻDŻANIE UKŁADÓW
377
ZAGNIEŻDŻANIE UKŁADÓW
• W pliku XML umieszczamy układ RelativeLayout, który będzie układem głównym.
Ustawiamy w nim atrybut android:gravity na wartość center_horizontal.
Dzięki temu pozostałe układy, które będą w nim zagnieżdżone, będą wyświetlane w
pozycji wyśrodkowywanej poziomo. Następnie w układzie RelativeLayout
umieszczamy układ TableLayout, a w nim cztery komponenty CheckBox. Po czym
dodajemy poniżej układ LinearLayout, a w nim dwa przyciski. Żeby zrobić nieco
odstępu pomiędzy układami (TableLayout i LinearLayout), użyliśmy atrybutów
android:layout_marginTop oraz android:layout_marginBottom.
De niujemy je w układzie TableLayout: pierwszy z wartością 10dp, a drugi 5dp.
378
fi
ZAGNIEŻDŻANIE UKŁADÓW
379
ZAGNIEŻDŻANIE UKŁADÓW (XML)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal">
<TableLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tableLayout"
android:layout_marginTop="10dp"
android:layout_marginBottom="5dp">
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
380
ZAGNIEŻDŻANIE UKŁADÓW (XML)
<CheckBox
android:text="Opcja 1"
android:id="@+id/checkBox"
android:layout_column="0"
android:checked="false" />
<CheckBox
android:text="Opcja 2"
android:id="@+id/checkBox2"
android:layout_column="1"
android:checked="false" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
<CheckBox
android:text="Opcja 3"
android:id="@+id/checkBox3"
android:layout_column="0"
android:checked="false" />
<CheckBox
android:text="Opcja 4"
android:id="@+id/checkBox4"
android:layout_column="1"
android:checked="false" />
</TableRow>
381
ZAGNIEŻDŻANIE UKŁADÓW (XML)
</TableLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/tableLayout">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="OK"
android:id="@+id/button" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Anuluj"
android:id="@+id/button2" />
</LinearLayout>
</RelativeLayout>
382
KOMPONENT SCROLLVIEW
383
KOMPONENT SCROLLVIEW
• Komponent ScrollView jest kontenerem dla innych układów pozwalającym na przewijanie
ich zawartości, który przydaje się w sytuacji, kiedy rozmiar układu przekracza zyczną wielkość
naszego ekranu.
fi
KOMPONENT SCROLLVIEW
• Nie powinniśmy go używać z komponentem ListView, który ma już własny
mechanizm przewijania zoptymalizowany pod kątem pracy z dużymi listami.
386
KOMPONENT SCROLLVIEW
387
KOMPONENT SCROLLVIEW
388
KOMPONENTY INTERFEJSU
UŻYTKOWNIKA
389
KOMPONENTY INTERFEJSU
UŻYTKOWNIKA
• Komponenty są bardzo istotnym elementem interfejsu użytkownika. To za ich pomocą
komunikuje się on z aplikacją, a aplikacja prezentuje mu informacje zwrotne.
391
KATEGORIA BUTTONS
392
KATEGORIA WIDGETS
393
KATEGORIA CONTAINERS
394
KATEGORIA HELPERS
395
KATEGORIA GOOGLE
396
KATEGORIA LEGACY
397
STYLE I TEMATY
398
STYLE
399
fi
STYLE
400
STYLE
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="tekst1"
android:textColor="#434230"
android:background="#c6ecc6"
android:typeface="serif"
android:textSize="15sp"
android:textStyle="bold"
android:padding="10dp"
/>
401
STYLE
• Możemy to zrobić w sposób przedstawiony na poprzednim slajdzie i wszystko będzie
działać oraz wyglądać poprawnie. Jeśli jednak będziemy chcieli umieścić inne kontrolki
wykorzystujące takie same atrybuty, będziemy musieli je powielić w każdej z
kontrolek.
402
STYLE
• Jak się niedługo dowiemy, aplikacja może składać się z kilku plików XML, więc
przeglądanie ich wszystkich i szukanie kontrolek, które wymagają mody kacji,
okaże się bardzo czasochłonnym zadaniem.
• Stąd też w systemie Android mamy możliwość de niowania stylów. Dzięki nim w
jednym miejscu określimy wszystkie wymagane atrybuty, z których będą korzystały
nasze kontrolki. Jeżeli zaistnieje potrzeba dokonania jakiejś zmiany, to wystarczy
wprowadzić ją w jednym pliku (tam, gdzie zde niowaliśmy dany styl). Kod kontrolki
TextView wykorzystującej style będzie wyglądał jak na kolejnym slajdzie.
403
fi
fi
fi
STYLE
<TextView
android:id="@+id/textView1"
style="@style/MyStyle"
android:text="tekst"
/>
404
STYLE
<resources>
<style name="MyStyle">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:textColor">#434230</item>
<item name="android:background">#c6ecc6</item>
<item name="android:typeface">serif</item>
<item name="android:textSize">15sp</item>
<item name="android:textStyle">bold</item>
<item name="android:padding">10dp</item>
</style>
</resources>
405
STYLE - WYJAŚNIENIE WŁAŚCIWOŚCI
• android:textColor — kolor tekstu,
• serif — czcionkę szeryfową (z ozdobnikami w postaci poprzecznie lub ukośnie zakończonych głównych
kresek liter danego kroju pisma),
407
DZIEDZICZENIE STYLÓW
408
fi
fi
fi
DZIEDZICZENIE STYLÓW
• Tworząc nowy styl, nie musimy od nowa de niować wszystkich atrybutów, może
skorzystać ze stylu zde niowanego wcześniej i dodać do niego tylko nowe elementy.
• Dodatkowo będziemy mieli spójną i przejrzystą hierarchię stylów, która ułatwi nam
pisanie kodu i wprowadzanie wszelkich mody kacji.
• Style, które będziemy tworzyć, mogą dziedziczyć po naszych własnych stylach (wcześniej
już zde niowanych) lub też po stylach zde niowanych w pakiecie Android SDK.
409
fi
fi
fi
fi
fi
DZIEDZICZENIE STYLÓW
<style name="MyStyle">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:textColor">#434230</item>
<item name="android:background">#c6ecc6</item>
<item name="android:typeface">serif</item>
<item name="android:textSize">15sp</item>
<item name="android:textStyle">bold</item>
<item name="android:padding">10dp</item>
</style>
<style name="MyStyle.BlueCursive">
<item name="android:textColor">#0000ff</item>
<item name="android:textStyle">italic</item>
</style>
410
DZIEDZICZENIE STYLÓW
<style name="MyStyle.BlueCursive.Small">
<item name="android:textSize">10sp</item>
</style>
411
KORZYSTANIE Z DZIEDZICZĄCEGO
STYLU
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/MyStyle.BlueCursive.Small"
android:text="tekst2"
/>
412
DZIEDZICZENIE STYLÓW - UŻYCIE
„PARENT”
<style name="MyStyle">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:textColor">#434230</item>
<item name="android:background">#c6ecc6</item>
<item name="android:typeface">serif</item>
<item name="android:textSize">15sp</item>
<item name="android:textStyle">bold</item>
<item name="android:padding">10dp</item>
</style>
<style name="BlueCursive" parent="MyStyle">
<item name="android:textColor">#0000ff</item>
<item name="android:textStyle">italic</item>
</style>
<style name="Small" parent="BlueCursive">
<item name="android:textSize">10sp</item>
</style>
413
DZIEDZICZENIE STYLÓW - UŻYCIE
„PARENT”
414
STYLE
• Kiedy poznaliśmy już metody tworzenia stylów oraz mechanizm dziedziczenia, pojawia
się pytanie, skąd mamy wiedzieć, jakie atrybuty możemy w danym stylu zde niować?
• Jeżeli jednak zdarzy nam się, że w de nicji naszego stylu użyliśmy atrybutu, którego dana
kontrolka nie obsługuje, to ten atrybut zostanie po prostu zignorowany.
415
fi
fi
STYLE
• Istnieją jednak takie atrybuty stylów, które nie są obsługiwane przez żadną kontrolkę i
mogą być stosowane tylko do tematów (ang. themes). Właściwości te dotyczą całego
okna aplikacji, a nie żadnej konkretnej kontrolki. Przykładem tego typu właściwości są
m.in.: ukrywanie tytułu aplikacji, ukrywanie pasku stanu i zmiana tła okna.
fi
TEMATY
417
TEMATY
418
fi
PRZYKŁAD TEMATU
419
PRZYKŁAD TEMATU
• Zwróćmy uwagę na nazwę naszego tematu oraz na temat bazowy.
• Drugi atrybut to android:colorBackground, który już poznaliśmy, ustawia on tło naszej aplikacji.
Oczywiście w pliku colors.xml należy wcześniej zde niować wartość koloru o nazwie green.
420
fi
fi
GDZIE SZUKAĆ JAKI TEMAT JEST
USTAWIONY?
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.MyApplication"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</manifest>
421
OBRAZY TYPU NINE-PATCH
• Obrazy typu nine-patch (ang. dziewięć łatek) są specjalnymi,
rozciągalnymi bitmapami, które system Android potra w ładny
sposób wyświetlać.
fi
OBRAZY TYPU NINE-PATCH
423
OBRAZY TYPU NINE-PATCH
• Obszary narożne, oznaczone cyfrą 1, nie są skalowane, co oznacza, że zawsze wyglądają
tak samo. Obszary oznaczone cyfrą 2 mogą być skalowane tylko w poziomie, a obszary
oznaczone cyfrą 3 tylko w pionie. Obszar środkowy, oznaczony cyfrą 4, jest skalowany
zarówno w pionie, jak i poziomie. Podsumowując, w obszarach oznaczonych cyfrą 1
umieszczamy elementy, które nie powinny być skalowane, żeby zawsze wyglądać tak
samo (np. zaokrąglone narożniki przycisku lub małe ikony). Natomiast w obszarze 4
możemy umieszczać elementy, które wyglądają dobrze w każdym rozmiarze (np.
jednolity kolor). W obszarach oznaczonych cyframi 2 i 3 umieszczamy takie elementy,
które dobrze się skalują w jednym wymiarze (poziomo lub pionowo).
424
OBRAZY TYPU NINE-PATCH
• Technicznie plik obrazu, który wykorzystuje technologię nine-patch,
różni się od zwykłego obrazu tylko dwoma rzeczami. Pierwsza to
nazwa pliku, która ma postać <nazwa obrazka>.9.png (zwykła
nazwa pliku to <nazwa obrazka>.png), druga to ramka
otaczająca nasz obraz o szerokości 1 piksela.
426
OBRAZY TYPU NINE-PATCH
• Dokumentacja: https://developer.android.com/studio/write/
draw9patch
427
SELEKTORY
• Selektory (ang. selectors) to prosta, ale bardzo użyteczna konstrukcja pozwalająca
dostosować wygląd komponentu w zależności od stanu, w jakim się znajduje.
fi
SELEKTORY
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/
android">
<item android:state_pressed="true">
<color android:color="#FF0000" /> <!-- pressed -->
</item>
<item android:state_focused="true">
<color android:color="#00FF00" /> <!-- focused -->
</item>
<item>
<color android:color="#0000FF" /> <!-- default -->
</item>
</selector>
429
SELEKTORY
430
SELEKTORY
431
SELEKTORY
432
SELEKTORY
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/
android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/main">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Przycisk"
android:id="@+id/button"
android:background="@drawable/my_button" />
</LinearLayout>
433
SELEKTORY
434
SELEKTORY
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="MyApplication" parent="Theme.AppCompat">>
<item name="android:colorBackground">@color/white</item>
</style>
</resources>
435
SELEKTORY
436
DOSTĘPNE STANY DLA SELEKTORÓW
• android:state_pressed — kontrolka jest wciśnięta,
• android:state_activated — kontrolka (np. Checkbox) lub jej rodzic zmienili swój stan na zaznaczony,
438
fi
KSZTAŁTY
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape=["rectangle" | "oval" | "line" | "ring"] >
<corners
android:radius="integer"
android:topLeftRadius="integer"
android:topRightRadius="integer"
android:bottomLeftRadius="integer"
android:bottomRightRadius="integer" />
<gradient
android:angle="integer"
android:centerX="float"
android:centerY="float"
android:centerColor="integer"
android:endColor="color"
android:gradientRadius="integer"
android:startColor="color"
android:type=["linear" | "radial" | "sweep"]
android:useLevel=["true" | "false"] />
<padding
android:left="integer"
android:top="integer"
android:right="integer"
android:bottom="integer" />
<size
android:width="integer"
android:height="integer" />
<solid
android:color="color" />
<stroke
android:width="integer"
android:color="color"
android:dashWidth="integer"
android:dashGap="integer" />
</shape>
439
KSZTAŁTY
• Opiszmy teraz po kolei wszystkie dostępne opcje. Pierwszy istotny element w znaczniku
<shape> to atrybut android:shape. Jak widzimy, może on przyjąć cztery wartości:
• line — linia biegnąca poziomo przez środek kontrolki; wartość ta wymaga znacznika
<stroke> do zde niowania szerokości linii;
• android:innerRadius — promień wewnętrznej części pierścienia (środek pierścienia pokrywa się ze środkiem kontrolki).
• android:innerRadiusRatio — promień wewnętrznej części pierścienia wyrażony jako stosunek szerokości pierścienia. Na
przykład jeżeli ustawimy android:innerRadiusRatio="7", to promień będzie równy szerokości pierścienia podzielonej przez 7.
Wartość ta jest nadpisywana przez android:innerRadius.
• android:thicknessRatio — grubość pierścienia wyrażona jako stosunek szerokości pierścienia. Na przykład jeżeli
android:thicknessRatio="2", wtedy grubość pierścienia równa jest szerokości pierścienia podzielonej przez 2.
• android:useLevel — ustawiamy wartość true, jeżeli pierścień jest używany jako LevelListDrawable (zasób, który zarządza
grupą obiektów gra cznych). We wszystkich innych sytuacjach powinniśmy ustawić tę wartość jako false, inaczej nasz pierścień
się nie pojawi!
441
fi
KSZTAŁTY
• Kolejny przydatny znacznik to <corners>. Dzięki niemu możemy tworzyć prostokąty z zaokrąglonymi rogami.
Stąd też występuje tylko z kształtem o wartości rectangle (pol. prostokąt). Atrybuty, które możemy wraz z nim
wykorzystać, to:
• android:radius — promień dla wszystkich narożników wartość ta jest nadpisywana przez szczegółowe
ustawienia poszczególnych z nich;
• android:angle — kąt określający kierunek przejścia tonalnego. Wartość 0 (domyślna) oznacza kierunek od lewej do
prawej, zaś 90 kierunek z dołu do góry, przy czym każda przypisana wartość musi być wielokrotnością liczby 45.
• android:centerX — względna współrzędna X wyznaczająca środek gradientu. Wartość ta musi mieścić się w
przedziale [0, 1].
• android:centerY — względna współrzędna Y wyznaczająca środek gradientu. Wartość ta musi mieścić się w
przedziale [0, 1].
• android:centerColor — opcjonalny kolor, który jest kolorem pośrednim pomiędzy początkowym a końcowym.
• radial — gradient promieniowy (radialny), kolor początkowy znajduje się w środku okręgu;
• android:useLevel — ustawiamy wartość true, jeżeli gradient używany jest jako LevelListDrawable (zasób, który
zarządza grupą obiektów gra cznych). We wszystkich innych sytuacjach powinniśmy użyć wartości false.
444
fi
KSZTAŁTY
• Kolejny atrybut to <padding>, czyli margines wewnętrzny. Wyznacza on pozycję
zawartości kontrolki (np. tekstu na przycisku), a nie pozycję kształtu. Atrybuty dostępne
wraz ze znacznikiem <padding> to:
• Ostatni z omawianych znaczników to <stroke>, który rysuje ramkę otaczającą kontrolkę. Do dyspozycji mamy cztery
atrybuty:
• android:dashGap — odległość pomiędzy kreskami (w ramce rysowanej linią przerywaną) wykorzystywaną wraz z
atrybutem android:dashWidth,
• android: dashWidth — długość kresek (w ramce rysowanej linią przerywaną) wykorzystywaną wraz z atrybutem
dashGap.
447
PRZYKŁAD
448
PRZYKŁAD
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="StylPrzycisku">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:textColor">#ffffff</item>
<item name="android:gravity">center</item>
<item name="android:layout_margin">10dp</item>
<item name="android:textSize">25sp</item>
<item name="android:textStyle">bold</item>
<item name="android:shadowColor">#0a0a0a</item>
<item name="android:shadowDx">-2</item>
<item name="android:shadowDy">-2</item>
<item name="android:shadowRadius">1</item>
</style>
</resources>
449
PRZYKŁAD
• Opiszmy pokrótce wykorzystane przez nas atrybuty:
• android:shadowDy (o wartości -2) — określa pozycję cienia w kierunku pionowym, wartość ujemna
oznacza przesunięcie w górę (dodatnia w dół);
452
PRZYKŁAD
• Opiszmy pokrótce użyte przez nas atrybuty:
• <selector> — pozwala na zmianę wyglądu przycisku w zależności od stanu, w jakim się znajduje; w naszym przykładzie mamy opisane dwa
stany: atrybut android:state_pressed oznaczający przycisk wciśnięty oraz brak atrybutu w znaczniku <item> oznaczający stan domyślny
(normalny);
• <shape> — nadaje odpowiedni kształt naszemu komponentowi, a brak wartości oznacza domyślny prostokątny kształt; kolor de niujemy za
pomocą znacznika <solid> i atrybutu android:color;
• <stroke> — określa obramowanie komponentu; atrybut android:width ustawia grubość ramki, a atrybut android:color jej kolor;
• <padding> — ustawia poszczególne marginesy wewnętrzne dzięki atrybutom android:left (lewy), android:top (górny), android:right (prawy),
android:bottom (dolny);
• <gradient> — ustawia przejście tonalne pomiędzy kolorem początkowym (atrybut android:startColor) a kolorem końcowym (atrybut
android:endColor), kąt przejścia de niujemy dzięki atrybutowi android:angle.
453
fi
fi
fi
PRZYKŁAD
454
PRZYKŁAD
455
PRZYKŁAD
456
PRZYKŁAD
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/
android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/main">
<Button
android:text="OK"
style="@style/StylPrzycisku"
android:background="@drawable/gradient" />
</LinearLayout>
457
PRZYKŁAD
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="MyApplication" parent="Theme.AppCompat">>
<item name="android:colorBackground">@color/white</item>
</style>
</resources>
458
PRZYKŁAD
459
AKTYWNOŚCI I FRAGMENTY
460
AKTYWNOŚCI
461
AKTYWNOŚCI
• Aktywność (ang. activity) to jeden z najważniejszych komponentów w aplikacjach systemu
Android.
• Tak więc aplikacja najczęściej składa się z jednej bądź kilku aktywności, z których będą
korzystali użytkownicy.
• Idea ta wynika z faktu, że system Android zarządza całą dostępną pamięcią. Jeżeli
będzie jej potrzebował więcej, to może niektóre (ukryte) aktywności naszej aplikacji
usunąć z pamięci. Będzie to skutkowało tym, że jeżeli się odpowiednio to tego nie
przygotujemy, możemy utracić część istotnych danych. Dlatego też musimy dobrze
zrozumieć tę koncepcję.
463
CYKL ŻYCIA AKTYWNOŚCI
464
CYKL ŻYCIA AKTYWNOŚCI
• Na pierwszy rzut oka widzimy, że schemat jest dość skomplikowany. Postaram się
jednak wszystko dokładnie wyjaśnić. Na samej górze mamy uruchomienie
aktywności. Pierwsza metoda, która zostanie wywołana, to onCreate(). To tutaj
powinniśmy dokonać wszystkich statycznych ustawień dotyczących aktywności (np.
tworzenia kontrolek, podpinania danych do listy). W metodzie tej mamy dostępny
obiekt typu Bundle, który przechowuje poprzedni stan aktywności (jeżeli taki
wystąpił). Tutaj także możemy zakończyć aktywność za pomocą metody nish(). W
takiej sytuacji zostanie wywołana metoda onDestroy(), a cały cykl życia aktywności
zostanie pominięty (onStart(), onResume(), onPause(), onStop()).
465
fi
CYKL ŻYCIA AKTYWNOŚCI
466
CYKL ŻYCIA AKTYWNOŚCI
467
CYKL ŻYCIA AKTYWNOŚCI
• Kolejna metoda w cyklu życia aktywności to onPause(). Wywołuje się ją, kiedy inna aktywność
przykrywa naszą. Na przykład jeżeli aktywność B jest uruchomiona na przodzie aktywności A,
to zostanie dla niej wywołana metoda onPause(). Dopóki nie zakończy się działanie tej
metody, dopóty aktywność B nie zostanie uruchomiona. Stąd też nie powinniśmy w tej
metodzie wykonywać żadnych długich operacji. Metoda onPause() jest najczęściej
wykorzystywana do zapisywania danych, zatrzymywania działających animacji (czy innych
elementów nadmiernie obciążających procesor), zwalniania zasobów (szczególnie tych, które
wymagają wyłącznego dostępu, np. aparatu). Zapisywanie danych wprowadzonych przez
użytkownika jest tutaj niezwykle istotne, gdyż system może w tym stanie zakończyć istnienie
metody (ang. kill), jeżeli będzie potrzebował dodatkowych zasobów.
468
CYKL ŻYCIA AKTYWNOŚCI
469
CYKL ŻYCIA AKTYWNOŚCI
• Ostatnia metoda, jaka zostanie wywołana przed całkowitym zniszczeniem aktywności, to
onDestroy(). Może to nastąpić po wywołaniu metody nish(), albo kiedy system operacyjny
tymczasowo zniszczy aktywność, aby odzyskać pamięć. Miejmy na uwadze, że zgodnie ze
schematem metoda ta nie musi zostać wykonana.
• W sytuacji bardzo niskiego poziomu zasobów system może (po metodzie onPause())
całkowicie zakończyć działanie aplikacji. Dlatego też onDestroy()nie służy do zapisywania
danych (należy to robić w metodzie onPause()). Tutaj natomiast powinniśmy zwolnić zasoby
takie jak wątki związane z daną aktywnością, które nie są potrzebne w innych aktywnościach
naszej aplikacji. W tym przypadku nie ma obaw, że metoda nie zostanie wykonana (gdy system
zamknie aplikację), bo wraz z zamknięciem aplikacji wszystkie jej zasoby zostaną zwolnione.
470
fi
CYKL ŻYCIA AKTYWNOŚCI
471
CYKL ŻYCIA AKTYWNOŚCI
• Zwróćmy uwagę na trzy istotne pętle widoczne na schemacie:
• stan aktywny (ang. active) — aktywność jest na pierwszym planie (na górze stosu aktywności);
• stan wstrzymania (ang. pause) — aktywność straciła skupienie (ang. focus), ale jest cały czas (choćby częściowo)
widoczna, zachowuje też swój stan oraz dane wszystkich kontrolek i jest przypięta do menedżera okien (ang. window
manager), jednakże w przypadku ekstremalnie niskiego poziomu zasobów może być przez system zamknięta;
• stan zatrzymania (ang. stop) — aktywność jest całkowicie niewidoczna, ale zachowuje swój stan oraz dane
wszystkich kontrolek, może być dość często zamykana przez system w celu odzyskania wykorzystywanej przez nią pamięci;
• stan zniszczenia (ang. destroy) — aktywność może zostać zakończona przez użytkownika (np. metodą nish()) lub
przez system operacyjny, jeżeli ponownie ją uruchomimy, musi na nowo zostać utworzona i powrócić do swojego
poprzedniego stanu.
475
fi
AKTYWNOŚCI - PRZYKŁAD
package edu.zsk.myapplication;
import android.os.Bundle;
import android.util.Log;
import androidx.appcompat.app.AppCompatActivity;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(tag, "onCreate");
}
476
AKTYWNOŚCI - PRZYKŁAD
@Override
public void onStart()
{
super.onStart();
Log.d(tag, "onStart()");
}
@Override
public void onRestart()
{
super.onRestart();
Log.d(tag, "onRestart()");
}
477
AKTYWNOŚCI - PRZYKŁAD
@Override
public void onResume()
{
super.onResume();
Log.d(tag, "onResume()");
}
@Override
public void onPause()
{
super.onPause();
Log.d(tag, "onPause()");
}
478
AKTYWNOŚCI - PRZYKŁAD
@Override
public void onStop()
{
super.onStop();
Log.d(tag, "onStop()");
}
@Override
public void onDestroy()
{
super.onDestroy();
Log.d(tag, "onDestroy()");
}
479
AKTYWNOŚCI - PRZYKŁAD
480
AKTYWNOŚCI - PRZYKŁAD
481
OKNA DIALOGOWE
482
OKNA DIALOGOWE POSTĘPU
• Klasyczne okno dialogowe służy do prezentowania użytkownikowi
informacji i pozyskiwania od niego odpowiedzi. Najpierw pokażemy
jednak okna dialogowe postępu używane do wyświetlania
użytkownikowi informacji o tym, jak zajęta jest aplikacja.
import android.app.ProgressDialog;
import android.os.Bundle;
import android.view.View;
import androidx.appcompat.app.AppCompatActivity;
484
OKNA DIALOGOWE POSTĘPU
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/
android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Oblicz"
android:id="@+id/button"
android:onClick="DialogWindow" />
</LinearLayout>
485
OKNA DIALOGOWE POSTĘPU
486
OKNA DIALOGOWE POSTĘPU
public void DialogWindow(View view) {
final ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setCancelable(false);
progressDialog.setIcon(R.mipmap.ic_launcher);
progressDialog.setTitle("Pobieram dane...");
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setButton(DialogInterface.BUTTON_POSITIVE, "OK",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
Toast.makeText(getBaseContext(),"Kliknięto OK",
Toast.LENGTH_SHORT).show();
}
});
progressDialog.setButton(DialogInterface.BUTTON_NEGATIVE,
"Anuluj",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int which)
{
Toast.makeText(getBaseContext(),
"Kliknięto Anuluj",
Toast.LENGTH_SHORT).show();
}
});
progressDialog.show();
new Thread(new Runnable(){
public void run(){
for (int i=1; i<=10; i++) {
try {
Thread.sleep(1500);
progressDialog.incrementProgressBy(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
progressDialog.dismiss();
}
}).start();
}
487
OKNA DIALOGOWE POSTĘPU
public void DialogWindow(View view) {
final ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setCancelable(false);
progressDialog.setIcon(R.mipmap.ic_launcher);
progressDialog.setTitle("Pobieram dane...");
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setButton(DialogInterface.BUTTON_POSITIVE, "OK",
(dialogInterface, i) -> Toast.makeText(getBaseContext(),"Kliknięto OK",
Toast.LENGTH_SHORT).show());
progressDialog.setButton(DialogInterface.BUTTON_NEGATIVE,
"Anuluj",
(dialog, which) -> Toast.makeText(getBaseContext(),
"Kliknięto Anuluj",
Toast.LENGTH_SHORT).show());
progressDialog.show();
new Thread(() -> {
for (int i=1; i<=10; i++) {
try {
Thread.sleep(1500);
progressDialog.incrementProgressBy(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
progressDialog.dismiss();
}).start();
}
488
OKNA DIALOGOWE POSTĘPU
489
UWAGA!
Klasa ProgressDialog została zdeprecjonowana wraz z API 26 (Android 8 „Oreo”) i
nie powinniśmy jej używać. Zamiast tego powinniśmy użyć komponentu ProgressBar.
490
INFORMACYJNE OKNA DIALOGOWE
package edu.zsk.myapplication;
import android.os.Bundle;
import android.view.View;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
491
INFORMACYJNE OKNA DIALOGOWE
492
INFORMACYJNE OKNA DIALOGOWE
package edu.zsk.myapplication;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
493
INFORMACYJNE OKNA DIALOGOWE
494
INFORMACYJNE OKNA DIALOGOWE
package edu.zsk.myapplication;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
495
INFORMACYJNE OKNA DIALOGOWE
496
INTENCJE
497
INTENCJE
498
INTENCJE
• Dzielimy je na trzy podstawowe grupy pozwalające na:
• uruchomienie innej aktywności — aby uruchomić nową aktywność, przekazujemy obiekt klasy Intent do
metody startActivity(); intencja opisuje aktywność, która ma zostać uruchomiona, oraz dostarcza innych
niezbędnych do uruchomienia informacji;
• uruchomienie usługi — usługa (ang. service) to komponent, który wykonuje swoje operacje w tle (bez interfejsu
użytkownika), aby ją uruchomić (np. w celu ściągnięcia pliku), przekazujemy intencję do metody startService();
intencja opisuje usługę, która ma zostać uruchomiona, oraz dostarcza innych niezbędnych do uruchomienia informacji;
499
INTENCJE
• Aby rozpocząć pracę z intencjami i lepiej zrozumieć mechanizm ich działania, musimy opisać dwa typy
intencji:
• intencje domniemane (ang. implicit intents) — nie określają nazwy komponentu, a jedynie
deklarują akcję, którą chcemy wykonać; w tej sytuacji to system operacyjny zdecyduje, który
komponent należy wykorzystać, na przykład jeżeli chcemy pokazać użytkownikowi jego położenie na
mapie, to możemy użyć intencji domniemanej, wtedy to system operacyjny uruchomi aplikację, która
będzie w stanie to zadanie wykonać.
500
INTENCJE
• Kiedy tworzymy intencję jawną, system operacyjny (dzięki dostarczonej mu pełnej
nazwie) natychmiast uruchamia podaną aktywność czy usługę.
503
INTENCJE JAWNE
504
INTENCJE JAWNE - PRZYKŁAD 1
// MainActivity.java
package edu.zsk.myapplication;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import androidx.appcompat.app.AppCompatActivity;
505
INTENCJE JAWNE - PRZYKŁAD 1
<!-- activity_main.xml -->
<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/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Pierwsza aktywność"
android:textColor="@color/black"
android:textSize="30sp"
/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Przejdź do drugiej aktywności"
android:id="@+id/button"
android:onClick="onClick" />
</LinearLayout>
506
INTENCJE JAWNE - PRZYKŁAD 1
// SecondActivity.java
package edu.zsk.myapplication;
import android.os.Bundle;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
}
}
507
INTENCJE JAWNE - PRZYKŁAD 1
<!-- activity_second.xml -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Druga aktywność"
android:textColor="@color/black"
android:textSize="30sp"
android:gravity="center"
/>
</LinearLayout>
508
INTENCJE JAWNE - PRZYKŁAD 1
509
INTENCJE JAWNE - PRZYKŁAD 2
// MainActivity.java
package edu.zsk.myapplication;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import androidx.appcompat.app.AppCompatActivity;
510
INTENCJE JAWNE - PRZYKŁAD 2
// SecondActivity.java
package edu.zsk.myapplication;
import android.os.Bundle;
import android.widget.Toast;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
Bundle bundle = getIntent().getExtras();
if (bundle != null) {
String napis = bundle.getString("Imie");
int liczba = bundle.getInt("Wiek");
Toast.makeText(this, napis + " ma " + liczba + " lat",
Toast.LENGTH_SHORT).show();
}
}
}
511
INTENCJE JAWNE - PRZYKŁAD 2
512
INTENCJE JAWNE - PRZYKŁAD 3
// MainActivity.java
package edu.zsk.myapplication;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == myCode && resultCode == RESULT_OK) {
String imie = data.getStringExtra("imie");
Toast.makeText(this, "Witaj " + imie, Toast.LENGTH_SHORT).show();
}
super.onActivityResult(requestCode, resultCode, data);
}
}
513
INTENCJE JAWNE - PRZYKŁAD 3
<!-- activity_main.xml -->
<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/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Pierwsza aktywność"
android:textColor="@color/black"
android:textSize="30sp"
/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Przejdź do drugiej aktywności"
android:id="@+id/button"
android:onClick="onClick" />
</LinearLayout>
514
INTENCJE JAWNE - PRZYKŁAD 3
// SecondActivity.java
package edu.zsk.myapplication;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
}
515
INTENCJE JAWNE - PRZYKŁAD 3
<!-- activity_second.xml -->
<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/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Druga aktywność"
android:textColor="@color/black"
android:textSize="30sp"
android:gravity="center"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Podaj imię:"
android:textColor="@color/black"
android:id="@+id/textView"
android:textSize="20sp" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/black"
android:id="@+id/imie" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Logowanie"
android:id="@+id/button"
android:onClick="onClick"/>
</LinearLayout>
516
INTENCJE JAWNE - PRZYKŁAD 3
517
INTENCJE DOMNIEMANE
518
INTENCJE DOMNIEMANE
519
INTENCJE DOMNIEMANE - PRZYKŁAD 1
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/MyApplication"
tools:targetApi="31">
<activity
android:name=".SecondActivity"
android:exported="false"
>
<intent-filter>
<action android:name="edu.zsk.myapplication.ACTION2" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</manifest>
520
INTENCJE DOMNIEMANE - PRZYKŁAD 1
// MainActivity.java
package edu.zsk.myapplication;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import androidx.appcompat.app.AppCompatActivity;
521
INTENCJE DOMNIEMANE - PRZYKŁAD 1
// SecondActivity.java
package edu.zsk.myapplication;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
}
}
522
INTENCJE DOMNIEMANE - PRZYKŁAD 1
523
INTENCJE DOMNIEMANE - PRZYKŁAD 2
<activity
android:name=".ThirdActivity"
android:exported="false">
<intent-filter>
<action android:name="edu.zsk.myapplication.ACTION2" />
524
INTENCJE DOMNIEMANE - PRZYKŁAD 2
// MainActivity.java
package edu.zsk.myapplication;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import androidx.appcompat.app.AppCompatActivity;
525
INTENCJE DOMNIEMANE - PRZYKŁAD 2
<!-- activity_main.xml -->
<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/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Pierwsza aktywność"
android:textColor="@color/black"
android:textSize="30sp"
/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Przejdź do innej aktywności"
android:id="@+id/button"
android:onClick="onClick" />
</LinearLayout>
526
INTENCJE DOMNIEMANE - PRZYKŁAD 2
// SecondActivity.java
package edu.zsk.myapplication;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
}
}
527
INTENCJE DOMNIEMANE - PRZYKŁAD 2
<!-- activity_second.xml -->
<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/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Druga aktywność"
android:textColor="@color/black"
android:textSize="30sp"
android:gravity="center"
/>
</LinearLayout>
528
INTENCJE DOMNIEMANE - PRZYKŁAD 2
// ThirdActivity.java
package edu.zsk.myapplication;
import android.os.Bundle;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
setContentView(R.layout.activity_third);
}
}
529
INTENCJE DOMNIEMANE - PRZYKŁAD 2
<!-- activity_third.xml -->
<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/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Trzecia aktywność"
android:textColor="@color/black"
android:textSize="30sp"
android:gravity="center"
/>
</LinearLayout>
530
INTENCJE DOMNIEMANE - PRZYKŁAD 2
531
INTENCJE DOMNIEMANE - PRZYKŁAD 3
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Podaj adres strony WWW" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/editTextWebsite"
android:text="zsk.poznan.pl" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Otwórz WWW"
android:id="@+id/buttonWebsite"
android:onClick="onClickButtonWebsite"/>
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="@android:color/darker_gray" /> <!-- Linia -->
532
INTENCJE DOMNIEMANE - PRZYKŁAD 3
// MainActivity.java
533
INTENCJE DOMNIEMANE - PRZYKŁAD 3
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Podaj miasto" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/editTextCity"
android:text="Poznań" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Pokaż Miasto"
android:id="@+id/buttonCity"
android:onClick="onClickButtonCity"/>
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="@android:color/darker_gray" /> <!-- Linia -->
534
INTENCJE DOMNIEMANE - PRZYKŁAD 3
// MainActivity.java
535
INTENCJE DOMNIEMANE - PRZYKŁAD 3
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Podaj szerokość geograficzną" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/editTextLatitude"
android:inputType="numberDecimal"
android:text="52.2296" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Podaj długość geograficzną" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/editTextLongitude"
android:inputType="numberDecimal"
android:text="21.0122" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Pokaż Lokalizację"
android:id="@+id/buttonLocation"
android:onClick="onClickButtonLocation" />
536
INTENCJE DOMNIEMANE - PRZYKŁAD 3
// MainActivity.java
538
INTENCJE DOMNIEMANE - PRZYKŁAD 4
public void onClickAlarm(View view){
Intent intent = new Intent(AlarmClock.ACTION_SET_ALARM)
.putExtra(AlarmClock.EXTRA_MESSAGE, "Pora wstawać!")
.putExtra(AlarmClock.EXTRA_HOUR, 17)
.putExtra(AlarmClock.EXTRA_MINUTES, 54);
startActivity(intent);
}
540
INTENCJE DOMNIEMANE - PRZYKŁAD 4
541
INTENCJE DOMNIEMANE - PRZYKŁAD 4
542
FRAGMENTY
543
FRAGMENTY
• Od wersji systemu Android 3.0 możemy korzystać z fragmentów
(ang. fragments), które pozwalają na podzielenie naszej aktywności na
moduły oraz lepsze dopasowanie wyglądu i zachowania naszej
aplikacji. Wynika to z faktu, że oprócz urządzeń o małym ekranie,
takich jak smartfony, naszą aplikację mogą obsługiwać także tablety o
dużo większych rozmiarach. Ta dużo większa przestrzeń może zostać
lepiej wykorzystana dzięki wyświetlaniu dwóch (lub większej liczby)
fragmentów w ramach jednej aktywności.
544
FRAGMENTY
545
FRAGMENTY - PRZYKŁAD 1
// MainActivity.java
package edu.zsk.myapplication;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
547
FRAGMENTY - PRZYKŁAD 1
// FirstFragment.java
package edu.zsk.myapplication;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.fragment.app.Fragment;
548
FRAGMENTY - PRZYKŁAD 1
<?xml version="1.0" encoding="utf-8"?>
<!--fragment_first.xml-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#5eb4e6">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Fragment 1"
android:textColor="#000000"
android:textSize="30sp" />
</RelativeLayout>
549
FRAGMENTY - PRZYKŁAD 1
// SecondFragment.java
package edu.zsk.myapplication;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.fragment.app.Fragment;
550
FRAGMENTY - PRZYKŁAD 1
<?xml version="1.0" encoding="utf-8"?>
<!--fragment_second.xml-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#dc3b53">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Fragment 2"
android:textColor="#000000"
android:textSize="30sp" />
</RelativeLayout>
551
FRAGMENTY - PRZYKŁAD 1
552
FRAGMENTY - PRZYKŁAD 1
553
FRAGMENTY - PRZYKŁAD 2
554
FRAGMENTY - PRZYKŁAD 2
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction =
fragmentManager.beginTransaction();
if (getResources().getConfiguration().orientation ==
Configuration.ORIENTATION_PORTRAIT)
{
fragmentTransaction.replace(R.id.main, new FirstFragment());
}
else
{
fragmentTransaction.replace(R.id.main, new SecondFragment());
}
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
555
FRAGMENTY - PRZYKŁAD 2
556
FRAGMENTY - PRZYKŁAD 3
<!-- activity_main.xml -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:name="edu.zsk.myapplication.FirstFragment"
android:id="@+id/fragment1"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<fragment
android:name="edu.zsk.myapplication.SecondFragment"
android:id="@+id/fragment2"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
557
FRAGMENTY - PRZYKŁAD 3
// MainActivity.java
package edu.zsk.myapplication;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
559
FRAGMENTY - PRZYKŁAD 3
// FirstFragment.java
package edu.zsk.myapplication;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.fragment.app.Fragment;
560
FRAGMENTY - PRZYKŁAD 3
<?xml version="1.0" encoding="utf-8"?>
<!--fragment_second.xml-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#dc3b53">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Fragment 2"
android:textColor="#000000"
android:textSize="30sp"
android:id="@+id/textView"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Pobierz tekst"
android:id="@+id/button"
android:layout_below="@+id/textView"
android:layout_centerHorizontal="true" />
</RelativeLayout>
561
FRAGMENTY - PRZYKŁAD 3
// SecondFragment.java
package edu.zsk.myapplication;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
562
FRAGMENTY - PRZYKŁAD 3
563