Путь к фронтенд флаттеру (2): предпроектная подготовка

Flutter

Последнее время больше, напишу в проекте с флаттером, так что поделюсь.

1. Библиотека маршрутизации:fluro

Установить

Эта часть официального документа, напрямую использующая номер версии, неверна. Номер версии не нужно указывать в кавычках, поэтому правильный способ -pubspec.yamlв файлеdependenciesприсоединиться ниже

fluro: ^1.5.1

После этого редактор может сам установить зависимости по команде флаттера, либо запустить его в корневом каталоге проектаflutter pub get, см. конкретный процессофициальный сайт флаттера

использовать

Официальный документ относительно краток, я читал егоflutter goПосле кода использование этой библиотеки маршрутизации резюмируется следующим образом:

  1. Определите класс, реализующий метод, расширяющий входящий экземпляр маршрутизатора.код здесь
  2. убедиться, что код выполняетсяНачалоВызовите указанный выше метод класса для инициализации маршрута, напримерrunAppперед запуском метода илиКонструктор корневого класса MyApp, я выбрал последнее.Экземпляр маршрутизатора предпочтительно является глобальной переменной, чтобы к нему также можно было получить доступ в других файлах..код здесь
  3. существуетMaterialAppизonGenerateRouteПерепишите следующий код. Здесь используется маршрутизатор, поэтому на шаге 2 убедитесь, что маршрутизатор был правильно инициализирован.
onGenerateRoute: (settings) {
  return Application.router.generator(settings);
}
  1. При переходе по странице вы можете использовать методы, предоставляемые этой библиотекой,router.navigateTo(context, "/users/1234", transition: TransitionType.fadeIn);, вы также можете использовать метод перехода маршрутизации, предоставляемый флаттером,Navigator.of(context).pushNamed("/users/1234", arguments: {"from": "ui"}).

нужноИзмените анимацию перехода страницы, чтобы использовать прежнюю,нужноПри наличии дополнительных параметров рекомендуется использовать последний. Потому что анимацию перехода можно задать на шаге 2, а первый обеспечивает только передачу динамических параметров, если нужно пройтиMapДанные должны быть закодированы и декодированы, поэтому я рекомендую последнее.

2. библиотека webviewk:webview_flutter

Установить

webview_flutter: ^0.3.16

использовать

код здесь

  1. Каталогios/Runner/Info.plistизdictдобавить в<key>io.flutter.embedded_views_preview</key> <string>YES</string>
  2. После того, как пакет введен в файл, его можно использовать напрямуюWebViewТеперь метод использования намного проще, чем метод плагина.Определяя компоненты, вы можете предоставить методы для использования js.Чтобы передать значения в js, вам нужен метод AssessmentJavascript контроллера.
WebView(
  // webview的url
  initialUrl: url ?? 'https://www.baidu.com/',
  // 监听页面url的变化,根据返回值决定跳转还是阻止
  navigationDelegate: (request) {
    if (request.url.startsWith('https://www.youtube.com/')) {
      print('blocking navigation to $request}');
      return NavigationDecision.prevent;
    }

    return NavigationDecision.navigate;
  },
  // flutter向js注入全局变量,然后js就可以调用flutter的方法
  // 例子中js的window会多出一个 Print 对象,js调用Print.postMessage('我是js')时,在flutter中则会打印 js传过来的值: 我是js
  javascriptChannels: {
    JavascriptChannel(
      name: 'Print',
      onMessageReceived: (JavascriptMessage msg) {
        print('js传过来的值: ' + msg.message);
      }
    ),
  },
  // 是否允许运行js
  javascriptMode: JavascriptMode.unrestricted,
  // webview 创建后肤将控制器赋值给实例变量,方便控制
  onWebViewCreated: (webViewController) {
    // _controller.complete(webViewController);
    _webViewController = webViewController;
  },
  // 页面加载完成
  onPageFinished: (String msg) {
    // print('加载完成');
  },
)
  1. При перемотке методом перемотания флаттера используется по умолчанию. Если вам нужно перемотать в WebView, вам нужно обернуть слой снаружи.WillPopScopeчтобы прослушать возврат страницы для внесения изменений.
