Урок 12. Toolbar и различные способы его создания на примере UserInfoActivity – Devcolibri – Android для начинающих

Урок 12. Toolbar и различные способы его создания на примере UserInfoActivity

Знакомство с элементом Toolbar

Элемент Toolbar предназначен для быстрого и удобного доступа пользователя к часто используемым функциям. Создать его можно используя как упрощённый вариант, в котором о многом уже позаботились разработчики системы Android, так и полностью управляя всеми внутренними компонентами. Мы рассмотрим оба этих способа.

На главном экране приложения с детальной информацией о пользователе нам необходимо создать такой toolbar:

 

user_info_toolbar.png

 

Здесь у нас находится только один элемент: кнопка поиска, которая должна перенаправлять нас на экран для поиска других пользователей.

В ранних версиях Android использовался элемент ActionBar, теперь же его функцию выполняет Toolbar. Важно, использовать Toolbar из пакета android.support.v7.widget, чтобы у нас была совместимость со старыми устройствами.

Поэтому сперва нам необходимо позаботиться о том, чтобы наши экраны не содержали элемент ActionBar по умолчанию. Для этого нам нужно унаследовать главный стиль приложения (находится в файле styles.xml) от необходимого нам Theme.AppCompat.Light.NoActionBar:

 

styles.xml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

    <!-- Остальные элементы ниже не изменились -->

</resources>

 

Теперь необходимо добавить элемент Toolbar в xml-файл activity_user_info.xml. Для этого добавим Toolbar над контейнером RelativeLayout, в котором находится вся информация о пользователе. Также добавим стиль для тулбара, чтобы переиспользовать его на других экранах.

 

activity_user_info.xml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        style="@style/Toolbar"/>

    <RelativeLayout>
        <!-- Весь контент информации о пользователе -->

    </RelativeLayout>    
</LinearLayout>

 

styles.xml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<resources>

    <!-- Остальные элементы выше не изменились -->
    <style name="Toolbar">
        <item name="android:layout_width">match_parent</item>
        <item name="android:layout_height">?attr/actionBarSize</item>
        <!-- <item name="theme">@style/ThemeOverlay.AppCompat.Dark.ActionBar</item> -->
        <item name="android:background">?attr/colorPrimary</item>
    </style>
    <!-- Остальные элементы ниже не изменились -->

<resources>

Атрибуты элемента Toolbar

Остановимся на некоторых атрибутах:

  • "android:layout_height">?attr/actionBarSize. Здесь мы указываем высоту тулбара. Таким синтаксисом мы можем получить доступ к значению высоты, которая применяется в атрибутах темы. По умолчанию, если мы не переопределяем значение, оно берётся из системного пакета темы support. Это значение лучше использовать, т.к. оно соответствует гайдам дизайна от Google. Подробнее можете изучить на сайте официальной документации.
    Не забывайте снизу менять язык на русский, если на английском пока сложновато.
  • theme>@style/ThemeOverlay.AppCompat.Dark.ActionBar. Мы пока закомментировали этот атрибут. Объясним его чуть позже более наглядно.

Таким образом, мы добавили в нашу Activity тулбар. Но этого мало. Нам нужно сообщить ей, что мы используем его в качестве замены элементу ActionBar. Это необходимо, чтобы на устройствах со старой версией Android наш интерфейс выглядел также, как и на устрйоства с новой версией. Для этого нам просто нужно вызвать метод Activity setSupportActionBar(Toolbar toolbar):

 

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
public class UserInfoActivity extends AppCompatActivity {

    // Остальной код выше не изменился
    private Toolbar toolbar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        // Остальной код выше не изменился    

        toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        initRecyclerView();

        loadUserInfo();
        loadTweets();
    }
}

 

Важно, чтобы импорт вашего тулбара выглядел так: import android.support.v7.widget.Toolbar;. Именно тулбар из этого пакета нам и нужен.

Давайте запустим приложение и посмотрим, что получилось:

 

ToolbarDark.png

 

