Przejdź do głównej treści
INF.04-02-23.06-SGCzerwiec 2023 · 23 kroki · ok. 57 min · 29 kryteriów z klucza

Rozwiązanie krok po kroku: Sortowanie bąbelkowe i ustawienia czcionki (C# + .NET MAUI)

Rozwiązanie dotyczy arkusza z sortowaniem bąbelkowym i ustawieniami czcionki w wersji C# + .NET MAUI: w konsoli funkcja, która sortuje rosnąco tablicę 100 liczb pseudolosowych bez gotowych funkcji, i test w programie głównym; w aplikacji mobilnej .NET MAUI ekran „Właściwości czcionki” z suwakiem, który zmienia rozmiar cytatu i wypisuje swoją wartość, oraz przyciskiem „>>”, który przełącza cytat w kółko: „Dzień dobry”, „Good morning”, „Buenos dias”. Do tego plik testu, zrzuty i srodowisko.txt.

To drugie rozwiązanie tego arkusza - pierwsze, w zakładce obok, robi to samo w Javie i Android Studio. Arkusz dopuszcza oba środowiska (obraz 1c pokazuje aplikację z Visual Studio), a klucz ocenia je tymi samymi kryteriami.

Kroki idą zdanie po zdaniu za treścią arkusza, a kod od początku jest taki, jak w porządnym projekcie. Na końcu dwa kroki porównują to rozwiązanie z wariantem w Javie.

Co widać w podglądzie. Wyniki programu konsolowego pochodzą z prawdziwego uruchomienia kodu z danego kroku (.NET 10); w każdym uruchomieniu sprawdzono, że liczb jest 100, mieszczą się w przedziale 0..1000 i stoją rosnąco. Ekran telefonu to symulacja w przeglądarce zbudowana z pliku XAML danego kroku; jej zachowanie odpowiada kodowi C# z kroku - przesuwaj suwak i klikaj „>>”. Każdy stan aplikacji zbudowano też naprawdę (dotnet build) i porównano z emulatorem Pixel 8 (Android 16).

Jak liczą się punkty. Klucz ma 29 kryteriów (R.1.1 - R.4.5), każde za 1 punkt. Próg zdania części praktycznej to 75%, czyli 22 punkty - można stracić 7 kryteriów i nadal zdać. Przy każdym kroku jest napisane, które kryteria spełnia; egzaminator ocenia spełnienie kryteriów z klucza, nie zgodność z tym kodem.

  1. Etap 1: Przygotowanie

    Krok 1 · po tym etapie masz 0 z 29 kryteriów (pkt)

    Krok 1: Folder zdającego i podfoldery

    ok. 1 min
    Polecenie z arkusza

    Utwórz folder i nazwij go numerem zdającego. W folderze utwórz podfoldery: konsola, mobilna, testy.

    Na pulpicie zakładasz folder o nazwie z numerem PESEL, a w nim konsola, mobilna i testy. Arkusz nie ma załączników - wszystkie dane (100 liczb i trzy powitania) powstają w kodzie.

  2. Etap 2: Aplikacja konsolowa

    Kroki 2-7 · po tym etapie masz 15 z 29 kryteriów (pkt)

    Krok 2: Projekt konsola w C#

    ok. 3 min
    Polecenie z arkusza

    Napisz program sortujący tablicę metodą bąbelkową. Program wykonywany w konsoli. Obiektowy język programowania zgodny z zainstalowanym na stanowisku egzaminacyjnym, jeden z: C++, C#, Java, Python.

    Wybierasz C# - ten sam język posłuży w .NET MAUI. W Visual Studio: Utwórz nowy projekt → Aplikacja konsolowa, nazwa konsola (w terminalu: dotnet new console -n konsola). Szablon tworzy Program.cs z instrukcjami najwyższego poziomu - program główny piszesz wprost w pliku, bez klasy i metody Main. Funkcję sortującą dopiszesz w tym samym pliku jako funkcję lokalną.

    konsola/Program.cs C# nowy plik
    Console.WriteLine("Hello, World!");
    Wynik programu po tym kroku
    > konsola.exe
    Hello, World!
  3. Krok 3: Funkcja BubbleSort: tablica jako argument, bez wyniku

    Kryteria: , ,

    R.2.1 Program składa się z programu głównego oraz przynajmniej jednej funkcji lub metody do sortowania. Zawartość funkcji jest zgodna z przeznaczeniem. Dopuszcza się aby funkcja była niedokończona, ale zapisy w niej wskazywały na proces sortowania

    R.2.2 Utworzono funkcję sortującą która jako argument przyjmuje tablicę i nie zwraca żadnej wartości (np. void)

    R.1.3 Użyto znaczące nazewnictwo funkcji lub metod

    ok. 2 min
    Polecenie z arkusza

    Sortowanie odbywa się w funkcji, której argumentem jest tablica, funkcja nie zwraca wartości.

    Nagłówek funkcji: argument int[] numbers, typ zwracany void (R.2.1, R.2.2). Funkcja nie musi zwracać tablicy: tablica w C# jest typem referencyjnym - funkcja dostaje odwołanie do tej samej tablicy, którą widzi program główny, i sortuje ją w miejscu. Nazwa mówi, co funkcja robi (R.1.3).

    static przy funkcji lokalnej oznacza, że funkcja nie sięga do zmiennych programu głównego - korzysta tylko z parametru. Funkcje lokalne piszesz na końcu pliku, pod programem głównym; program główny dopiszesz nad nią.

    konsola/Program.cs C# zmienione: 4 linie
    
    static void BubbleSort(int[] numbers)
    {
    }

    Wynik programu bez zmian - taki jak po kroku 2.

  4. Krok 4: Dwie pętle: przebiegi i pary sąsiadów

    Kryteria: , , ,

    R.2.3 Zastosowano algorytm sortowania (wystarczy że elementy kodu będą na to wskazywać)

    R.2.4 Na proces sortowania składają się dwie pętle operujące na wszystkich wymaganych do prawidłowego posortowania elementach tablicy. Pętle są sterowane różnymi zmiennymi

    R.1.2 Kod zapisano z wcięciami dla zagłębień bloków

    R.1.5 Zastosowano typy zmiennych pasujące do problemu (np. dowolny typ całkowity dla tablicy; typ całkowity dla iteratora pętli) w przypadku Python, tam gdzie jest to wymagane zastosowano jawną konwersję do odpowiednich typów

    ok. 3 min
    Polecenie z arkusza

    Napisz program sortujący tablicę metodą bąbelkową. Sortowanie odbywa się rosnąco, nie wykorzystuje gotowych funkcji do sortowania oraz zamiany miejscami elementów.

    Sortowanie bąbelkowe to dwie zagnieżdżone pętle sterowane różnymi zmiennymi (R.2.4, R.1.5):

    • zewnętrzna i liczy przebiegi - wystarczy Length - 1, bo po ostatnim przebiegu najmniejsza liczba sama zostaje na początku,
    • wewnętrzna j idzie po parach sąsiadów j i j + 1. Po każdym przebiegu największa z nieposortowanych liczb „wypływa” na koniec jak bąbelek, więc kolejny przebieg może być o jeden krótszy: Length - 1 - i.

    W C# długość tablicy to właściwość Length (wielką literą; w Javie length).

    Typowe błędy

    Pętla wewnętrzna do j < numbers.Length - przy j równym ostatniemu indeksowi odwołanie numbers[j + 1] rzuca IndexOutOfRangeException.

    konsola/Program.cs C# zmienione: 6 linii
    
    static void BubbleSort(int[] numbers)
    {
        for (int i = 0; i < numbers.Length - 1; i++)
        {
            for (int j = 0; j < numbers.Length - 1 - i; j++)
            {
            }
        }
    }

    Wynik programu bez zmian - taki jak po kroku 2.

  5. Krok 5: Porównanie sąsiadów i zamiana przez zmienną pomocniczą

    Kryteria: , , ,

    R.2.3 Zastosowano algorytm sortowania (wystarczy że elementy kodu będą na to wskazywać)

    R.2.5 W pętli wewnętrznej znajduje się porównanie dwóch sąsiednich elementów tablicy gwarantujące sortowanie bąbelkowe rosnące

    R.2.6 Zapisano zamianę elementów miejscami przy pomocy zmiennej buforowej lub w inny sposób, który nie powoduje utraty danych lub w Python zapis typu a, b = b, a

    R.1.1 Kod źródłowy zapisano w sposób czytelny: instrukcje w osobnych liniach, stosowane spacje pomiędzy operatorami, konsekwentnie stosowana wybrana konwencja dla nawiasów klamrowych instrukcji blokowej

    ok. 3 min
    Polecenie z arkusza

    Sortowanie odbywa się rosnąco, nie wykorzystuje gotowych funkcji do sortowania oraz zamiany miejscami elementów.

    Jeśli lewy sąsiad jest większy od prawego, zamieniasz je miejscami - duże liczby wędrują w prawo, a tablica układa się rosnąco (R.2.5). Znak > decyduje o kierunku: < posortowałoby malejąco.

    Zamiana bez gotowych funkcji: zmienna pomocnicza temp (R.2.6). Najpierw zapamiętujesz lewy element, potem nadpisujesz go prawym, na końcu wpisujesz zapamiętaną wartość w prawy. C# ma też zapis krótszy - zamianę przez krotkę (numbers[j], numbers[j + 1]) = (numbers[j + 1], numbers[j]); - klucz też go przyjmuje („w inny sposób, który nie powoduje utraty danych”), ale wersja z temp jest czytelna dla każdego egzaminatora.

    Typowe błędy

    Zamiana „na skróty” numbers[j] = numbers[j + 1]; numbers[j + 1] = numbers[j]; - po pierwszej instrukcji obie komórki mają tę samą wartość, druga liczba przepada (R.2.6).

    konsola/Program.cs C# zmienione: 6 linii
    
    static void BubbleSort(int[] numbers)
    {
        for (int i = 0; i < numbers.Length - 1; i++)
        {
            for (int j = 0; j < numbers.Length - 1 - i; j++)
            {
                if (numbers[j] > numbers[j + 1])
                {
                    int temp = numbers[j];
                    numbers[j] = numbers[j + 1];
                    numbers[j + 1] = temp;
                }
            }
        }
    }

    Wynik programu bez zmian - taki jak po kroku 2.

  6. Krok 6: Test w programie głównym: 100 liczb z przedziału 0..1000

    Kryteria: ,

    R.4.2 Tablica jest wypełniana liczbami pseudolosowymi z zakresu 0..1000

    R.1.4 Użyto znaczące nazewnictwo zmiennych. Wyjątkami od reguły są zmienne bufor, tmp, iteratory pętli itp. Kryterium nie jest spełnione tylko wtedy, gdy nazwy zmiennych nic nie znaczą, np. x, a, tab, tablica, fun

    ok. 2 min
    Polecenie z arkusza

    Sortowana jest tablica 100 pseudolosowych liczb całkowitych. W teście sprawdź działanie funkcji sortującej dla wylosowanych liczb pseudolosowych. Liczby powinny być całkowite dodatnie z przedziału 0..1000.

    Program główny - nad funkcją - zawiera test z części III (R.4.2). Tablica ma 100 elementów typu int (R.1.5), nazwa numbers mówi, co w niej jest (R.1.4). Random.Shared.Next(0, 1001) losuje od 0 do 1000 włącznie: górna granica w Next jest wyłączna, stąd 1001. Random.Shared to gotowy generator .NET - nie tworzysz własnego obiektu Random.

    Typowe błędy

    Random.Shared.Next(1000) losuje tylko do 999 - liczba 1000 nigdy nie wypadnie, choć arkusz podaje przedział 0..1000 (R.4.2).

    konsola/Program.cs C# zmienione: 5 linii
    int[] numbers = new int[100];
    for (int i = 0; i < numbers.Length; i++)
    {
        numbers[i] = Random.Shared.Next(0, 1001);
    }
    
    static void BubbleSort(int[] numbers)
    {
        for (int i = 0; i < numbers.Length - 1; i++)
        {
            for (int j = 0; j < numbers.Length - 1 - i; j++)
            {
                if (numbers[j] > numbers[j + 1])
                {
                    int temp = numbers[j];
                    numbers[j] = numbers[j + 1];
                    numbers[j + 1] = temp;
                }
            }
        }
    }

    Wynik programu bez zmian - taki jak po kroku 2.

  7. Krok 7: Wywołanie BubbleSort i wypisanie tablicy z komunikatem

    Kryteria: , ,

    R.4.1 Test funkcji sortującej zawiera odwołanie do tej funkcji z prawidlowo przekazanym parametrem

    R.4.3 Działanie programu testującego polega na wyświetleniu posortowanych rosnąco elementów tablicy

    R.1.7 Program po uruchomieniu wyświetla liczby rozdzielone dowolnym separatorem, widoczny jest znaczący komunikat opisujący co zostało wyświetlone. Jeżeli kod nie uruchamia się - sprawdzić w kodzie aplikacji

    ok. 2 min
    Polecenie z arkusza

    Wszystkie elementy posortowanej tablicy są wyświetlane na ekranie, oddzielone dowolnym separatorem, poprzedzone znaczącym komunikatem. Program główny powinien zawierać test działania funkcji sortującej.

    Wywołujesz funkcję z tablicą jako argumentem (R.4.1) i wypisujesz wszystkie 100 liczb po komunikacie „Tablica posortowana rosnąco:” (R.1.7, R.4.3). string.Join(", ", numbers) skleja elementy tablicy w jeden napis, wstawiając przecinek tylko między liczbami. To funkcja do wypisania, a nie do sortowania - arkusz zabrania tylko gotowego sortowania i gotowej zamiany.

    Podgląd to prawdziwe uruchomienie - sprawdzono, że liczb jest 100, mieszczą się w 0..1000 i stoją rosnąco.

    konsola/Program.cs C# zmienione: 3 linie
    int[] numbers = new int[100];
    for (int i = 0; i < numbers.Length; i++)
    {
        numbers[i] = Random.Shared.Next(0, 1001);
    }
    
    BubbleSort(numbers);
    Console.WriteLine("Tablica posortowana rosnąco: " + string.Join(", ", numbers));
    
    static void BubbleSort(int[] numbers)
    {
        for (int i = 0; i < numbers.Length - 1; i++)
        {
            for (int j = 0; j < numbers.Length - 1 - i; j++)
            {
                if (numbers[j] > numbers[j + 1])
                {
                    int temp = numbers[j];
                    numbers[j] = numbers[j + 1];
                    numbers[j + 1] = temp;
                }
            }
        }
    }
    Wynik programu po tym kroku
    > konsola.exe
    Tablica posortowana rosnąco: 2, 8, 34, 40, 45, 49, 69, 85, 102, 105, 127, 130, 131, 154, 157, 169, 182, 194, 202, 208, 236, 246, 251, 262, 265, 291, 297, 308, 309, 333, 346, 361, 363, 373, 376, 382, 383, 393, 413, 427, 435, 492, 494, 503, 506, 507, 521, 525, 539, 545, 547, 562, 579, 590, 602, 614, 614, 624, 625, 627, 630, 639, 646, 649, 655, 673, 699, 701, 707, 723, 746, 754, 771, 777, 794, 802, 826, 827, 833, 850, 850, 857, 867, 871, 880, 888, 894, 897, 902, 907, 908, 928, 935, 939, 940, 956, 961, 985, 994, 1000
  8. Etap 3: Test aplikacji konsolowej

    Kroki 8-9 · po tym etapie masz 18 z 29 kryteriów (pkt)

    Krok 8: Plik test.cs i zrzut konsola_testy

    Kryteria: , ,

    R.4.4 Zapisano zrzut ekranu z uruchomienia lub kompilacji aplikacji konsolowej, na zrzucie widoczne jest środowisko, w którym powstała aplikacja oraz wypisany jest wynik działania programu lub błędy kompilacji

    R.1.6 Podjęto próbę uruchomienia kodu, co udokumentowano zrzutem ekranowym przedstawiającym wykonywany program lub jego kompilację

    R.2.7 Program uruchamia się w konsoli, co udokumentowano zrzutem ekranu

    ok. 3 min
    Polecenie z arkusza

    Test powinien być fragmentem kodu, który należy umieścić w programie głównym aplikacji. Test zapisz w folderze testy, w pliku o nazwie test, z rozszerzeniem charakterystycznym dla aplikacji pisanych w danym języku programowania. Uruchom aplikację z testem i udokumentuj to zrzutem ekranu. Zrzut powinien obejmować cały obszar ekranu z widocznym paskiem zadań i nazywać się konsola_testy.jpg. Zrzut umieść w folderze testy.

    Test to fragment programu głównego - kopiujesz go do pliku test.cs w folderze testy (rozszerzenie plików C#). Plik nie musi się sam kompilować: arkusz wymaga fragmentu kodu, a działający test jest w Program.cs.

    Uruchamiasz program w Visual Studio (Ctrl+F5) i robisz zrzut całego ekranu z paskiem zadań, ze środowiskiem i oknem konsoli - konsola_testy.jpg w folderze testy (R.4.4, R.1.6, R.2.7).

    testy/test.cs C# nowy plik
    // Test funkcji sortującej - fragment programu głównego (Program.cs)
    int[] numbers = new int[100];
    for (int i = 0; i < numbers.Length; i++)
    {
        numbers[i] = Random.Shared.Next(0, 1001);
    }
    
    BubbleSort(numbers);
    Console.WriteLine("Tablica posortowana rosnąco: " + string.Join(", ", numbers));

    Wynik programu bez zmian - taki jak po kroku 7.

  9. Krok 9: Folder konsola: archiwum, źródło i plik wykonywalny

    ok. 2 min
    Polecenie z arkusza

    Kod aplikacji przygotuj do nagrania na płytę. W podfolderze konsola powinno znaleźć się archiwum całego projektu o nazwie konsola.zip, plik z kodem źródłowym programu oraz plik wykonywalny, jeżeli istnieje.

    Folder projektu pakujesz do konsola.zip, obok kopiujesz Program.cs i plik wykonywalny konsola.exe z bin\Debug\net8.0 - razem z konsola.dll, bez którego .exe się nie uruchomi.

    Wynik programu bez zmian - taki jak po kroku 7.

  10. Etap 4: Aplikacja mobilna

    Kroki 10-20 · po tym etapie masz 29 z 29 kryteriów (pkt)

    Krok 10: Nowy projekt Czcionka (.NET MAUI)

    ok. 3 min
    Polecenie z arkusza

    Wykonaj aplikację mobilną za pomocą środowiska programistycznego dostępnego na stanowisku egzaminacyjnym oraz uruchom ją w dostępnym emulatorze systemu mobilnego. Aplikacja służy do zarządzania ustawieniami czcionki.

    W Visual Studio: Utwórz nowy projekt → Aplikacja .NET MAUI, nazwa Czcionka (w terminalu: dotnet new maui -n Czcionka). Będziesz zmieniać dwa pliki: MainPage.xaml (wygląd w XAML) i MainPage.xaml.cs (kod C# strony). Strona jest osadzona w Shell (AppShell.xaml) - stąd pasek „Home” u góry.

    Na liście urządzeń wybierasz emulator Androida i uruchamiasz (F5) - na ekranie przykładowa strona szablonu.

    Czcionka/MainPage.xaml XAML nowy plik
    <?xml version="1.0" encoding="utf-8" ?>
    <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="Czcionka.MainPage">
    
        <ScrollView>
            <VerticalStackLayout
                Padding="30,0"
                Spacing="25">
                <Image
                    Source="dotnet_bot.png"
                    HeightRequest="185"
                    Aspect="AspectFit"
                    SemanticProperties.Description="dot net bot in a submarine number ten" />
    
                <Label
                    Text="Hello, World!"
                    Style="{StaticResource Headline}"
                    SemanticProperties.HeadingLevel="Level1" />
    
                <Label
                    Text="Welcome to &#10;.NET Multi-platform App UI"
                    Style="{StaticResource SubHeadline}"
                    SemanticProperties.HeadingLevel="Level2"
                    SemanticProperties.Description="Welcome to dot net Multi platform App U I" />
    
                <Button
                    x:Name="CounterBtn"
                    Text="Click me" 
                    SemanticProperties.Hint="Counts the number of times you click"
                    Clicked="OnCounterClicked"
                    HorizontalOptions="Fill" />
            </VerticalStackLayout>
        </ScrollView>
    
    </ContentPage>
    Czcionka/MainPage.xaml.cs C# nowy plik
    namespace Czcionka;
    
    public partial class MainPage : ContentPage
    {
    	int count = 0;
    
    	public MainPage()
    	{
    		InitializeComponent();
    	}
    
    	private void OnCounterClicked(object? sender, EventArgs e)
    	{
    		count++;
    
    		if (count == 1)
    			CounterBtn.Text = $"Clicked {count} time";
    		else
    			CounterBtn.Text = $"Clicked {count} times";
    
    		SemanticScreenReader.Announce(CounterBtn.Text);
    	}
    }
    Ekran telefonu po tym kroku

    Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.

  11. Krok 11: VerticalStackLayout z marginesem 20

    Kryteria: ,

    R.3.1 Zastosowano język znaczników XML/XAML lub inny do opisu interfejsu użytkownika oraz kod zawiera przynajmniej jedną kontrolkę wynikającą z treści zadania

    R.3.2 Zastosowano rozkład liniowy (np. StackLayout, LinearLayout lub inny o tej idei), pola edycyjne są rozciągnięte na całą szerokość okna (np. fill lub match_parent), ustawiono marginesy dla całej strony lub rozkładu na 20

    ok. 2 min
    Polecenie z arkusza

    Interfejs użytkownika zapisany za pomocą języka znaczników wspieranego w danym środowisku (np. XAML, XML). Zastosowany typ rozkładu liniowy (Linear / Stack lub inny o tej idei). Zastosowano marginesy dla całej strony 20.

    Usuwasz przykładową treść szablonu i zostawiasz jeden układ VerticalStackLayout - elementy jeden pod drugim (R.3.1, R.3.2). Margin="20" odsuwa cały układ o 20 od każdej krawędzi strony (R.3.2). Ten sam efekt dałoby Padding="20" na ContentPage - klucz przyjmuje margines strony albo rozkładu.

    Z MainPage.xaml.cs usuwasz licznik i metodę OnCounterClicked (przycisk, który ją wywoływał, zniknął). Zostaje konstruktor z InitializeComponent().

    Typowe błędy

    Usunięcie przycisku z XAML bez usunięcia CounterBtn z kodu kończy się błędem kompilacji: nazwa CounterBtn nie istnieje.

    Czcionka/MainPage.xaml XAML zmienione: 2 linie
    <?xml version="1.0" encoding="utf-8" ?>
    <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="Czcionka.MainPage">
    
        <VerticalStackLayout Margin="20">
        </VerticalStackLayout>
    
    </ContentPage>
    Czcionka/MainPage.xaml.cs C# zmienione: 4 linie
    namespace Czcionka;
    
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
        }
    }
    Ekran telefonu po tym kroku

    Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.

  12. Krok 12: Tytuł „Właściwości czcionki” na zielonym tle

    Kryteria:

    R.3.3 Zastosowano kontrolki: tekstu, suwaka, przycisku. Tekst "Właściwości czcionki" oraz tekst przycisku mają cechy: biały kolor czcionki, kolor tła #558B2F, pogrubione. Tekst "Właściwości czcionki" jest zapisany czcionką o największym rozmiarze, "Rozmiar: " - średnią

    ok. 2 min
    Polecenie z arkusza

    Napis o treści: „Właściwości czcionki”. Wszystkie pola są rozciągnięte na szerokość strony. Zastosowany kolor tła elementów: #558B2F, zgodnie z Obrazem 1a. Zastosowany kolory czcionki: czarny i biały, zgodnie z Obrazem 1a. Czcionka napisu „Właściwości czcionki” ma rozmiar największy i jest pogrubiona.

    Label w VerticalStackLayout domyślnie wypełnia całą szerokość (HorizontalOptions="Fill"), więc zielone tło #558B2F sięga od marginesu do marginesu. Biały tekst, pogrubiony (FontAttributes="Bold") i największy w aplikacji - 24 (R.3.3).

    Czcionka/MainPage.xaml XAML zmienione: 5 linii
    <?xml version="1.0" encoding="utf-8" ?>
    <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="Czcionka.MainPage">
    
        <VerticalStackLayout Margin="20">
            <Label Text="Właściwości czcionki"
                   FontSize="24"
                   FontAttributes="Bold"
                   TextColor="White"
                   BackgroundColor="#558B2F" />
        </VerticalStackLayout>
    
    </ContentPage>
    Ekran telefonu po tym kroku

    Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.

  13. Krok 13: Napis „Rozmiar:” średnią czcionką

    Kryteria:

    R.3.3 Zastosowano kontrolki: tekstu, suwaka, przycisku. Tekst "Właściwości czcionki" oraz tekst przycisku mają cechy: biały kolor czcionki, kolor tła #558B2F, pogrubione. Tekst "Właściwości czcionki" jest zapisany czcionką o największym rozmiarze, "Rozmiar: " - średnią

    ok. 2 min
    Polecenie z arkusza

    Napis o treści: „Rozmiar: ”. Czcionka napisu „Rozmiar:” ma rozmiar średni.

    Rozmiar 18 - mniejszy od tytułu, większy od cytatu (domyślne 14) (R.3.3). Kolor czarny. Napis ma nazwę x:Name="SizeLabel" - pod tą nazwą kod będzie dopisywał wartość suwaka. Spacja po dwukropku jest w treści celowo.

    Czcionka/MainPage.xaml XAML zmienione: 5 linii
    <?xml version="1.0" encoding="utf-8" ?>
    <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="Czcionka.MainPage">
    
        <VerticalStackLayout Margin="20">
            <Label Text="Właściwości czcionki"
                   FontSize="24"
                   FontAttributes="Bold"
                   TextColor="White"
                   BackgroundColor="#558B2F" />
    
            <Label x:Name="SizeLabel"
                   Text="Rozmiar: "
                   FontSize="18"
                   TextColor="Black" />
        </VerticalStackLayout>
    
    </ContentPage>
    Ekran telefonu po tym kroku

    Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.

  14. Krok 14: Suwak Slider od 0 do 40

    Kryteria: ,

    R.3.3 Zastosowano kontrolki: tekstu, suwaka, przycisku. Tekst "Właściwości czcionki" oraz tekst przycisku mają cechy: biały kolor czcionki, kolor tła #558B2F, pogrubione. Tekst "Właściwości czcionki" jest zapisany czcionką o największym rozmiarze, "Rozmiar: " - średnią

    R.3.4 Suwak ma wartość maksymalną 40

    ok. 2 min
    Polecenie z arkusza

    Suwak (SeekBar / Slider). Suwak ma wartość maksymalną 40, jeżeli ustawienie minimum jest wymagane – ustawić wartość 0.

    Slider - w VerticalStackLayout rozciąga się na całą szerokość - z Maximum="40" (R.3.3, R.3.4). Minimum i tak wynosi domyślnie 0, ale zapisujesz je jawnie, jak każe arkusz.

    Wartość suwaka (Value) w MAUI jest typu double - przesuwanie daje liczby z ułamkiem, np. 23,7. Rozmiar czcionki ma być liczbą całkowitą, więc zamienisz ją w kodzie na int.

    Typowe błędy

    Bez Maximum="40" suwak MAUI ma domyślne maksimum 1 - cała skala to wartości od 0 do 1 (R.3.4).

    Czcionka/MainPage.xaml XAML zmienione: 4 linie
    <?xml version="1.0" encoding="utf-8" ?>
    <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="Czcionka.MainPage">
    
        <VerticalStackLayout Margin="20">
            <Label Text="Właściwości czcionki"
                   FontSize="24"
                   FontAttributes="Bold"
                   TextColor="White"
                   BackgroundColor="#558B2F" />
    
            <Label x:Name="SizeLabel"
                   Text="Rozmiar: "
                   FontSize="18"
                   TextColor="Black" />
    
            <Slider x:Name="SizeSlider"
                    Minimum="0"
                    Maximum="40" />
        </VerticalStackLayout>
    
    </ContentPage>
    Ekran telefonu po tym kroku

    Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.

  15. Krok 15: Napis cytatu „Dzień dobry”

    Kryteria:

    R.3.3 Zastosowano kontrolki: tekstu, suwaka, przycisku. Tekst "Właściwości czcionki" oraz tekst przycisku mają cechy: biały kolor czcionki, kolor tła #558B2F, pogrubione. Tekst "Właściwości czcionki" jest zapisany czcionką o największym rozmiarze, "Rozmiar: " - średnią

    ok. 1 min
    Polecenie z arkusza

    Napis cytatu.

    Cytat o nazwie QuoteLabel - kod będzie zmieniał jego treść i rozmiar. Na starcie „Dzień dobry” w domyślnym rozmiarze 14 (R.3.7).

    Czcionka/MainPage.xaml XAML zmienione: 4 linie
    <?xml version="1.0" encoding="utf-8" ?>
    <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="Czcionka.MainPage">
    
        <VerticalStackLayout Margin="20">
            <Label Text="Właściwości czcionki"
                   FontSize="24"
                   FontAttributes="Bold"
                   TextColor="White"
                   BackgroundColor="#558B2F" />
    
            <Label x:Name="SizeLabel"
                   Text="Rozmiar: "
                   FontSize="18"
                   TextColor="Black" />
    
            <Slider x:Name="SizeSlider"
                    Minimum="0"
                    Maximum="40" />
    
            <Label x:Name="QuoteLabel"
                   Text="Dzień dobry"
                   TextColor="Black" />
        </VerticalStackLayout>
    
    </ContentPage>
    Ekran telefonu po tym kroku

    Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.

  16. Krok 16: Przycisk „>>” wyśrodkowany i pogrubiony

    Kryteria: ,

    R.3.3 Zastosowano kontrolki: tekstu, suwaka, przycisku. Tekst "Właściwości czcionki" oraz tekst przycisku mają cechy: biały kolor czcionki, kolor tła #558B2F, pogrubione. Tekst "Właściwości czcionki" jest zapisany czcionką o największym rozmiarze, "Rozmiar: " - średnią

    R.3.7 Aplikacja kompiluje się i uruchamia w emulatorze, co udokumentowano zrzutem ekranu, jej wygląd jest zgodny z obrazem 1a lub 1c w arkuszu egzaminacyjnym. Zawiera wszystkie elementy. Przycisk jest wyśrodkowany oraz napis cytatu brzmi "Dzień dobry"

    ok. 2 min
    Polecenie z arkusza

    Przycisk o treści: „>>”. Przycisk jest wyśrodkowany oraz jego tekst jest wyśrodkowany i pogrubiony.

    Przycisk w VerticalStackLayout domyślnie wypełnia szerokość - HorizontalOptions="Center" zmniejsza go do szerokości napisu i stawia na środku (R.3.7). Tekst przycisku MAUI jest wyśrodkowany domyślnie; pogrubiasz go FontAttributes="Bold". Tło #558B2F i biały tekst (R.3.3).

    Znak > w XAML zapisujesz jako &gt; - nawias ostry jest częścią składni znaczników. Ekran ma już wszystkie elementy z obrazu 1c.

    Typowe błędy

    Bez HorizontalOptions="Center" przycisk zostaje przy domyślnym Fill - zielony pas na całą szerokość, a nie wyśrodkowany przycisk (R.3.7).

    Czcionka/MainPage.xaml XAML zmienione: 6 linii
    <?xml version="1.0" encoding="utf-8" ?>
    <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="Czcionka.MainPage">
    
        <VerticalStackLayout Margin="20">
            <Label Text="Właściwości czcionki"
                   FontSize="24"
                   FontAttributes="Bold"
                   TextColor="White"
                   BackgroundColor="#558B2F" />
    
            <Label x:Name="SizeLabel"
                   Text="Rozmiar: "
                   FontSize="18"
                   TextColor="Black" />
    
            <Slider x:Name="SizeSlider"
                    Minimum="0"
                    Maximum="40" />
    
            <Label x:Name="QuoteLabel"
                   Text="Dzień dobry"
                   TextColor="Black" />
    
            <Button Text="&gt;&gt;"
                    FontAttributes="Bold"
                    TextColor="White"
                    BackgroundColor="#558B2F"
                    HorizontalOptions="Center" />
        </VerticalStackLayout>
    
    </ContentPage>
    Ekran telefonu po tym kroku

    Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.

  17. Krok 17: Tablica powitań i przycisk „>>” w kółko

    Kryteria: , ,

    R.3.5 Obsłużono przycisk za pomocą zdarzenia kliknięcia lub obsłużono suwak za pomocą zdarzenia zmiany wartości. Po wystąpieniu zdarzenia wywoływana jest funkcja obsługująca zdarzenie lub zapisano obsługę suwaka za pomocą powiązania (Binding)

    R.3.6 Napisy "Dzień dobry", "Good morning", "Buenos dias" zakodowano w tablicy 3-elementowej typu napisowego, np. String[]

    R.3.10 Po wybraniu przycisku, zmienia się napis cytatu w karuzeli, czyli 1-2-3-1...

    ok. 3 min
    Polecenie z arkusza

    Teksty pojawiające się w polu napisu cytatu są zdefiniowane w kodzie jako tablica 3-elementowa. Po wybraniu przycisku następuje akcja: zamieniany jest tekst w napisie cytatu. Kolejne napisy: "Dzień dobry", "Good morning", "Buenos dias". Jeżeli wyświetlony jest tekst „Buenos dias”, wybranie przycisku powoduje wyświetlenie „Dzień dobry” itd.

    Pole strony string[] greetings z trzema napisami (R.3.6) - zapis ["...", "...", "..."] to wyrażenie kolekcji z C# 12. greetingIndex mówi, który napis jest teraz na ekranie (0 = „Dzień dobry”, jak na starcie).

    Kliknięcie wiążesz w XAML atrybutem Clicked="OnNextClicked" (R.3.5). W metodzie indeks zwiększasz o 1 i bierzesz resztę z dzielenia przez długość tablicy: 0 → 1 → 2 → 0... Po „Buenos dias” (indeks 2) wychodzi 3 % 3 = 0, czyli znów „Dzień dobry” - karuzela (R.3.10). Do cytatu odwołujesz się wprost po nazwie QuoteLabel z x:Name.

    Kliknij w podglądzie kilka razy „>>”.

    Typowe błędy

    greetingIndex++ bez reszty z dzielenia - czwarte kliknięcie odwołuje się do greetings[3] i aplikacja zamyka się z IndexOutOfRangeException (R.3.10).

    Czcionka/MainPage.xaml XAML zmienione: 1 linia
    <?xml version="1.0" encoding="utf-8" ?>
    <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="Czcionka.MainPage">
    
        <VerticalStackLayout Margin="20">
            <Label Text="Właściwości czcionki"
                   FontSize="24"
                   FontAttributes="Bold"
                   TextColor="White"
                   BackgroundColor="#558B2F" />
    
            <Label x:Name="SizeLabel"
                   Text="Rozmiar: "
                   FontSize="18"
                   TextColor="Black" />
    
            <Slider x:Name="SizeSlider"
                    Minimum="0"
                    Maximum="40" />
    
            <Label x:Name="QuoteLabel"
                   Text="Dzień dobry"
                   TextColor="Black" />
    
            <Button Text="&gt;&gt;"
                    Clicked="OnNextClicked"
                    FontAttributes="Bold"
                    TextColor="White"
                    BackgroundColor="#558B2F"
                    HorizontalOptions="Center" />
        </VerticalStackLayout>
    
    </ContentPage>
    Czcionka/MainPage.xaml.cs C# zmienione: 9 linii
    namespace Czcionka;
    
    public partial class MainPage : ContentPage
    {
        private readonly string[] greetings = ["Dzień dobry", "Good morning", "Buenos dias"];
        private int greetingIndex = 0;
    
        public MainPage()
        {
            InitializeComponent();
        }
    
        private void OnNextClicked(object? sender, EventArgs e)
        {
            greetingIndex = (greetingIndex + 1) % greetings.Length;
            QuoteLabel.Text = greetings[greetingIndex];
        }
    }
    Ekran telefonu po tym kroku

    Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.

  18. Krok 18: Suwak: wartość po napisie „Rozmiar:”

    Kryteria: ,

    R.3.5 Obsłużono przycisk za pomocą zdarzenia kliknięcia lub obsłużono suwak za pomocą zdarzenia zmiany wartości. Po wystąpieniu zdarzenia wywoływana jest funkcja obsługująca zdarzenie lub zapisano obsługę suwaka za pomocą powiązania (Binding)

    R.3.8 Po przesunięciu suwaka jego aktualna wartość jest wyświetlana w napisie "Rozmiar: "

    ok. 3 min
    Polecenie z arkusza

    Po przesunięciu suwaka następuje akcja (obraz 1b): wartość aktualna suwaka jest zapisywana po napisie „Rozmiar:”.

    Zmianę suwaka odbierasz zdarzeniem ValueChanged="OnSizeChanged" (R.3.5). Metoda dostaje ValueChangedEventArgs z nową wartością e.NewValue (typu double). Rzutowanie (int) obcina część ułamkową - 23,7 daje 23 - i wpisujesz liczbę za „Rozmiar: ” (R.3.8).

    Przesuń suwak w podglądzie.

    Czcionka/MainPage.xaml XAML zmienione: 2 linie
    <?xml version="1.0" encoding="utf-8" ?>
    <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="Czcionka.MainPage">
    
        <VerticalStackLayout Margin="20">
            <Label Text="Właściwości czcionki"
                   FontSize="24"
                   FontAttributes="Bold"
                   TextColor="White"
                   BackgroundColor="#558B2F" />
    
            <Label x:Name="SizeLabel"
                   Text="Rozmiar: "
                   FontSize="18"
                   TextColor="Black" />
    
            <Slider x:Name="SizeSlider"
                    Minimum="0"
                    Maximum="40"
                    ValueChanged="OnSizeChanged" />
    
            <Label x:Name="QuoteLabel"
                   Text="Dzień dobry"
                   TextColor="Black" />
    
            <Button Text="&gt;&gt;"
                    Clicked="OnNextClicked"
                    FontAttributes="Bold"
                    TextColor="White"
                    BackgroundColor="#558B2F"
                    HorizontalOptions="Center" />
        </VerticalStackLayout>
    
    </ContentPage>
    Czcionka/MainPage.xaml.cs C# zmienione: 6 linii
    namespace Czcionka;
    
    public partial class MainPage : ContentPage
    {
        private readonly string[] greetings = ["Dzień dobry", "Good morning", "Buenos dias"];
        private int greetingIndex = 0;
    
        public MainPage()
        {
            InitializeComponent();
        }
    
        private void OnSizeChanged(object? sender, ValueChangedEventArgs e)
        {
            int size = (int)e.NewValue;
            SizeLabel.Text = $"Rozmiar: {size}";
        }
    
        private void OnNextClicked(object? sender, EventArgs e)
        {
            greetingIndex = (greetingIndex + 1) % greetings.Length;
            QuoteLabel.Text = greetings[greetingIndex];
        }
    }
    Ekran telefonu po tym kroku

    Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.

  19. Krok 19: Suwak: rozmiar czcionki cytatu

    Kryteria:

    R.3.9 Po przesunięciu suwaka jest zmieniany rozmiar czcionki napisu cytatu na wartość pobraną z suwaka (tylko wartości całkowite)

    ok. 2 min
    Polecenie z arkusza

    Rozmiar czcionki cytatu jest zmieniany na aktualną wartość suwaka (rozmiar czcionki powinien być liczbą całkowitą).

    Właściwość FontSize cytatu dostaje tę samą liczbę całkowitą size (R.3.9). FontSize jest typu double, ale wpisujesz do niej int po obcięciu - rozmiar jest zawsze całkowity. Przy wartości 0 MAUI wraca do rozmiaru domyślnego (14), a nie chowa tekstu - to sprawdzono na emulatorze.

    Przesuń suwak na 30 i kliknij dwa razy „>>” - jak na obrazie 1b.

    Czcionka/MainPage.xaml.cs C# zmienione: 1 linia
    namespace Czcionka;
    
    public partial class MainPage : ContentPage
    {
        private readonly string[] greetings = ["Dzień dobry", "Good morning", "Buenos dias"];
        private int greetingIndex = 0;
    
        public MainPage()
        {
            InitializeComponent();
        }
    
        private void OnSizeChanged(object? sender, ValueChangedEventArgs e)
        {
            int size = (int)e.NewValue;
            SizeLabel.Text = $"Rozmiar: {size}";
            QuoteLabel.FontSize = size;
        }
    
        private void OnNextClicked(object? sender, EventArgs e)
        {
            greetingIndex = (greetingIndex + 1) % greetings.Length;
            QuoteLabel.Text = greetings[greetingIndex];
        }
    }
    Ekran telefonu po tym kroku

    Symulacja ekranu w przeglądarce - w Android Studio / Visual Studio wygląd może się nieco różnić.

  20. Krok 20: Uruchomienie w emulatorze, zrzuty, srodowisko.txt i folder mobilna

    Kryteria: ,

    R.3.7 Aplikacja kompiluje się i uruchamia w emulatorze, co udokumentowano zrzutem ekranu, jej wygląd jest zgodny z obrazem 1a lub 1c w arkuszu egzaminacyjnym. Zawiera wszystkie elementy. Przycisk jest wyśrodkowany oraz napis cytatu brzmi "Dzień dobry"

    R.4.5 Zapisano zrzut ekranu z uruchomienia lub kompilacji aplikacji mobilnej, na zrzucie widoczne jest środowisko, w którym powstała aplikacja

    ok. 4 min
    Polecenie z arkusza

    Wykonaj zrzut ekranu emulacji aplikacji, ze środowiskiem programistycznym w tle. Zrzut zawierający cały obszar ekranu z widocznym paskiem zadań zapisz jako mobilna.jpg w folderze numerem zdającego/mobilna. Utwórz plik tekstowy o nazwie srodowisko.txt w folderze numerem zdającego/mobilna. Zapisz w nim nazwę środowiska programistycznego, w którym została wykonana aplikacja oraz nazwę emulowanego urządzenia lub systemu, na którym uruchomiono aplikację. W podfolderze mobilna powinno znaleźć się archiwum całego projektu o nazwie mobilna.zip, plik (lub pliki) z kodem źródłowym interfejsu użytkownika (XAML lub XML) oraz plik źródłowy kodu skojarzonego z interfejsem użytkownika.

    Uruchamiasz aplikację (F5) na emulatorze. Zrzut całego ekranu z Visual Studio w tle i paskiem zadań - mobilna.jpg (R.3.7, R.4.5); zrzuty interakcji (suwak, „>>”) - mobilna1, mobilna2. Plik srodowisko.txt z nazwą środowiska i emulatora. W folderze mobilna: mobilna.zip (bez folderów bin i obj - to wyniki budowania), MainPage.xaml, MainPage.xaml.cs.

    mobilna/srodowisko.txt Tekst nowy plik
    Środowisko programistyczne: Visual Studio (.NET MAUI)
    Emulator: Android Emulator - Pixel 8 (Android 16, API 36)

    Ekran telefonu bez zmian - taki jak po kroku 19.

  21. Etap 5: Porównanie z wariantem Java + Android

    Kroki 21-22 · po tym etapie masz 29 z 29 kryteriów (pkt)

    Krok 21: Te same kryteria, inny zapis

    ok. 3 min
    Polecenie z arkusza

    Obiektowy język programowania zgodny z zainstalowanym na stanowisku egzaminacyjnym, jeden z: C++, C#, Java, Python.

    wymaganieC# + .NET MAUIJava + Android
    margines strony 20Margin="20" na układzielayout_margin="20dp" (padding nadpisuje szablon)
    suwak 0-40Slider Minimum="0" Maximum="40"SeekBar android:max="40"
    wartość suwakadouble - rzutujesz na intod razu int (progress)
    zmiana suwakaValueChanged="OnSizeChanged" w XAMLsłuchacz OnSeekBarChangeListener z trzema metodami
    przycisk na środkuHorizontalOptions="Center"layout_gravity="center_horizontal"
    wypisanie tablicystring.Join(", ", numbers)pętla z przecinkiem

    Obsługa suwaka w MAUI to jedna metoda wskazana w XAML, w Androidzie - anonimowa klasa z trzema metodami, z których dwie zostają puste. Klucz (R.3.5) dopuszcza też powiązanie (Binding): Text="{Binding Source={x:Reference SizeSlider}, Path=Value, StringFormat='Rozmiar: {0:F0}'}" - napis śledzi suwak bez kodu C#, ale z formatem F0 liczba jest zaokrąglana, a nie obcinana jak przez (int).

    Ekran telefonu bez zmian - taki jak po kroku 19.

  22. Krok 22: Co wybrać na egzaminie

    ok. 2 min
    Polecenie z arkusza

    Wykonaj aplikację mobilną za pomocą środowiska programistycznego dostępnego na stanowisku egzaminacyjnym oraz uruchom ją w dostępnym emulatorze systemu mobilnego.

    Klucz ocenia oba środowiska tymi samymi kryteriami. C# + .NET MAUI daje jeden język na obie części i krótszą obsługę zdarzeń, ale pierwsze budowanie projektu na Androida trwa kilka minut - emulator i pusty projekt warto uruchomić na samym początku egzaminu. Java + Android Studio to najczęstsze środowisko na stanowiskach, z podglądem układu XML w edytorze.

    Różnica, o której łatwo zapomnieć: w MAUI wartość suwaka jest ułamkiem, więc bez (int) rozmiar czcionki nie byłby liczbą całkowitą i kryterium R.3.9 nie byłoby spełnione.

    Ekran telefonu bez zmian - taki jak po kroku 19.

  23. Etap 6: Oddanie pracy

    Krok 23 · po tym etapie masz 29 z 29 kryteriów (pkt)

    Krok 23: Nagranie płyty

    ok. 5 min
    Polecenie z arkusza

    Nagraj płytę z rezultatami pracy. W folderze z numerem zdającego powinny się znajdować podfoldery konsola, mobilna, testy. W folderze testy pliki: konsola_testy.jpg, test.

    Sprawdzasz zawartość przed nagraniem:

    • konsola: konsola.zip, Program.cs, konsola.exe z konsola.dll,
    • mobilna: mobilna.zip, MainPage.xaml, MainPage.xaml.cs, mobilna.jpg, srodowisko.txt,
    • testy: test.cs, konsola_testy.jpg.

    Nagrywasz, sprawdzasz odczyt płyty, opisujesz ją numerem zdającego.

    Ekran telefonu bez zmian - taki jak po kroku 19.

Podgląd

To jedno z możliwych rozwiązań. Egzaminator ocenia spełnienie kryteriów z klucza odpowiedzi, a nie zgodność z tym kodem - inna, poprawna droga też daje punkty.

Autor rozwiązania: . Licencja CC BY-NC 4.0 - kopiowanie i przeróbki do celów niekomercyjnych, z podaniem autora i źródła (link do tej strony) (zasady wykorzystania). Treść arkusza i klucza oceniania pochodzi z CKE.