Future<bool> back() async {
  bool canBack = await _webViewController?.canGoBack();
  if (canBack) {
    _webViewController.goBack();
  } else {
    Navigator.of(context).pop();
  }

  return false;
}
  1. с помощью контроллераevaluateJavascriptjs можно выполнить через флаттер, таким образомПолучите значение, возвращаемое js, или введите переменные в js (например, информацию о пользователе и т. д.)., но это ограничено. В Android значение, возвращаемое после выполнения, представляет собой строку в формате JSON. В iOS могут быть возвращены только строки примитивных типов и типов массивов, другие не примитивные типы не поддерживаются иБудущее вернется как ошибка.

3. Библиотека HTTP-запросов:dio

Установить

dio: ^3.0.1

использовать

Используется, как используется DiO, не очень отличается от Axios, которые обычно используют передний конец, поэтому я расскажу только о трудностях, которые я столкнулся раньше.

  1. проблема дио перехватчиков. На самом деле, это в основном обучение дротикам не очень хорошо, кроме функции или метода, можно только объявить переменную, но метод не может быть выполнен экземпляром, следующий код будет жаловаться.
Dio dio = new Dio();
dio.interceptors.add(DioCacheManager(CacheConfig(baseUrl: baseUrl)).interceptor);

Поэтому, когда вы хотите инкапсулировать определенный класс A, вы должны создать новый класс B, а затем выполнить метод A в методе B, а затем вернуться после операции.код здесь

  1. При выполнении http-запроса выберите, отображать ли поле загрузки в соответствии с параметром. Прочитав документ, я обнаружил, что дополнительный параметр существует как в запросе, так и в ответе, но в документе не указано, как этот дополнительный параметр передается. Позже я посмотрел на подсказку типа и обнаружил, что дополнительный параметр включен в опции параметра запроса. На самом деле нет необходимости передавать параметр загрузки через extra, его можно инкапсулировать прямо в запрашиваемом месте. О загрузочном ящикекод здесь

  2. Данные ответа обрабатываются, и соответствующая обработка выполняется по коду ошибки бэкенда. Изначально я хотел обрабатывать данные ответа в перехватчиках, но если это сделать, подсказка типа возвращаемых данных будет неверной, поэтому окончательно обрабатывается после получения данных ответа.

4. json в дартс-класс:json_model

Установить

dependencies:
  json_annotation: ^2.0.0
dev_dependencies:
  json_model: ^0.0.2
  build_runner: ^1.0.0
  json_serializable: ^2.0.0

использовать

  1. Создайте новую папку JSONS в корневом каталоге проекта
  2. Создайте новый файл json в этой папке
  3. воплощать в жизньflutter packages pub run json_model

5. Кэш HTTP-запросов:dio-http-cache

Установить

dependencies:
  dio_http_cache: ^0.2.0

Версия 0.2.0 dio-http-cache имеет конфликт зависимостей с библиотекой json_model, чтобы разрешить конфликт зависимостей.

json_model的依赖目前是
  json_annotation: ^2.2.0
  json_serializable: ^2.0.0

为了兼容http_cache,需要升级这两个依赖包的版本
  json_annotation: ^3.0.0
  json_serializable: ^3.0.0

использовать

  1. добавить в диоdio-http-cache interceptor
dio.interceptors.add(DioCacheManager(CacheConfig(baseUrl: "http://www.google.com")).interceptor);
  1. Добавьте параметры запроса
options: buildCacheOptions(
  Duration(days: 7),
  forceRefresh: true,
  options: Options(
    headers: headers,
    method: method,
    extra: {
      'needLoading': needLoading ?? true,
      ...(extra ?? {}),
    },
  ),
)

6. библиотека тостов:bot_toast