Видим, что текст в нашем тулбаре отображается тёмным цветом. Это потому что наше приложение по умолчанию использует Light тему Theme.AppCompat.Light.NoActionBar. Эта тема означает, что фоновый цвет будет светлым, а текст – тёмным.

Давайте раскомментируем атрибут тулбара, который указывает, что все его вложенные элементы должны использовать тему Dark. В тёмной теме весь текст будет отображать светлым цветом, а фоновый цвет – тёмным. Помним, что фоновый цвет тулбара мы тоже переопределяем, используя атрибут android:background.

 

styles.xml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<resources>

    <!-- Остальные элементы выше не изменились -->
    <style name="Toolbar">
        <item name="android:layout_width">match_parent</item>
        <item name="android:layout_height">?attr/actionBarSize</item>
        <item name="theme">@style/ThemeOverlay.AppCompat.Dark.ActionBar</item>
        <item name="android:background">@color/colorPrimary</item>
    </style>
    <!-- Остальные элементы ниже не изменились -->

<resources>

 

Запустим приложение, посмотрим, что получилось:

 

ToolbarLight.png

 

Отлично, двигаемся дальше.

Осталось наполнить наш toolbar содержимым. Т.к. нашему тулбару необходима всего одна кнопка поиска, то мы можем обойтись стандартным способом добавления элементов в тулбар: при помощи Menu (помимо примера ниже также можете ознакомиться с данным уроком).

Скачивание png иконки

Давайте вначале скачаем иконку поиска, которая будем отображаться в menu. Как правило, для создания приложения достаточно пользоваться ресурсами, которые уже для разработчиков подготовил Google. Например, такая ситуация с иконками, которые рекомендует использовать Google. Их можно найти на этом сайте. В данном случае нам необходима иконка поиска, поэтому попробуем её найти, введя в поле поиска search:

 

download_material_icon.jpg

 

Нашли подходящую иконку, выбрали её разрешение и цвет, а теперь можем и скачать .png-файлы. В первую очередь извлекаем архив для удобной работы с файлами. После извлечения архива видим, что в папке содержатся иконки для webios и android. Нам естественно нужна только последняя папка. В ней содержится иконка промасштабированная для различных разрешений экранов, поэтому в зависимости от разрешения экрана устройство самостоятельно будет использовать наиболее подходящий ресурс для отображения.

Наша задача – обеспечить приложение иконками для разных разрешений. Подробнее об этом можно почитать в официальной документации (мы делаем ссылки только на те части документации Android, которая официально переведена на русский язык. Переключения языка доступно в самом низу страницы документации).

Таким образом выделяем все папки внутри android (drawable-hdpidrawable-xhdpi и так далее), копируем их, потом заходим в проект и вставляем их в папку res нашего приложения. После добавления иконок структура проекта выглядит так:

 

SearchIcon.png

 

Т.е. мы скопировали несколько иконок для разных размеров экранов.

Если поменяем тип отображения файлов с Android на Project, то увидим, что физически создалось несколько папок, в каждой из которых лежит png для разного разрешения экрана.

 

SearchIconProjectStructure.png

Создание menu

Далее создадим папку menu. Для этого нажимаем правой кнопкой по папке res и выбираем New -> Android resource directory. В дилаговом окне выбираем Resource type – menu. Все остальные поля заполнятся автоматически такими же значениями, как на скрине ниже.

 

MenuFolder.png

 

Нажимаем OK. Видим, что папка создалась.

Далее создадим новый файл меню. Для этого правой кнопкой кликаем по папке menu и выбираем варианты New -> Menu resource file.Вводим имя user_info_menu.xml.

 

user_info_menu.xml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
        android:id="@+id/action_search"
        app:showAsAction="always"
        android:icon="@drawable/ic_search_white_24dp"
        android:title="@string/search_hint"/>
</menu>

 

Из данного xml-файла можно увидеть, что наша иконка поиска будет всегда видна пользователю (app:showAsAction="always"). Видим, что мы ссылаемся на иконку, которую только что добавили в проект (android:icon="@drawable/ic_search_white_24dp").

