Предисловие:
- Flutter перешел от бета-версии к версии 1.0 в 2018 г. Хотя выяснилось, что в версии 1.0 по-прежнему много ошибок, несовершенная экология, мало библиотек и плохая реализация некоторых функций, люди, которые обращают на это внимание, по-прежнему полны энтузиазма.Каждый день появляются новые вещи о выводе Flutter, что указывает на то, что многие люди все еще очень оптимистичны в этом отношении.
- В Китае Alibaba и Tencent также активно проповедуют и делают много качественного обмена. Для пожара может потребоваться время, а для коммерческого использования тоже требуется мужество, но учиться и разбираться нужно еще сейчас.
О проекте:
На этот раз я решил сымитировать очень легкий проект单读App
, в основном через проект, чтобы практиковать обычно используемые组件
,布局
,网络请求
,json解析
Ждать.
Подготовка проекта:
Этот проект черезCharles
Инструмент захвата пакетов для получения предметовApi
,пройти черезApple Configurator 2
инструменты для имитацииApp
Для ознакомления и использования двух инструментов, пожалуйста, обратитесь к предыдущим статьям.Charles, одно из гималайских приложений Swift с высоким уровнем имитации, перехватывает пакеты, получает ресурсы изображения и т. д.
Исходный код проекта:
Flutter имитирует полный исходный код приложения для однократного чтения
Изображение эффекта:
Представлены основные пункты проекта в целом:
Возьмите главную страницу, которую вы видите, когда приходит проект, в качестве примера, чтобы представить макет:
На главной странице проекта используетсяPageView
, текущий экран может видеть в реальном времениPageView
Одна страница, макет страницы в основном используетсяColumn
вchildren: <Widget>[]
обернуть все видыWidget
, верхнее изображение используетnew Image.network()
Чтобы получить изображение сети дисплея, средняя часть обернутаContainer、Text
, можно использовать расстояние между компонентамиPadding
илиExpanded
Приходите к живому управлению, выберите использование внизуRow
Оберните, как кнопки комментариев о напитках и т. Д.
Пример основного кода для главной страницы:
Вернуться к просмотру страниц:
return Center(
child: PageView.builder(
itemCount: dataList.length,
scrollDirection: Axis.vertical,
itemBuilder: (context, index) {
return calendarList(dataList[index],index,context);
},
),
);
Сетевой запрос и парсинг данных:
требуется в машиностроенииpubspec.yaml
в файлеdependencies:
введен вdio: ^1.0.13
Эта библиотека является библиотекой сетевых запросов.^x.x.x
это номер версии.
существуетdependencies:
введен вjson_annotation:: ^2.0.0
,существуетdev_dependencies:
введен вjson_serializable: ^2.0.1
build_runner: ^1.1.2
, Эти три библиотеки для синтаксического анализа json, которые можно использовать вместе для выполнения сетевых запросов и назначения данных для синтаксического анализа json, запомните верхний правый угол после завершения введения.Packages get
один раз.
Примеры использования следующие:
Объяснять:
Поскольку это интерфейс захвата пакетов, захваченные пакеты содержат зашифрованныеsign
Поле не взломано, что приводит к очень короткому тайм-ауту интерфейса, поэтому многоjson
Данные локального интерфейса также означают, что подкачки нет, но интерфейс текстового модуля является полученным сетевым интерфейсом, включая пейджинговые и раскрывающиеся соединения, поэтому проект может видеть локальныйjson
Данные и сетевые данные обрабатываются двумя способами.
для местныхjson
Введение файла, вы можете напрямую перетащитьjson
Перейдите в папку, созданную самим проектом, а затем вpubspec.yaml
в файлеflutter:
написать нижеassets:
Представляет введение файлов ресурсов, а затем записывает конкретный путь.Например- json/HomeData.json
Однако нужно обращать внимание на орфографию и пробелы.Ресурсы изображений, необходимые в том же проекте, также перетаскиваются в новую папку, а затем импортируются в нее.Packages get
Для получения дополнительной информации вы можете просмотреть исходный код этого проекта.
местный
json
данныеload
и пример разбора:
void loadData() async{
String cssStr = await DefaultAssetBundle.of(context).loadString('json/HomeData.json');
CommonModel model = CommonModel.fromJson(json.decode(cssStr));
setState(() {
List<dynamic>data = [];
data.addAll(model.datas);
dataList.addAll(data);//给数据源赋值
});
}
Пример запроса и разбора сетевого интерфейса: Объясните, что iOS необходимо добавить доверенную аутентификацию Http при запросе интерфейса http, в частности, добавив код в папку iOS --> Runner-->info.plist
/// 这里是请求接口数据,当滑动到最底端的时候会判断是否加载更多更改二个参数,post_id,page+1,然后把新请求的数据追加到以前的数据中
void loadData(String post_id, int curPage,bool isMore) async{
Dio dio = new Dio();
Response response = await dio.get("http://203.195.230.211/index.php?m=Home&c=Api2&a=getTagList&tag=$tag&p=$curPage&client=iOS&show_sdv=1&page_id=$post_id&create_time=0&sign=24a904d18a786327741ca5613180ceda&time=1547092560&device_id=A39632E7-F689-405B-A3A3-0319D6095B54&version=1.6.2&client=iOS");
CommonModel result = CommonModel.fromJson(response.data);
setState(() {
if(!isMore) {
List<dynamic>data = [];
data.addAll(result.datas);
new_page_id = result.datas[data.length-1].id;
dataList.addAll(data);//给数据源赋值
}else{
List<dynamic>data = [];
data.addAll(result.datas);
new_page_id = result.datas[data.length-1].id;
dataList.addAll(data);
}
});
}
}
Для создания модели данных:
Вот инструмент для автоматического созданияmodel
,json2dart,
как показано на рисунке:
Конкретное использование заключается в том, чтобы сначала создать, например, в проектеHomeDataModel.dart
файл, а затем используйте инструмент для созданияjson
формат, скопируйте его в файл ниже, обратите внимание наentity
следует изменить наHomeDataModel
, в это время терминал перейдет в корневую директорию проекта, т.е.ls
можно увидетьpubspec.yaml
каталог, запуститьflutter packages pub run build_runner build
, который будет автоматически сгенерирован через некоторое времяHomeDataModel.g.dart
документ.
Перейти в раздел Главная здесь布局
,数据模型
,接口请求
,数据解析
Все хорошо, можно поставить значение для просмотра страницы с реальными данными, вот низ главной страницыRow
, то есть, как и в некоторых примерах кода присваивания, подробности см. в исходном коде.
class _LikeWidgetState extends State<LikeWidget> {
bool _isLike = true;
void _togoLike() {
setState(() {
/// 如果是喜欢置为未喜欢
if (_isLike) {
_isLike = false;
/// 如果是未喜欢置为喜欢
} else {
_isLike = true;
}
});
}
@override
Widget build(BuildContext context) {
return Row(
children: <Widget>[
new Expanded(
child:new Row(
children: <Widget>[
new IconButton(
icon: Image.asset('assets/comment@2x.png'),
onPressed: (){
Navigator.of(context).push(new MaterialPageRoute(builder: (ctx) {
return new CommentPageStateful(post_id: widget.data.id);
}));
}
),
new Text(
widget.data.comment,
style: TextStyle(
color: Colors.black,
fontSize: 16,
),
),
new IconButton(
icon: (_isLike ? new Image.asset("assets/like@2x.png") : new Image.asset("assets/liked@2x.png")),
onPressed: (){
_togoLike();
}
),
new Text(
/// 这里是先通过int.parse(widget.data.good) string转int ,然后toString()再转成string
_isLike ? int.parse(widget.data.good).toString() : (int.parse(widget.data.good)+1).toString(),
style: TextStyle(
color: Colors.black,
fontSize: 16,
),
),
],
)
),
new Container(
padding: EdgeInsets.only(right: 15),
child: new Text(
'阅读数 '+widget.data.view,
style: TextStyle(
color: Colors.black,
fontSize: 16,
),
),
)
],
);
}
}
Пользовательский ящик:
Его видно через главную страницу, вверхуAppBar
Левая и правая кнопки могут всплывать влево и вправоDrawer
, из-за системыDrawer
Невозможно замаскировать весь экран, поэтому выберите здесьWidget
полноэкранная маскаDrawer
.
Изображение эффекта:
настроить
Drawer
Образец кода:
/// 自定义的左边栏抽屉
class LeftDrawer extends StatefulWidget {
final double elevation;
final Widget child;
final String semanticLabel;
final double widthPercent;
///add start
final DrawerCallback callback;
///add end
const LeftDrawer({
Key key,
this.elevation = 16.0,
this.child,
this.semanticLabel,
this.widthPercent,
///add start
this.callback,
///add end
}) : assert(widthPercent < 1.0 && widthPercent > 0.0),
super(key: key);
@override
_LeftDrawerState createState() => _LeftDrawerState();
}
class _LeftDrawerState extends State<LeftDrawer> {
@override
Widget build(BuildContext context) {
assert(debugCheckHasMaterialLocalizations(context));
String label = widget.semanticLabel;
final double _width = MediaQuery.of(context).size.width * widget.widthPercent;
return Semantics(
scopesRoute: true,
namesRoute: true,
explicitChildNodes: true,
label: label,
child: ConstrainedBox(
constraints: BoxConstraints.expand(width: _width),
child: Material(
color: Colors.black87,
elevation: widget.elevation,
child: Container(
),
),
),
);
}
для левого и правогоDrawer
Текстовая кнопка имеет анимацию увеличения, анимация шрифта используетanimated_text_kit: ^1.2.0
, Есть несколько анимаций, вы можете обратиться к исходному коду для получения подробной информации, конкретное использование - импортimport 'package:animated_text_kit/animated_text_kit.dart';
Widget _AnimatedText(String str){
return SizedBox(
child: ScaleAnimatedTextKit(
duration: Duration(milliseconds: 4000),
isRepeatingAnimation: false,
text:[str],
textStyle: TextStyle(
fontSize: 35,
color: Colors.white
),
),
);
}
О загрузке WebView:
Flutter
используется вWebView
, вы можете использоватьflutter_webview_plugin: ^0.3.0+2
Плагин, он также очень прост в использовании и импорте заголовочных файлов.import 'package:flutter_webview_plugin/flutter_webview_plugin.dart'
;
Widget _WebView(String url) {
return WebviewScaffold(url: url);
}
Используйте этот плагин для отображения общегоWebView
страницу, но в моем проектеWebView
верх страницыAppBar
, На нем все еще есть кнопка, как показано на рисунке ниже, нажмите кнопку, чтобы перейти к интерфейсу комментариев, но используйте этот плагин, потому что возвращаемыйWebviewScaffold
, так когдаWebView
Когда страница переходит на другие страницы, эта страница всегда будет вверху других страниц, хотя вы можете использоватьwidget.flutterWebviewPlugin.close();
чтобы закрыть страницу, но это означает, что вы не сможете увидеть ее, когда вернетесьWebView
Содержание страницы, и я хотел пойти авторуgithub
Ищу ответ, видел кого-то уже упомянутогоissue
Но ярлык, данный автором, подлежит разрешению. Кто знает, как решить эту проблему, пожалуйста, просветите меня.
WebView
страницу, вы также можете использоватьurl_launcher: ^4.0.1
Плагин, этот плагин является системным плагином, который может не только отображатьWebView
Пожалуйста, обратитесь к информации для конкретного использования страницы Стиль страницы после использования фиксируется Для конкретного использования, пожалуйста, обратитесь к следующей цитате.入import 'package:url_launcher/url_launcher.dart';
void _launchURL(String url, BuildContext context) async {
if (await canLaunch(url)) {
await launch(url);
} else {
throw 'Could not launch $url';
}
}
onTap: (){
_launchURL(data.html5, context);
},
url_launcher
показыватьWebView
Стиль страницы:
Объяснять:
В этом проекте есть два вида загрузкиWebView
Используются методы страницы и используется вторая страница текстового модуля.Detail
Страница используетflutter_webview_plugin
, остальные страницы сведений используютurl_launcher
показыватьWebView
страница.
***Дополнительные примечания:
Нашел лучший после того, как группа друзей подсказалаwebview
метод загрузки, используйтеwebview_flutter: ^0.2.0
плагин, сейчас в проектеWebView
Все страницы были заменены этим методом, который можно настроить с помощью этого плагина.AppBar
, и нет проблем с перескакиванием страниц, два вышеприведенныхwebview
Способ загрузки можно выбрать самостоятельно.
Специально используется вpubspec.yaml
введен вwebview_flutter: ^0.2.0
а такжеPackages get
Теперь на странице нужно использоватьimport 'package:webview_flutter/webview_flutter.dart';
import 'dart:async';
Важно отметить, что на стороне iOS необходимо добавить настройки в info.plist.
Пример использования исходного кода:class WebViewExample extends StatelessWidget {
final Completer<WebViewController> _controller =
Completer<WebViewController>();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Flutter WebView example'),
),
body: WebView(
initialUrl: 'https://www.baidu.com',
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController webViewController) {
_controller.complete(webViewController);
},
),
);
}
}
Страница комментариев:
Просто для использованияflutter_webview_plugin
изWebView
Нажмите кнопку комментариев в правом верхнем углу страницы, чтобы перейти на страницу комментариев, потому что страница комментариев должна отображаться.HeaderView
, так что выбирайsticky_headers: ^0.1.7
Библиотека очень эффективна и удобна в использовании, внешний вид и подробный код смотрите в исходном коде.sticky_headers
Пример основного кода выглядит следующим образом:
child: ListView.builder(
itemCount: newsList.length+hotsList.length+1,
itemBuilder: (context, index) {
if (index == 0) {
return StickyHeader(header: CommentHeader('喜欢', diggList.length, index),
content: DiggList(diggList, diggList.length, context),
);
}else if (hotsList.length >0 && index < hotsList.length+1) {
return StickyHeader(header: CommentHeader('最热评论', hotsList.length, index-1),
content: HotsList(hotsList[index-1], index, context),
);
}else {
return StickyHeader(header: CommentHeader('最新评论', newsList.length, index-hotsList.length-1),
content: NewsList(newsList[index-hotsList.length-1], index, context),
);
}
},
),
Рендеринг страницы комментариев:
Разговор о странице:
В верхней части страницы обсуждения есть панель вкладок, и, проводя пальцем влево и вправо, можно переключаться между страницей вопроса для одного чтения и страницей читателя.
Пример кода выглядит следующим образом:
class TalkStateful extends StatefulWidget {
@override
_TalkPageState createState() => new _TalkPageState();
}
class _TalkPageState extends State<TalkStateful> with SingleTickerProviderStateMixin {
TabController _tabController;
@override
void initState() {
// TODO: implement initState
super.initState();
_tabController = new TabController(vsync: this, initialIndex: 0, length: 2);
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.black87,
title: new Text('谈论', style: TextStyle(color: Colors.white,fontSize: 24),),
bottom: new TabBar(
isScrollable: false,//是否可滑动
unselectedLabelColor: Colors.white,//未选中按钮颜色
labelColor: Colors.white,//选中按钮颜色
labelStyle: TextStyle(fontSize: 16),//文字样式
indicatorSize: TabBarIndicatorSize.label,//滑动的宽度是根据内容来适应,还是与整块那么大(label表示根据内容来适应)
indicatorWeight: 2.0,//滑块高度
indicatorColor: Colors.black87,//滑动颜色
indicatorPadding: EdgeInsets.only(bottom: 1),//与底部距离为1
controller: _tabController,
tabs: <Widget> [
new Tab(
text: '单读问',
),
new Tab(
text: '读者论',
)
]
),
),
body: new TabBarView(
controller: _tabController,
children: <Widget> [
new DanDuWenPage(),
new DuZheLunPage(),
]
),
);
}
}
Говоря о рендеринге страниц, можно сказать следующее:
Об этом проекте давайте представим его здесь.Если вы хотите узнать больше, пожалуйста, посмотрите часть исходного кода.Если вы ничего не понимаете или у вас есть вопросы, вы можете общаться друг с другом.
Примените настройки Icon и LaunchPage LaunchImage:
Пример основной папки проекта настройки iOS: flutter_dandu--> ios--> Runner--> Assets.xcassets--> AppIcon And LaunchImage
Пример основной папки проекта Android: flutter_dandu-->android-->app-->src--main-->res
Суммировать:
новичок вFlutter
использоватьDart
Язык, это точно будет неудобно, слишком много вложенности трудно читать, но после понимания это нормально, в общем, давайте сейчас поговорим об этомFlutter
Будущее еще немного впереди, но перспективы все еще очень хорошие.Если у вас есть время или клиентские специалисты по внешнему интерфейсу, вы можете подумать о том, чтобы начать работу и учиться. После того, как вы овладеете навыками, писать что-то очень быстро, кроссплатформенность — это общая тенденция, даже если нет.Flutter
Появятся другие. самое главное этоFlutter
даGoogle
Новая система для мобильного оборудованияFuchsia
изUI
Структура и переходные продукты все еще должны быть весьма оптимистичными.
Образовательные ресурсы:
Для больших парней это должны быть исходный код и официальные документы, а для новичков давайте поищем переводы и другие туториалы для больших парней. Вот несколько хороших ссылок на учебные ресурсы:
Серия базовых руководств:
1. Китайский сайт флаттера: https://flutterchina.club
2. Технический жир: бесплатное руководство по базовому видео Flutter
Технические статьи о больших парнях:
1.Талант /user/149189…
2.nuggets.capable/post/684490…
3.Талант /user/407224…
4.nuggets.capable/post/684490…
5.у-у-у. Краткое описание.com/U/5 от 5872 Цао Цао 9…
Флаттер круги и теги и знайте:
Трепетный круг: https://www.jianshu.com/c/ebc9d2e84214
Тег флаттера: https://juejin.cn/tag/Flutter
Флаттер знает: https://zhuanlan.zhihu.com/flutter
Флаттер-проповедник:
Техническая команда Сяньюй
Пример с открытым исходным кодом Flutter:
1.GitHub.com/2-Inc/Привет, тело…
2.flutterawesome.com
3.GitHub.com/solid O/awes…
Отличные проекты Flutter с открытым исходным кодом:
1. Клиентское приложение Github
2. Разработчики Flutter из аукционной команды Alibaba помогают приложению
3. Китайское приложение с открытым исходным кодом
4. Имитация приложения NetEase Cloud Music
5. Приложение Fake Book Flag Novel
6. Ежедневное приложение «Имитация любопытства»
7. Приложение для имитации одиночного чтения