…
итак, пора браться за дело.
место для длинного вступления*
Первым делом выбираем сайт, который мы будем использовать как макет. Первое, что пришло в голову, это 4PDA. Это достаточно красивый, и, очень, известный сайт.
Усложним себе задачу загрузкой списка элементов напрямую с сайта, без api.
Далее, выбираем язык. В последний раз я писал на Kotlin, значит, переключаемся на Dart
На скриншоте мы видим:
- Прокручиваемый список элементов
- Рекламу сверху и внизу в разных представлениях (Пока не знаю, следует ли её вставлять)
- Наверху контейнер с логотипом, поиском, кнопкой для входа, вкладки, две обычные кнопки, тёмная кнопка
- Ниже поле с текстом и кнопками с обводкой
Внизу страницы номера страниц и какой-то текст
Анимации на сайте я не обнаружил, это упростит нам задачу
Скрол страницы сдвигает всю верхнюю панель, а значит всё, кроме рекламы внизу, находится в одном элементе.
Неожиданным моментом оказалось то, что в качестве логотипа страницы используется не привычный SVG файл, а специальный шрифт
const Text(
"4",
style: TextStyle(
fontFamily: "fontello",
fontWeight: FontWeight.normal,
fontStyle: FontStyle.normal,
color: Colors.white,
backgroundColor: Color.fromARGB(255, 0, 114, 188),
),
),
таким образом у нас выглядит логотип.
Спустя несколько часов рутины мы получаем вот такое меню, надпись HUAWEI, вдруг, оказалась SVG изображанием, потому я использовал flutter_svg для её отображения. При детальном разборе можно заметить неточности размеров, но, это вряд-ли будет критично в нашем проекте, а если будет - ничего не мешает это исправить без особых трудностей.
Я ожидал проблем в этом виджете, но не думал что они будут в кодировке
final a = (await http.Client().get(Uri.parse("https://4pda.to/"))).body;
Я использовал этот способ обращения к сайту, далее регулярные выражения
_title = RegExp('title=".+">').firstMatch(o)?.group(0);
Взять название достаточно просто, а вот исправить уже сложнее
При использовании этого
var resp = await http.Client().get(Uri.parse("https://4pda.to/"));
String.fromCharCodes(resp.bodyBytes)
или этого
var resp = await http.Client().get(Uri.parse("https://4pda.to/"));
utf8.decode(resp.bodyBytes)
способа кириллица не отображается.
При этом кодирование и декодирование строк происходит без ошибок.
print((utf8.decode(resp.bodyBytes.sublist(754, 769), allowMalformed: true)));
I/flutter (19851): ����� �� �����
эта строка не подлежит восстановлению.
Та же ошибка происходит при ascii и base64.
Верной кодировкой оказалась windows-1251
Раз проблему не удалось решить стандартным способом, придётся использовать свой
const List cp1251 = [
'\u0000',
'\u0001',
...
'\u044E',
'\u044F'
];
создаём массив символов кодировки
String encode(Uint8List data){
StringBuffer out = StringBuffer();
for (int i in data){
out.write(cp1251[i]);
}
return out.toString();
}
создаём функцию обработки. Работает достаточно быстро, а это значит, что дополнительная оптимизация не нужна
final a = encode((await http.Client().get(Uri.parse("https://4pda.to/"))).bodyBytes);
и обращаемся к функции.
Получаем человеческий.
Немного рутины внизу, исправление ошибок, и, наконец, мы получаем результат
На странице ещё остались необработанные детали, вроде, рекламы и изменений дизайна отдельных постов, но для нашего проекта этой работы достаточно
Пишите предложения для подобных проектов, если получилось интересно.
0 комментариев