Теперь мы можем наполнить содержимым наш Toolbar, переопределив метод onCreateOptionsMenu в Activity. Это стало возможным благодаря тому, что мы вызвали метод setSupportActionBar(toolbar).

Чтобы переопределить какой-то из методов мы можем нажать комбинацию клавиш Ctrl + O. После этого появится окно со всеми методами. Мы можем ввести название метода onCreateOptionsMenu. И выбрать его.

 

OnCreateOptionsMenu.png

 

Давайте добавим в метод использование user_info_menu.

 

UserInfoActivity.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
public class UserInfoActivity extends AppCompatActivity {

    // Остальной код выше не изменился

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.user_info_menu, menu);
        return true;
    }
    // Остальной код ниже не изменился

}

 

Отлично, дело за малым: выполнить необходимое нам действие по клику на кнопку (переход на экран для поиска пользователей). В этом нам поможет другой метод Activity:

 

UserInfoActivity.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
public class UserInfoActivity extends AppCompatActivity {

    // Остальной код выше не изменился
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if(item.getItemId() == R.id.action_search) {
            Intent intent = new Intent(this, SearchUsersActivity.class);
            startActivity(intent);
        }
        return true;
    }
    // Остальной код ниже не изменился
}

 

По клику на иконку поиска мы будем переходить на следующий экран, используя Intent, не передавая никакие данные при этом.

Единственная вещь, о которой ещё стоит упомянуть – это установка заголовка нашего экрана, отображающегося в тулбаре. Мы хотим устанавливать имя пользователя динамически в методе displayUserInfo. Для этого достаточно вызвать в необходимом месте метод тулбара setTitle(CharSequence title). Помните, что мы вызывали строку setSupportActionBar(toolbar). Также в Activity есть метод getSupportActionBar, который используется для совместимости со старыми устройствами. Его мы и будем использовать. Давайте добавим эту логику в метод displayUserInfo().

 

UserInfoActivity.java

1
2
3
4
5
6
public class UserInfoActivity extends AppCompatActivity {
    private void displayUserInfo(User user) {
        // остальной код выше не изменился
        getSupportActionBar().setTitle(user.getName());
    }
}

 

AndroidStudio можем подчёркивать вызов getSupportActionBar().setTitle, сообщая, что объект может быть null. Но мы помним, что мы вызвали метод setSupportActionBar(toolbar), поэтому можем пока игнорировать это замечание. Если кто-то сильно хочет, то можно добавить проверку на null.

Запустим приложение, посмотрим на результат:

 

UserInfoToolbarResult.png

 

Полный листинг кода:

 

UserInfoActivity.java

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package colibri.dev.com.colibritweet.activity;

import java.util.Arrays;
import java.util.Collection;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ImageView;
import android.widget.TextView;

import com.squareup.picasso.Picasso;

import colibri.dev.com.colibritweet.R;
import colibri.dev.com.colibritweet.adapter.TweetAdapter;
import colibri.dev.com.colibritweet.pojo.Tweet;
import colibri.dev.com.colibritweet.pojo.User;

public class UserInfoActivity extends AppCompatActivity {
    private ImageView userImageView;
    private TextView nameTextView;
    private TextView nickTextView;
    private TextView descriptionTextView;
    private TextView locationTextView;
    private TextView followingCountTextView;
    private TextView followersCountTextView;
    private Toolbar toolbar;