Почему тост должен использовать отдельную библиотеку? Потому что во флаттере, если вы хотите отобразить тост, вам обычно нужно использоватьBuildContext context, и чтобы использовать эту библиотеку, просто используйтеBotToastInitЭлемент оборачивается один раз, а затем его можно использовать напрямую, в противном случае необходимо создавать контекст глобальной переменной (не знаю, возможно ли это) или каждый раз передавать контекст.

существуетflutter的initState声明周期中,可以得到 context,但无法真正使用它,因为框架还没有完全将其与 state 关联。 доinitState()Когда выполнение метода завершается, объект State инициализируется, и контекст становится доступным. так вinitStateПри выполнении http-запроса в методе всплывающее уведомление не может отображаться напрямую.

// 第一帧 build 结束时触发,此时context可用
void initState() {
  super.initState();
  WidgetsBinding.instance.addPostFrameCallback((callback){

  });
}

Установить

dependencies:
  bot_toast: ^2.1.0

использовать

  1. Импортировать библиотеку BotToast
import 'package:bot_toast/bot_toast.dart';
  1. Инициализировать Bottooast
// 1.使用BotToastInit直接包裹MaterialApp
BotToastInit(
  child: MaterialApp(
    title: 'BotToast Demo',
    // 2.注册路由观察者
    navigatorObservers: [BotToastNavigatorObserver()],
    home: XxxxPage(),
  )
);
  1. Использование BotToast
BotToast.showText(text:"xxxx");  //弹出一个文本框;
BotToast.showSimpleNotification(title: "init"); //弹出简单通知Toast
BotToast.showLoading(); //弹出一个加载动画

7. Потяните вверх, чтобы загрузить, и потяните вниз, чтобы обновить:flutter_easyrefresh

Установить

dependencies:
  flutter_easyrefresh: ^2.0.4

использовать

код здесь

Я должен сказать, что эта библиотека действительно удобна и намного проще написала, чем в Интернете. Официальная документация была написана очень подробно, поэтому я не буду написать это.

8. Карусель:flutter_swiper

Установить

dependencies:
  flutter_swiper: ^1.1.6

использовать

код здесь

Эта библиотека тоже очень мощная, и в основном там есть часто используемые функции.

Если вы хотите реализовать связь между вкладкой и свайпером,

// swiper onIndexChanged
Swiper(
  itemCount: 2,
  itemBuilder: (context, index) {
    return Container(
      color: Color(0xFF82B1FF),
      child: Center(child: Text('$index',)),
    );
  },
  onIndexChanged: (index) {
    _tabController.index = index;
  },
  controller: _swiperController,
)

// tab onTap
TabBar(
  tabs: tabs,
  labelPadding: EdgeInsets.only(bottom: 12.0),
  indicatorSize: TabBarIndicatorSize.label,
  indicatorWeight: 3.0,
  onTap: (int index) {
    _swiperController.move(index);
  },
  controller: _tabController,
)

9. Управление статусом:Event Bus

Во флаттере довольно много библиотек управления состоянием, таких как официально рекомендуемый Provider, а также redux, mobx, bloc, rxdart и т.д. Основная причина в том, что текущий проект пока маленький, и мест не так много которые требуют совместного использования состояния, поэтому я сначала буду использовать шину событий.

Установить

dependencies:
  event_bus: 1.1.0

использовать

  1. Создать экземпляр
import 'package:event_bus/event_bus.dart';

EventBus eventBus = EventBus();
  1. определить класс события
class PieceEvent {
  bool isBlack;
  PieceEvent({ this.isBlack = true });
}
  1. слушать это событие
eventBus.on<PieceEvent>().listen((event) {
  setState(() {
    isBlack = event.isBlack;
  });
});
  1. вызвать событие
eventBus.fire(PieceEvent(isBlack: isBlack));

  1. [ПЕРЕВОД] Фрезентация Объясните основные концепции: виджет, состояние, контекст и унаследованный
  2. Stateful Widget Lifecycle
  3. material icon
  4. emoji

Кодовый адрес:GitHub.com/ma125120/legal…