рекомендации по чтению
- Количество слов: 2739
- Время: зависит от вас
- Основное содержание: картинки и код
- Сцена: По дороге на работу и с работы, в постели.
- Глава 2 Портал:Фактический бой Flutter создает приложение «изолированный остров» с нуля (№ 2, заставка, загрузочная страница).
Цели главы
Мы закончим эту часть дальше
Поскольку мы запрашиваем ресурсы сетевого образа, будет некоторое время запроса, которое также следует оптимизировать.
написать впереди
Прежде чем начать это путешествие во Flutter, вам необходимо зарезервировать некоторые часто используемые баллы.
- Научный Интернет: не спрашивайте почему, потому что этот шаг особенно важен как развитие
- Ду Вэнь, автор книги «Флаттер в действии» (псевдоним)wendux): Эта книга очень подходит для начинающих, чтобы познакомиться с различными частями Flutter. Это будет отличаться от нашего HTML
- Китайское сообщество флаттера:китайское сообщество: Будут некоторые видео-ресурсы и рекомендации по плагинам.
- Технический блог Flutter Salted Fish TeamКоманда соленой рыбы Alibaba: Как мы все знаем, такие приложения, как Xianyu, разрабатываются с использованием технологии Flutter в Китае, и их вклад в большое семейство Flutter также особенно важен.
Эта статья - первый абзац этого путешествия, потому что автор не знает, какой прогресс будет развиваться, но постарайтесь обновлять каждую неделю, давайте учиться вместе, lets_do_it
Инициализация проекта
Итак, поскольку мы собираемся начать новый проект, мы решили инициализировать новый проект. Его можно найти где угодно на диске, поэтому я выберу этот
каталог проекта
После того, как проект создан, по-прежнему старый способ удалить бесполезный код.Основной кодmain.dart
Здесь мы можем задать уровень виртуальной машины, который нам удобен для отладки
держи это всегда на высоте
Структура каталогов
Начните создавать знакомые папки
- models — это в основном класс Model, в котором размещен проект, поэтому нам не очень хорошо напрямую манипулировать JSON, возвращаемым фоном в проекте.
- страницы в основном для размещения некоторых файлов страниц, включая домашнюю страницу, список книг, лайки
- провайдер в основном размещает глобальное управление состоянием
- Общие классы методов в проекте utils
- виджеты общие виджеты
Установка зависимостей
Мы можем попробовать добавить эти два URL-адреса в закладки.
- pubВ нашем проекте также используются некоторые сторонние плагины и пакеты.
- hubВключая отличные проекты, такие как Flutter-go, я слышал, что пользователи appid могут подать заявку на использование APP через официальные каналы.
имя плагина | адрес | |
---|---|---|
flutter_screenutil | flutter_screenutil | экранизация |
curved_navigation_bar | curved_navigation_bar | Нижняя панель навигации |
provider | provider | государственное управление |
shared_preferences | shared_preferences | локальная настойчивость |
dio | dio | сетевой запрос |
fluro | fluro | структура маршрутизации |
. . . | ||
Парсинг основного файла
Мы инициализировали проект выше, очевидно, что черный цвет немного уродлив, не соответствует нашей эстетике, взглянитеMaterialApp
Внешний API
const MaterialApp({
Key key,
this.navigatorKey,
this.home,
this.routes = const <String, WidgetBuilder>{},
this.initialRoute,
this.onGenerateRoute,
this.onUnknownRoute,
this.navigatorObservers = const <NavigatorObserver>[],
this.builder,
this.title = '',
this.onGenerateTitle,
this.color,
this.theme,
this.darkTheme,
this.themeMode = ThemeMode.system,
this.locale,
this.localizationsDelegates,
this.localeListResolutionCallback,
this.localeResolutionCallback,
this.supportedLocales = const <Locale>[Locale('en', 'US')],
this.debugShowMaterialGrid = false,
this.showPerformanceOverlay = false,
this.checkerboardRasterCacheImages = false,
this.checkerboardOffscreenLayers = false,
this.showSemanticsDebugger = false,
this.debugShowCheckedModeBanner = true,
- главная Это должна быть домашняя страница
- Является ли initialRoute исходным маршрутом? Может быть, мы сможем использовать его позже, когда будем писать маршрут.
- название Это должно быть название
- цвет цвет
- тема есть тема
APP, по нашему мнению, делится на верхнюю, среднюю и нижнюю части, точно так же, как наша голова, тело и ноги.
Тогда давайте начнем писать мою домашнюю страницу
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
void main() => runApp(MyApp());
// 这里我们用StatelessWidget,我是一个没有状态的"孩子"
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: '孤岛',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHome(),
);
}
}
class MyHome extends StatefulWidget {
MyHome({Key key}) : super(key: key);
@override
_MyHomeState createState() => _MyHomeState();
}
class _MyHomeState extends State<MyHome> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('孤岛APP'),
),
);
}
}
Очевидно, что если мы поместим эти компоненты в одну и ту же папку, это не будет соответствовать спецификации разработки и не будет способствовать последующей оптимизации и обслуживанию.
Затем напишите его в папке pages
lib
├── pages
├────book_list_page.dart
├────home_page.dart
├────love_page.dart
Исходный код для каждой страницы выглядит так
- book_list_page.dart
import 'package:flutter/material.dart';
class BookListPage extends StatefulWidget {
BookListPage({Key key}) : super(key: key);
@override
_BookListPageState createState() => _BookListPageState();
}
class _BookListPageState extends State<BookListPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('我是书单'),
),
);
}
}
- home_page.dart
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
HomePage({Key key}) : super(key: key);
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('我是首页'),
),
);
}
}
- love_page.dart
import 'package:flutter/material.dart';
class LovePage extends StatefulWidget {
LovePage({Key key}) : super(key: key);
@override
_LovePageState createState() => _LovePageState();
}
class _LovePageState extends State<LovePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('我是喜欢'),
),
);
}
}
Нижняя панель навигации
Здесь мы используем **curved_navigation_bar** это колесо
Сначала добавьте зависимости
dependencies:
curved_navigation_bar: ^0.3.1 #latest version
В начале мы сказали, что некоторые общие детали, которые мы вставляемwidgets
файл, то мы планируем поместить его в папку общедоступных частей и назвать егоwidget_bottom_navigation_bar.dart
импортировать в голову файла
import 'package:flutter/material.dart';
import 'package:curved_navigation_bar/curved_navigation_bar.dart';
import '../pages/home_page.dart';
import '../pages/book_list_page.dart';
import '../pages/love_page.dart';
Весь код в нем
/// 在这里我们生命一个有状态的部件,因为其中会牵扯到index的改变
class BottomNavBarWidget extends StatefulWidget {
BottomNavBarWidget({Key key}) : super(key: key);
@override
_BottomNavBarWidgetState createState() => _BottomNavBarWidgetState();
}
class _BottomNavBarWidgetState extends State<BottomNavBarWidget>
with SingleTickerProviderStateMixin {
/// 这里声明一个控制器,在flutter中好多用到控制器的地方,包括像最常见的表单
TabController tabController;
/// 这里把我们引入的三个页面放进List集合里,等候发落
List _pages = [HomePage(), BookListPage(), LovePage()];
/// 这个就是比较核心的索引了,默认值就是我们的首页
int currentIndex = 0;
@override
void initState() {
super.initState();
tabController = TabController(vsync: this, length: 3)
..addListener(() {
/// setState 这里有点像咱们 的React,更改数据的时候是要在setState()里
setState(() {
currentIndex = tabController.index;
});
});
}
// 这里是一个部件,返回的值类型是个Widget是用Scaffold包着的,里边也是界面的核心
@override
Widget build(BuildContext context) {
return Scaffold(
bottomNavigationBar: CurvedNavigationBar(
// backgroundColor: _pages[currentIndex],
index: currentIndex,
// 底部按钮
items: <Widget>[
Image.asset(
'images/bottom_nav/home@light.png',
width: 50,
height: 50,
),
Image.asset(
'images/bottom_nav/book_list@light.png',
width: 50,
height: 50,
),
Image.asset(
'images/bottom_nav/love@light.png',
width: 50,
height: 50,
),
],
/// 点击不同的底部导航
onTap: (index) {
//Handle button tap
setState(() {
currentIndex = index;
});
tabController.animateTo(index,
duration: Duration(milliseconds: 300), curve: Curves.ease);
},
),
// 主体部分,就是文中我们所说的人的身体一样
body: TabBarView(
controller: tabController,
children: <Widget>[
Container(
child: _pages[0],
),
Container(
child: _pages[1],
),
Container(
child: _pages[2],
)
],
));
}
}
Что касается того, как использовать это колесо, для передачи строк или компонентов, нет ничего лучше, чем посмотреть исходный код.
- Проект: Список виджетов
- index: индекс NavigationBar, который можно использовать для изменения текущего индекса или установки начального индекса.
- Цвет: цвет панели навигации, по умолчанию — Colors.white.
- buttonBackgroundColor: цвет фона плавающей кнопки, по умолчанию используется свойство color.
- backgroundColor: фон NavigationBar, по умолчанию Colors.blueAccent.
- onTap: функция обрабатывает щелчок по элементу
- animationCurve: кнопка интерполяции кривой изменяет анимацию, по умолчанию Curves.easeOutCubic
- animationDuration: продолжительность анимации изменения кнопки, по умолчанию Duration (миллисекунды: 600)
- высота: высота панели навигации, минимальное значение – 0,0, максимальное – 75,0.
Импорт локальных изображений
Необходимо узнать о картинках, которые мы представили выше
Image.asset(
'images/bottom_nav/book_list@light.png',
width: 50,
height: 50,
),
то естьimages/bottom_nav/book_list@light.png
,
-
Создайте проект в корневом каталоге проекта
images目录
, и скопируйте нужные изображения в этот каталог -
существует
pubspec.yaml
серединаflutter
Частично добавить следующее:assets: - images/bottom_nav/home@light.png - images/bottom_nav/book_list@light.png - images/bottom_nav/love@light.png
-
загрузить это изображение
-
Image( image: AssetImage("images/avatar.png"), width: 100.0 );
-
Image.asset("images/avatar.png", width: 100.0, )
-
Пока что мы разработали ее часть, и никаких камней преткновения мы не встретили Вот так она выглядит сейчас в "Lone Island APP"
экранизация
Когда вы нажимаете на нижнюю навигацию, вы можете переключаться между тремя страницами.Теперь есть очень важный вопрос для рассмотрения.Давайте сосредоточимся на шрифте головы.Сейчас он такого размера под этот симулятор,тогда есть тысячи сотовых телефонов модели. Так что вам нужен экран, который не подходит
Здесь мы используем flutter_ScreenUtil
Решение для адаптации экрана флаттера позволяет вашему пользовательскому интерфейсу отображать разумную компоновку на экранах разных размеров!
- Адрес пакета [flutter_ScreenUtil (GitHub.com/open флаттер…)
- Звезды 1,2 тыс.+
Поговорим о том, как использовать
- ширина ширина ScreenUtil.getInstance().setWidth(540)
- высота высота ScreenUtil.getInstance().setHeight(200)
- размер шрифта
//长方形:
Container(
width: ScreenUtil.getInstance().setWidth(375),
height: ScreenUtil.getInstance().setHeight(200),
),
//如果你想显示一个正方形:
Container(
width: ScreenUtil.getInstance().setWidth(300),
height: ScreenUtil.getInstance().setWidth(300),
),
//传入字体大小,默认不根据系统的“字体大小”辅助选项来进行缩放(可在初始化ScreenUtil时设置allowFontScaling)
ScreenUtil.getInstance().setSp(28)
//传入字体大小,根据系统的“字体大小”辅助选项来进行缩放(如果某个地方不遵循全局的allowFontScaling设置)
ScreenUtil(allowFontScaling: true).setSp(28)
Внесите в файл, который необходимо адаптировать
import 'package:flutter_screenutil/flutter_screenutil.dart';
Здесь следует отметить, что инициализацию размера адаптации мы прописали в нижней навигации
Затем мы адаптируем три экрана изображения внизу
items: <Widget>[
Image.asset(
'images/bottom_nav/home@light.png',
width: ScreenUtil.getInstance().setWidth(100),
height: ScreenUtil.getInstance().setHeight(100),
),
Image.asset('images/bottom_nav/book_list@light.png',
width: ScreenUtil.getInstance().setWidth(100),
height: ScreenUtil.getInstance().setHeight(100)),
Image.asset('images/bottom_nav/love@light.png',
width: ScreenUtil.getInstance().setWidth(100),
height: ScreenUtil.getInstance().setHeight(100)),
],
Итак, теперь нам нужно разобраться со шрифтом головы, верно?
- Ввести import 'package:flutter_screenutil/flutter_screenutil.dart';
- Специфическая адаптация
title: Text(
'我是首页',
style: TextStyle(fontSize: ScreenUtil.getInstance().setSp(36)),
),
Там что-то внутри, верно?
DEBUG в правом верхнем углу
В MaterialApp установите для параметра debugShowCheckdModeBanner значение false.
Вот ссылка для ознакомленияКак удалить метку отладки в приложении флаттера
В конце этого путешествия давайте усовершенствуем этот «Остров».
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text(
'首页',
style: TextStyle(fontSize: ScreenUtil.getInstance().setSp(36)),
),
),
body: Container(
height: ScreenUtil.getInstance().setHeight(1334),
width: ScreenUtil.getInstance().setWidth(750),
child: Image.network(
'https://i.demo-1s.com/2019/11/16/yjhPSQWjuqPmosIL.jpg',
fit: BoxFit.cover,
),
),
);
напиши в конце
Этот участок дороги, мы придем сюда вместе, автор будет продолжать обновлять, пожалуйста, обратите больше внимания, соответствующий код также будет обновлен доавторский склад,GitHub.com/AsianStudent/грипп ТТ…
Если тебе это нравится, ты можешь меня подбодрить, так что давай помолодеем~~
END
Советы: для некоторых идей есть несколько отличных постов в блогах. Если они неуместны, вы также можете сослаться на автора.siteОставьте сообщение, чтобы поблагодарить открытый исходный код, спасибо всем