    private RecyclerView tweetsRecyclerView;
    private TweetAdapter tweetAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_user_info);

        userImageView = findViewById(R.id.user_image_view);
        nameTextView = findViewById(R.id.user_name_text_view);
        nickTextView = findViewById(R.id.user_nick_text_view);
        descriptionTextView = findViewById(R.id.user_description_text_view);
        locationTextView = findViewById(R.id.user_location_text_view);
        followingCountTextView = findViewById(R.id.following_count_text_view);
        followersCountTextView = findViewById(R.id.followers_count_text_view);
        toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        initRecyclerView();

        loadUserInfo();
        loadTweets();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.user_info_menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if(item.getItemId() == R.id.action_search) {
            Intent intent = new Intent(this, SearchUsersActivity.class);
            startActivity(intent);
        }
        return true;
    }

    private void loadTweets() {
        Collection<Tweet> tweets = getTweets();
        tweetAdapter.setItems(tweets);
    }

    private Collection<Tweet> getTweets() {
        return Arrays.asList(
                new Tweet(getUser(), 1L, "Thu Dec 13 07:31:08 +0000 2017", "Очень длинное описание твита 1",
                        4L, 4L, "https://www.w3schools.com/w3css/img_fjords.jpg"),

                new Tweet(getUser(), 2L, "Thu Dec 12 07:31:08 +0000 2017", "Очень длинное описание твита 2",
                        5L, 5L, "https://www.w3schools.com/w3images/lights.jpg"),

                new Tweet(getUser(), 3L, "Thu Dec 11 07:31:08 +0000 2017", "Очень длинное описание твита 3",
                        6L, 6L, "https://www.w3schools.com/css/img_mountains.jpg")
        );
    }

    private void initRecyclerView() {
        tweetsRecyclerView = findViewById(R.id.tweets_recycler_view);
        tweetsRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        tweetAdapter = new TweetAdapter();
        tweetsRecyclerView.setAdapter(tweetAdapter);
    }

    private void loadUserInfo() {
        User user = getUser();
        displayUserInfo(user);
    }

    private void displayUserInfo(User user) {
        Picasso.with(this).load(user.getImageUrl()).into(userImageView);
        nameTextView.setText(user.getName());
        nickTextView.setText(user.getNick());
        descriptionTextView.setText(user.getDescription());
        locationTextView.setText(user.getLocation());

        String followingCount = String.valueOf(user.getFollowingCount());
        followingCountTextView.setText(followingCount);

        String followersCount = String.valueOf(user.getFollowersCount());
        followersCountTextView.setText(followersCount);

        getSupportActionBar().setTitle(user.getName());
    }

    private User getUser() {
        return new User(
                1L,
                "http://i.imgur.com/DvpvklR.png",
                "DevColibri",
                "devcolibri",
                "Sample description",
                "USA",
                42,
                42
        );
    }
}

 

activity_user_info.xml

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        style="@style/Toolbar"/>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="8dp">

        <de.hdodenhof.circleimageview.CircleImageView
            android:id="@+id/user_image_view"
            android:layout_width="96dp"
            android:layout_height="96dp"
            android:src="@mipmap/ic_launcher"/>

        <TextView
            android:id="@+id/user_name_text_view"
            style="@style/TextView.Primary.Header"
            android:layout_below="@id/user_image_view"
            android:layout_marginTop="@dimen/text_small_margin"
            android:text="Имя"/>

        <TextView
            android:id="@+id/user_nick_text_view"
            style="@style/TextView.Secondary"
            android:layout_below="@id/user_name_text_view"
            android:layout_marginTop="@dimen/text_small_margin"
            android:text="Ник"/>

        <TextView
            android:id="@+id/user_description_text_view"
            style="@style/TextView.Primary"
            android:layout_below="@id/user_nick_text_view"
            android:layout_marginTop="@dimen/text_small_margin"
            android:text="Описание"/>

        <TextView
            android:id="@+id/user_location_icon_text_view"
            style="@style/TextIcon"
            android:layout_alignBaseline="@id/user_location_text_view"
            android:layout_below="@id/user_description_text_view"
            android:layout_marginTop="@dimen/text_small_margin"
            android:text="@string/fa_map_marker"/>

        <TextView
            android:id="@+id/user_location_text_view"
            style="@style/TextView.Secondary"
            android:layout_below="@id/user_description_text_view"
            android:layout_marginStart="10dp"
            android:layout_marginTop="@dimen/text_small_margin"
            android:layout_toEndOf="@id/user_location_icon_text_view"
            android:text="Местоположение"/>

        <TextView
            android:id="@+id/following_count_text_view"
            style="@style/TextView.Primary.Bold"
            android:layout_below="@id/user_location_text_view"
            android:layout_marginTop="@dimen/text_small_margin"
            android:text="4"/>

        <TextView
            android:id="@+id/following_text_view"
            style="@style/TextView.Secondary"
            android:layout_below="@id/user_location_text_view"
            android:layout_marginStart="5dp"
            android:layout_marginTop="@dimen/text_small_margin"
            android:layout_toEndOf="@+id/following_count_text_view"
            android:text="@string/following_hint"/>

        <TextView
            android:id="@+id/followers_count_text_view"
            style="@style/TextView.Primary.Bold"
            android:layout_below="@id/user_location_text_view"
            android:layout_marginStart="20dp"
            android:layout_marginTop="@dimen/text_small_margin"
            android:layout_toEndOf="@+id/following_text_view"
            android:text="4"/>

        <TextView
            android:id="@+id/followers_text_view"
            style="@style/TextView.Secondary"
            android:layout_below="@id/user_location_text_view"
            android:layout_marginStart="10dp"
            android:layout_marginTop="@dimen/text_small_margin"
            android:layout_toEndOf="@+id/followers_count_text_view"
            android:text="@string/followers_hint"/>

    </RelativeLayout>

    <View
        android:id="@+id/delimeter_view"
        android:layout_width="match_parent"
        android:layout_height="6dp"
        android:layout_marginTop="@dimen/text_small_margin"
        android:background="@color/gray_mercury"/>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/tweets_recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout>

 

