Основная задача - осуществить передачу данных, введенных пользователем на экране авторизации, на сервер и обработать ответ. Для тестирования используется браузер Google Chrome.
Схема смены экранов при получении с сервера подтверждения корректности данных:
Всего будет три экрана: "Страница авторизации", "Ожидаем...", "MyTEST screen". Первые два скрина - это всего один экран "Страница авторизации" для ввода данных авторизации, первый до ввода данных, второй после.
После ввода валидных данных в поля появляется кнопка "Отправить". Подробнее про валидацию данных в полях формы авторизации можно прочесть здесь.
При нажатии кнопки "Отправить" происходит смена экрана, открывается экран "Ожидаем..." и данные отправляются на сервер, после получения корректного ответа с сервера открывается следующий экран "MyTEST screen".
Схема смены экранов при отсутствии ответа с сервера или неверном ответе:
В этой схеме задействовано всего два экрана: "Страница авторизации", "Ожидаем...". После нажатия на кнопку "Отправить" открывается экран "Ожидаем..." и данные передаются на сервер. При отсутствии подключения к скрипту на сервере или получении некорректного ответа возвращаемся на первоначальный экран "Страница авторизации".
На сервере по ссылке обращения 'http://test.a77r.ru/test_reply_server.php' размещен простенький скрипт РНР:
Скрипт выложен специально для теста, поэтому в дальнейшем он может быть удален с сервера. Чтобы проверить активен ли скрипт можно перейти по обозначенной ссылке. Активный скрипт отправит в ответ такую строку в формате json:
Реализацию обоначенной схемы обработки данных и смены соответствующих экранов, можно осуществить разными способами, с возможным подключением различных библиотек и ресурсов. Попробуем обойтись наиболее примитивными элементами, чтобы не вникать на этом этапе в стороннее программное обеспечение.
Код будем размещать в нескольких файлах, так будет проще и удобнее для восприятия кода:
- auth_screen.dart - содержит код для экрана "Страница авторизации"
- load_screen.dart - содержит код для экрана "Ожидаем..."
- test_screen.dart - содержит код для экрана "MyTEST screen"
Теперь перейдем непосредственно к коду. Для удобства, крупные файлы буду рассматривать по частям.
main.dart:
В основном здесь должно быть все понятно для программистов, которые уже в теме работы с фреймворком Flutter. Небольшие пояснения к некоторым строкам были даны здесь.
auth_screen.dart часть 1:
Эта часть кода совпадает с ранее рассмотренным здесь, хотя есть небольшие различия:
строка №2 (file: auth_screen.dart)
import 'load_screen.dart';
Подключаем файл с виджетом загрузки, чтобы была возможность перейти на новый экран.
строка №27 (file: auth_screen.dart)
final GlobalKey
Объявляем ключ для формы, чтобы была возможность идентифицировать нашу форму для обработки вводимых в нее данных. Стоит обратить внимание, что объявление ключа происходит в виджете состояния.
По этой причине меняются обозначения объекта формы в виджете состояния (см. строки 35, 45, 74, 94, 95).
auth_screen.dart часть 2:
Эта часть кода в основном уже была рассмотрена здесь, стоит подробнее остановиться только на сделанном дополнении для навигации (см строки 96-106):
строка №96 (file: auth_screen.dart)
Navigator.pushAndRemoveUntil(
Объявляем навигацию с методом, примение которого осуществляет переход на новую страницу с удалением истории ранее посещенных страниц.
строка №99 (file: auth_screen.dart)
builder: (context) => LoadScreen(
Создаем виджет нового экрана, и передаем в него аргументы (см. строки 100-102).
load_screen.dart часть 1:
В этом файле код виджета второго экрана "Ожидаем...". Здесь будут реализованы функции отправки полученных с первого экрана данных на сервер. И в зависимости от ответа сервера будет происходить переход на следующую страницу или на первоначальную.
Пояснения к этой части кода:
строка №2 (file: load_screen.dart)
import 'package:flutter_test_1/ui/widgets/test_screen.dart';
Подключаем файл с виджетом последней страницы, чтобы была возможность осуществить переход на нее, при положительном ответе сервера.
строка №3 (file: load_screen.dart)
import 'auth_screen.dart';
Подключаем файл с виджетом первоначальной страницы, чтобы была возможность осуществить переход на нее, при некорректном ответе сервера.
Путь к файлу в этом случае задан относительный, т.к. все файлы виджетов экранов расположены у нас в одной папке. В предыдущей строке был задан полный путь.
строка №4 (file: load_screen.dart)
import 'dart:async';
Подключаем библиотеку dart, которая позволяет осуществлять асинхронную обработку данных.
строка №5 (file: load_screen.dart)
import 'dart:convert';
Подключаем библиотеку dart, которая позволит конвертировать данные в формат json.
строка №6 (file: load_screen.dart)
import 'package:http/http.dart' as http_d;
Подключаем пакет обработки http запросов. Обращаться к объекту этого пакета будем через заданный псевдоним http_d.
строка №8 (file: load_screen.dart)
class LoadScreen extends StatefulWidget {
Объявляем класс виджета - это виджет с состоянием.
строка №12 (file: load_screen.dart)
const LoadScreen(
Задаем конструктор виджета. Конструктор принимает три обязательных параметра (см. строки 14-16) - это аргументы, которые передаются с экрана авторизации.
Принимаемые значения присваиваются объявленным переменным (см. строки 9-11)
строка №22 (file: load_screen.dart)
class _LoadScreenState extends State
Объявляем класс состояния виджета.
строка №23 (file: load_screen.dart)
bool _auth = false;
Объявляем переменную, которая будет обозначать пройдена авторизация или нет. Первоначальное значение false - авторизация не пройдена.
строка №26 (file: load_screen.dart)
void initState() {
Задаем функцию, которая единоразово запускается при создании виджет. Нам это потребуется, чтобы при создании виджета совершить сразу отправку данных на сервер.
строка №28 (file: load_screen.dart)
processingHttp(widget.message, widget.login, widget.pass);
Запускаем функцию, которая отправляет передаваемые ей данные на сервер.
load_screen.dart часть 2:
строка №31 (file: load_screen.dart)
Future
Объявляем метод, который будет отправлять данные на сервер. Это будет асинхронная функция (см .строка 35), т.к. на отправку данных на сервер и получение ответа потребуется некоторое, заранее неопределенное время.
строка №36 (file: load_screen.dart)
try {
Обработку исключений, некорректного и нестандартного поведения при работе кода, будем осуществлять с помощью try - catch - finally.
В блоке try будет содержаться код, который контролируется на возникновение сбоев/ошибок (см. строки 37-49). Блок catch содержит код (см. строка 51), который сработает при появлении сбоя/ошибки. А блок finnaly (см. строки 53-55) выполнится после отработки этих блоков, вне зависимости от наличия сбоя.
строка №37 (file: load_screen.dart)
http_d.Response response = await http_d.post(
Ожидаем ответа от сервера (await), на который отправляем POST запрос, по адресу (см. строка 38), с передачей данных (см. строки 40-42). Ответ сервера будет помещен в переменную response.
строка №46 (file: load_screen.dart)
var result = json.decode(response.body);
Если от сервера будет получен корректный ответ, то декодируем json строку тела ответа и поместим результат в переменную result.
строка №47 (file: load_screen.dart)
if ((result['title'] is String) && result['title'] == 'test_string') {
Проверяем значение title из result, и если оно удовлетворяет требуемому (в нашем случае 'test_string'), то присваиваем переменной _auth значение true (см. строка 48), что будет означать прохождение авторизации.
Если где-то в блоке try произойдет ошибка, то выполнение кода в этом блоке остановится и начнется выполнение кода в блоке catch (см. строка 51). В нашем случае мы просто выведем ошибку в консоль. Если же ошибок не будет, то сразу переходим к выполению блока finally.
строка №53 (file: load_screen.dart)
Future.delayed(const Duration(seconds: 3), () {
Задаем функцию с отложенным исполнением, на 3 секунды. Это сделано для того, чтобы зафиксировать виджет на экране даже если обмен данными с сервером будет происходить очень быстро.
строка №54 (file: load_screen.dart)
getScreenWidget();
Запускаем функцию перехода на следующий экран. Эта функция асинхронная (см. стр. 59). Переход будем осуществлять по навигации с удалением истории ранних страниц (см. стр. 60).
строка №63 (file: load_screen.dart)
builder: (context) => _auth
Строим новый виджет с учетом значения переменной _auth. Если значение равно true, то запускаем виджет из файла test_screen (см .стр. 64), если false, то виджет из файла auth_screen (см .стр. 66).
Внешний вид виджета экрана "Ожидаем..." не требует особых комментариев, там все достаточно тривиально (см. строки 73-92).
test_screen.dart:
В виджете этого экрана все достаточно просто, возможно стоит дать только пару комментариев:
строка №5 (file: test_screen.dart)
const TestScreen({Key? key, required this.message}) : super(key: key);
Конструктор виджета, в котором задается обязательное значение сохраняемое в переменную message. Значение получаем из предыдущего виджета экрана "Ожидаем...".
строка №17 (file: test_screen.dart)
Text(message),
Выводим полученное сообщение с предыдущего экрана в центр теущего экрана.
Удачи в разработке!