styles.xml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

    <style name="Toolbar">
        <item name="android:layout_width">match_parent</item>
        <item name="android:layout_height">?attr/actionBarSize</item>
        <item name="theme">@style/ThemeOverlay.AppCompat.Dark.ActionBar</item>
        <item name="android:background">@color/colorPrimary</item>
    </style>

    <style name="TextView">
        <item name="android:layout_width">wrap_content</item>
        <item name="android:layout_height">wrap_content</item>
        <item name="android:textAppearance">@style/Text</item>
    </style>

    <style name="TextView.Primary">
        <item name="android:textAppearance">@style/Text.Primary</item>
    </style>

    <style name="TextView.Secondary">
        <item name="android:textAppearance">@style/Text.Secondary</item>
    </style>

    <style name="Text">
        <item name="android:textSize">16sp</item>
        <item name="fontFamily">sans-serif</item>
    </style>

    <style name="Text.Primary">
        <item name="android:textColor">@color/black</item>
    </style>

    <style name="Text.Secondary">
        <item name="android:textColor">@color/gray_dove_light</item>
    </style>

    <style name="TextView.Primary.Header">
        <item name="android:textAppearance">@style/Text.Primary.Header</item>
    </style>

    <style name="Text.Primary.Header">
        <item name="android:textSize">22sp</item>
        <item name="android:textStyle">bold</item>
    </style>

    <style name="Text.Primary.Bold">
        <item name="android:textStyle">bold</item>
    </style>

    <style name="TextView.Primary.Bold">
        <item name="android:textAppearance">@style/Text.Primary.Bold</item>
    </style>

    <style name="TextIcon" parent="TextView.Secondary">
        <item name="fontFamily">@font/font_awesome</item>
    </style>

    <style name="HalfWidth">
        <item name="android:layout_width">0dp</item>
        <item name="android:layout_height">wrap_content</item>
        <item name="android:layout_weight">0.5</item>
    </style>
</resources>

 

В результате данного урока мы узнали:

  • что такое элемент Toolbar;
  • что такое Menu и как его использловать с элементом Toolbar;
  • каким образом наполнить Toolbar пользовательскими элементами.
УВИДЕТЬ ВСЕ Добавить заметку
Вы
Добавить ваш комментарий
 

Сайт использует cookie-файлы для того, чтобы вам было удобнее им пользоваться. Для продолжения работы с сайтом, вам необходимо принять использование cookie-файлов.

Я ознакомлен(а)