【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex

简介: 【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex

【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex

章节内容【08】

【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-卓伊凡换人优雅草Alex

开发背景

由于卓伊凡工作实在太多,工作繁忙且卓伊凡每天晚上还要直播,因此本项目已前端部分转交优雅草Alex继续并且更新-为了保证每日更新

优雅草Alex 【高级全栈开发工程师-任职世界500强企业-月薪30k+】接下来就看这位大佬的表演吧

经典案例-在优雅草手撸加速器-win-mac-安卓+苹果 4端【仅用了一个月时间】

上篇我们做了自定义组件,本文继续完善注册相关页面并且实现跳转

闲话不多,开源仓库地址,可以观摩已经写好的代码:

https://gitee.com/youyacao/ff-flutter

demo下载

https://www.youyacao.cn/freefirend

更新代码文件和日志文件-gitee可见

·更新了getx路由
·增加了屏幕适配
·基础导航栏开发处理
·重建了Android
·布局规划了包含注册,直播,其他等页面框架
·整体处理

remote: Enumerating objects: 98, done.
remote: Counting objects: 100% (94/94), done.
remote: Compressing objects: 100% (50/50), done.
remote: Total 62 (delta 19), reused 13 (delta 0), pack-reused 0
Unpacking objects: 100% (62/62), 18.63 KiB | 141.00 KiB/s, done.
From https://gitee.com/youyacao/ff-flutter
   2d36d20..71239bb  master     -> origin/master
Updating 2d36d20..71239bb
Fast-forward
 .cursorrules                                       | 130 +++++++++++
 .fvmrc                                             |   3 +
 .gitignore                                         |   3 +
 .metadata                                          |  30 +--
 .vscode/launch.json                                |   6 +-
 .vscode/settings.json                              |   3 +
 android/.gitignore                                 |   2 +-
 android/app/build.gradle                           |  53 +++--
 android/app/src/main/AndroidManifest.xml           |   5 +-
 .../{freefirend => ff_flutter}/MainActivity.kt     |   2 +-
 .../app/src/main/res/mipmap-hdpi/ic_launcher.png   | Bin 1508805 -> 544 bytes
 .../app/src/main/res/mipmap-mdpi/ic_launcher.png   | Bin 1508805 -> 442 bytes
 .../app/src/main/res/mipmap-xhdpi/ic_launcher.png  | Bin 1508805 -> 721 bytes
 .../app/src/main/res/mipmap-xxhdpi/ic_launcher.png | Bin 1508805 -> 1031 bytes
 .../src/main/res/mipmap-xxxhdpi/ic_launcher.png    | Bin 1508805 -> 1443 bytes
 android/build.gradle                               |   4 +-
 android/gradle.properties                          |   2 +-
 android/gradle/wrapper/gradle-wrapper.properties   |   2 +-
 android/settings.gradle                            |   9 +-
 lib/controllers/index_controller.dart              |   5 +
 lib/controllers/register_controller.dart           |  14 ++
 lib/controllers/sms_login_controller.dart          |   5 +
 lib/main.dart                                      |  34 +--
 lib/routes/app_pages.dart                          |  38 +++
 lib/routes/app_routes.dart                         |   5 +
 lib/screens/account_screen.dart                    |  16 ++
 lib/screens/home_screen.dart                       | 254 ++++++++++++++++++++
 lib/screens/index.dart                             | 259 ++++++++-------------
 lib/screens/message_screen.dart                    |  16 ++
 lib/screens/register.dart                          | 109 +++++----
 lib/screens/short_video_screen.dart                |  16 ++
 linux/main.cc                                      |   6 +
 linux/my_application.cc                            | 124 ++++++++++
 linux/my_application.h                             |  18 ++
 pubspec.lock                                       |  66 ++++--
 pubspec.yaml                                       |   2 +
 test/widget_test.dart                              |  30 +++
 37 files changed, 972 insertions(+), 299 deletions(-)
 create mode 100644 .cursorrules
 create mode 100644 .fvmrc
 create mode 100644 .vscode/settings.json
 rename android/app/src/main/kotlin/com/example/{freefirend => ff_flutter}/MainActivity.kt (74%)
 create mode 100644 lib/controllers/index_controller.dart
 create mode 100644 lib/controllers/register_controller.dart
 create mode 100644 lib/controllers/sms_login_controller.dart
 create mode 100644 lib/routes/app_pages.dart
 create mode 100644 lib/routes/app_routes.dart
 create mode 100644 lib/screens/account_screen.dart
 create mode 100644 lib/screens/home_screen.dart
 create mode 100644 lib/screens/message_screen.dart
 create mode 100644 lib/screens/short_video_screen.dart
 create mode 100644 linux/main.cc
 create mode 100644 linux/my_application.cc
 create mode 100644 linux/my_application.h
 create mode 100644 test/widget_test.dart

实战开始

先打包个,flutter build apk 运行, 报错

先运行下看看

可以成功运行,那么已经可以确定肯定是gradle 打包问题了,解决打包问题前我们已经看看更新的内容吧,

import 'package:flutter/material.dart';
import 'package:logging/logging.dart';
import 'package:get/get.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:ff_flutter/routes/app_pages.dart';
import 'package:ff_flutter/routes/app_routes.dart';
void main() {
  // 初始化日志记录器
  Logger.root.level = Level.ALL;
  Logger.root.onRecord.listen((record) {
    debugPrint('${record.level.name}: ${record.time}: ${record.message}');
  });
  runApp(const MainApp());
}
class MainApp extends StatelessWidget {
  const MainApp({super.key});
  @override
  Widget build(BuildContext context) {
    return ScreenUtilInit(
        designSize: const Size(750, 1624), // 设置设计稿尺寸
        minTextAdapt: true,
        splitScreenMode: true,
        builder: (context, child) {
          return GetMaterialApp(
            debugShowCheckedModeBanner: false,
            title: 'freefirend',
            theme: ThemeData(
              primarySwatch: Colors.blue,
            ),
            initialRoute: AppRoutes.INDEX,
            getPages: AppPages.pages,
          );
        });
  }
}

从入口文件看到 更新了 路由app_routes.dart,更新了要么框架 app_pages.dart

页面框架代码:

import 'package:get/get.dart';
import 'package:ff_flutter/screens/index.dart';
import 'package:ff_flutter/screens/register.dart';
import 'package:ff_flutter/screens/smslogin.dart' as sms;
import 'package:ff_flutter/screens/home_screen.dart';
import 'package:ff_flutter/screens/short_video_screen.dart';
import 'package:ff_flutter/screens/message_screen.dart';
import 'package:ff_flutter/screens/account_screen.dart';
import 'package:ff_flutter/routes/app_routes.dart';
import 'package:ff_flutter/controllers/index_controller.dart';
import 'package:ff_flutter/controllers/register_controller.dart';
import 'package:ff_flutter/controllers/sms_login_controller.dart';
class AppPages {
  static final pages = [
    GetPage(
      name: AppRoutes.INDEX,
      page: () => IndexScreen(),
      binding: BindingsBuilder(() {
        Get.lazyPut(() => IndexController());
      }),
    ),
    GetPage(
      name: AppRoutes.REGISTER,
      page: () => const RegisterScreen(),
      binding: BindingsBuilder(() {
        Get.lazyPut(() => RegisterController());
      }),
    ),
    GetPage(
      name: AppRoutes.SMS_LOGIN,
      page: () => const sms.SmsLoginScreen(),
      binding: BindingsBuilder(() {
        Get.lazyPut(() => SmsLoginController());
      }),
    ),
  ];
}

路由文件代码,

abstract class AppRoutes {
  static const INDEX = '/';
  static const REGISTER = '/register';
  static const SMS_LOGIN = '/sms-login';
}

创建了 control 文件,里面对页面进行了方法的文件创建和默认的内容,诸如注册的调用

import 'package:get/get.dart';
class RegisterController extends GetxController {
  final RxBool agreedToTerms = false.obs;
  final RxString selectedCountryCode = '+1'.obs;
  void updateAgreedToTerms(bool value) {
    agreedToTerms.value = value;
  }
  void updateSelectedCountryCode(String value) {
    selectedCountryCode.value = value;
  }
}

这段代码定义了一个名为 RegisterController 的类,继承自 GetxController。它包含两个可观察变量:agreedToTerms 表示用户是否同意条款,默认为 falseselectedCountryCode 表示选择的国家代码,默认为 +1。还提供了两个方法用于更新这些变量的值。

控制流图

mermaid

flowchart TD A[初始化 RegisterController] --> B{更新 agreedToTerms} B -->|调用 updateAgreedToTerms| C[设置 agreedToTerms 值] A --> D{更新 selectedCountryCode} D -->|调用 updateSelectedCountryCode| E[设置 selectedCountryCode 值]

整体主要是对框架进行了适配,此刻我发现同事把我打包图标默认的默认被换了,因此我建立APP打包的图标自定义

找到原图标,下载并保存

修改pubspec.yaml, 加入自定义图标代码

flutter_launcher_icons:
  image_path: "assets/icon/logo.png"  # 指定用于生成图标的源图像路径
  android: true  # 表示要为 Android 平台生成图标
  ios: true      # 表示要为 iOS 平台生成图标
  remove_alpha_ios: true  # 移除 iOS 图标中的透明通道

在资源目录加入assets\icons中logo.png文件

再来看看index.dart中对导航栏的书写,

import 'package:flutter/material.dart';
import 'package:ff_flutter/screens/register.dart'; // 导入 register.dart 文件
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:ff_flutter/routes/app_routes.dart';
import 'package:ff_flutter/screens/home_screen.dart';
import 'package:ff_flutter/screens/short_video_screen.dart';
import 'package:ff_flutter/screens/message_screen.dart';
import 'package:ff_flutter/screens/account_screen.dart';
class IndexScreen extends StatefulWidget {
  // 改为 StatefulWidget
  @override
  State<IndexScreen> createState() => _IndexScreenState();
}
class _IndexScreenState extends State<IndexScreen> {
  int _selectedIndex = 0;
  final List<Widget> _pages = [
    HomeScreen(),
    ShortVideoScreen(),
    MessageScreen(),
    AccountScreen(),
  ];
  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: const Color(0xFF1E1E1E),
      body: IndexedStack(
        index: _selectedIndex,
        children: _pages,
      ),
      bottomNavigationBar: Container(
        height: 168.h,
        decoration: const BoxDecoration(
          color: Color(0xFF1E1E1E),
        ),
        child: Theme(
          data: ThemeData(
            splashColor: Colors.transparent,
            highlightColor: Colors.transparent,
          ),
          child: BottomNavigationBar(
            items: const <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                icon: Icon(Icons.home),
                label: 'Home',
                activeIcon: Icon(Icons.home, color: Color(0xFFE7568C)),
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.play_circle_outline),
                label: 'Short Video',
                activeIcon:
                    Icon(Icons.play_circle_outline, color: Color(0xFFE7568C)),
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.notifications_none),
                label: 'Message',
                activeIcon:
                    Icon(Icons.notifications_none, color: Color(0xFFE7568C)),
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.person_outline),
                label: 'Account',
                activeIcon:
                    Icon(Icons.person_outline, color: Color(0xFFE7568C)),
              ),
            ],
            currentIndex: _selectedIndex,
            selectedItemColor: const Color(0xFFE7568C),
            unselectedItemColor: Colors.grey,
            backgroundColor: const Color(0xFF1E1E1E),
            type: BottomNavigationBarType.fixed,
            selectedFontSize: 24.sp,
            unselectedFontSize: 24.sp,
            iconSize: 48.sp,
            elevation: 0,
            onTap: _onItemTapped,
          ),
        ),
      ),
    );
  }
}
class DownloadButton extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ElevatedButton.icon(
      onPressed: () {
        // 处理下载逻辑
      },
      icon: const Icon(
        Icons.system_update_alt,
        size: 30,
        color: Color(0xfff1f1f1), // 设置图标颜色为 0xfff1f1f1
      ),
      label: const Text(
        "Download",
        style: TextStyle(
          color: Color(0xfff1f1f1),
          fontSize: 26,
          fontFamily: "PingFang SC",
          fontWeight: FontWeight.w800,
        ),
      ),
      style: ElevatedButton.styleFrom(
        backgroundColor:
            const Color(0xffe7568c), // 使用 backgroundColor 替代 primary
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(27.r),
        ),
        padding: EdgeInsets.symmetric(horizontal: 17.w, vertical: 9.h),
        minimumSize: Size(195.w, 54.h),
      ),
    );
  }
}
class CustomIconButton extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      width: 54.w,
      height: 54.h,
      child: Stack(
        children: [
          Container(
            width: 54.w,
            height: 54.h,
            decoration: const BoxDecoration(
              shape: BoxShape.circle,
              color: Color(0xff151313),
            ),
          ),
          Positioned.fill(
            child: Align(
              alignment: Alignment.center,
              child: const Icon(
                Icons.notifications,
                size: 36,
                color: Color(0xfff1f1f1), // 设置图标颜色为 0xfff1f1f1
              ),
            ),
          ),
        ],
      ),
    );
  }
}
class MoreButton extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisSize: MainAxisSize.min,
      mainAxisAlignment: MainAxisAlignment.start,
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        const Text(
          "more",
          style: TextStyle(
            color: Color(0xff929292),
            fontSize: 26,
          ),
        ),
        SizedBox(width: 10.w),
        Transform.rotate(
          angle: 3.14,
          child: Container(
            width: 26.w,
            height: 26.h,
            decoration: BoxDecoration(
              borderRadius: BorderRadius.circular(8.r),
            ),
            child: const Icon(
              Icons.arrow_back, // 替换为合适的图标
              size: 26,
              color: Color(0xfff1f1f1), // 设置图标颜色为 0xfff1f1f1
            ),
          ),
        ),
      ],
    );
  }
}

结束,最后我们再来看看打包问题,解决之前的报错 只需要对Gradle处理,以下是常用处理方式,gradlew clean解决了我们的问题

java.net.SocketException: Unexpected end of file from server 错误通常发生在 Gradle 尝试从服务器下载依赖项时遇到连接问题。以下是一些可能的解决方案:

  • 检查网络连接
  • 确保你的网络连接稳定。
  • 如果使用代理,请确保代理配置正确。
  • 清理 Gradle 缓存
  • 进入项目根目录,运行命令 gradlew clean 清理构建缓存。
  • 删除 .gradle 文件夹(位于用户主目录下)以清除全局 Gradle 缓存。
  • 更新 Gradle 和插件
  • 检查并更新项目的 Gradle 版本和 Android 插件版本到最新稳定版。
  • 修改 build.gradle 文件中的 distributionUrl 到最新的 Gradle 版本。
  • 检查依赖项
  • 确认 pubspec.yaml 中的所有依赖项都能正常访问。
  • 使用 flutter pub get 命令来获取 Dart/Flutter 依赖项。
  • 尝试离线模式(如果网络不稳定):
  • gradle.properties 文件中添加 org.gradle.offline=true 来启用 Gradle 离线模式。
  • 防火墙或杀毒软件干扰
  • 暂时禁用防火墙或杀毒软件,测试是否是它们阻止了 Gradle 的网络请求。
  • 重试构建
  • 有时候简单的重试可以解决问题,因为可能是临时的网络波动导致的。

但是又遇到了新的问题,

问题出在 Gradle 版本与 Java 版本不兼容。具体来说,Gradle 不支持当前使用的 Java 版本(Java 11 或更高版本)。以下是解决此问题的步骤

  1. 检查当前 Java 和 Gradle 版本
  • 运行 flutter doctor --verbose 检查当前使用的 Java 和 Gradle 版本。
  1. 更新 Gradle 版本
  • 打开项目中的 android/gradle/wrapper/gradle-wrapper.properties 文件。
  • 修改 distributionUrl 以使用一个与当前 Java 版本兼容的 Gradle 版本。例如:

properties

distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-all.zip

  1. 更新 Android Studio 的 JDK
  • 如果你使用的是 Android Studio,确保它使用的是与 Gradle 兼容的 JDK 版本。可以在 Android Studio 的设置中更改 JDK 版本:
  • 打开 File -> Project Structure -> SDK Location
  • 更改 JDK location 到一个兼容的 JDK 版本。
  1. 清理和重建项目
  • 清理 Gradle 缓存:

bash

cd android ./gradlew clean

  • 重新构建项目:

bash

flutter clean flutter pub get flutter build apk --release

最后我们成功解决问题,已经提交打包,发现,还是不兼容,这时候怎么办,我们需要用到 FVM (Flutter Version Manager)

由于错误发生在 flutter_tools 中,你还需要确保 Flutter 工具本身使用的 Gradle 版本是最新的。你可以通过以下步骤来更新 Flutter 工具的 Gradle 版本:

  1. 打开 Flutter SDK 目录下的 packages/flutter_tools/gradle/gradle-wrapper.properties 文件。
  2. 修改 distributionUrl 为最新的 Gradle 版本,例如:

properties

distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-all.zip

使用 FVM (Flutter Version Manager)

如果你使用多个 Flutter 版本,建议使用 FVM 来管理不同项目的 Flutter 版本,确保每个项目使用兼容的 Flutter 和 Gradle 版本。

通过以上步骤,你应该能够解决 Gradle 版本与 Java 版本不兼容的问题,并成功构建你的 Flutter 项目。如果问题仍然存在,请提供更多的日志输出(如 --stacktrace --info),以便进一步诊断。

使用 FVM(Flutter Version Manager)可以帮助你管理不同项目的 Flutter 版本,确保每个项目使用兼容的 Flutter 和 Gradle 版本。以下是详细的步骤来安装和配置 FVM:

安装 FVM

  1. 安装 FVM: 你可以通过以下命令全局安装 FVM:

bash

dart pub global activate fvm

  1. 将 FVM 添加到 PATH: 确保 FVM 的二进制文件路径已添加到你的系统 PATH 中。通常路径为 ~/.pub-cache/bin。你可以通过以下命令将其添加到当前终端会话中:

bash

export PATH="$PATH":"$HOME/.pub-cache/bin"

如果你想永久添加,请将上述命令添加到你的 shell 配置文件中(例如 .bashrc.zshrc .bash_profile)。

使用 FVM 初始化项目

  1. 初始化 FVM: 在你的项目根目录下运行以下命令以初始化 FVM:

bash

fvm install

  1. 选择 Flutter 版本: FVM 会自动从 fvm.yaml 文件中读取指定的 Flutter 版本。如果没有该文件,FVM 会提示你选择一个版本并创建 fvm.yaml 文件。你也可以手动编辑 fvm.yaml 文件来指定版本:

yaml

flutter_sdk: version: "3.7.12" # 替换为你需要的版本号

  1. 使用指定的 Flutter 版本: 运行以下命令以使用 FVM 管理的 Flutter 版本:

bash

fvm flutter --version

更新项目中的依赖项

  1. 获取 Dart/Flutter 依赖项: 使用 FVM 管理的 Flutter 版本来获取依赖项:

bash

fvm flutter pub get

  1. 清理和重建项目: 清理 Gradle 缓存并重新构建项目:

bash

cd android ../.fvm/flutter_sdk/bin/flutter clean ../.fvm/flutter_sdk/bin/flutter pub get ../.fvm/flutter_sdk/bin/flutter build apk --release

更新 Gradle 和 Java 版本

  1. 更新 Gradle 版本: 打开项目中的 android/gradle/wrapper/gradle-wrapper.properties 文件,修改 distributionUrl 以使用一个与当前 Java 版本兼容的 Gradle 版本。例如:

properties

distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-all.zip

  1. 更新 Android Studio 的 JDK: 如果你使用的是 Android Studio,确保它使用的是与 Gradle 兼容的 JDK 版本。可以在 Android Studio 的设置中更改 JDK 版本:
  • 打开 File -> Project Structure -> SDK Location
  • 更改 JDK location 到一个兼容的 JDK 版本。

检查环境变量配置

确保你的环境变量配置正确,特别是 JAVA_HOME PATH 变量,指向正确的 JDK 和 Gradle 安装路径。

示例流程

假设你已经安装了 FVM 并将其添加到 PATH 中,以下是完整的示例流程:

  1. 初始化 FVM 并选择 Flutter 版本:

bash

cd g:\clone\ff-flutter fvm install

  1. 使用 FVM 管理的 Flutter 版本检查当前版本:

bash

fvm flutter --version

  1. 获取 Dart/Flutter 依赖项:

bash

fvm flutter pub get

  1. 清理和重建项目:

bash

cd android ../.fvm/flutter_sdk/bin/flutter clean ../.fvm/flutter_sdk/bin/flutter pub get ../.fvm/flutter_sdk/bin/flutter build apk --release

目录
相关文章
|
1天前
|
人工智能 JavaScript 前端开发
Vue 性能革命:揭秘前端优化的终极技巧;Vue优化技巧,解决Vue项目卡顿问题
Vue在处理少量数据和有限dom的情况下技术已经非常成熟了,但现在随着AI时代的到来,海量数据场景会越来越多,Vue优化技巧也是必备技能。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
10天前
|
JSON 自然语言处理 前端开发
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
108 72
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
|
23天前
|
安全 前端开发 开发工具
【01】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-项目开发实战-优雅草卓伊凡拟开发一个一站式家政服务平台-前期筹备-暂定取名斑马家政软件系统-本项目前端开源-服务端采用优雅草蜻蜓Z系统-搭配ruoyi框架admin后台-全过程实战项目分享-从零开发到上线
【01】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-项目开发实战-优雅草卓伊凡拟开发一个一站式家政服务平台-前期筹备-暂定取名斑马家政软件系统-本项目前端开源-服务端采用优雅草蜻蜓Z系统-搭配ruoyi框架admin后台-全过程实战项目分享-从零开发到上线
61 5
【01】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-项目开发实战-优雅草卓伊凡拟开发一个一站式家政服务平台-前期筹备-暂定取名斑马家政软件系统-本项目前端开源-服务端采用优雅草蜻蜓Z系统-搭配ruoyi框架admin后台-全过程实战项目分享-从零开发到上线
|
25天前
|
缓存 Java 测试技术
【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
161 3
【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
|
1月前
|
JSON 前端开发 API
以项目登录接口为例-大前端之开发postman请求接口带token的请求测试-前端开发必学之一-如果要学会联调接口而不是纯写静态前端页面-这个是必学-本文以优雅草蜻蜓Q系统API为实践来演示我们如何带token请求接口-优雅草卓伊凡
以项目登录接口为例-大前端之开发postman请求接口带token的请求测试-前端开发必学之一-如果要学会联调接口而不是纯写静态前端页面-这个是必学-本文以优雅草蜻蜓Q系统API为实践来演示我们如何带token请求接口-优雅草卓伊凡
64 5
以项目登录接口为例-大前端之开发postman请求接口带token的请求测试-前端开发必学之一-如果要学会联调接口而不是纯写静态前端页面-这个是必学-本文以优雅草蜻蜓Q系统API为实践来演示我们如何带token请求接口-优雅草卓伊凡
|
1月前
|
开发工具 Android开发 iOS开发
零基础构建即时通讯开源项目OpenIM移动端-Flutter篇
OpenIM 为开发者提供开源即时通讯 SDK,作为 Twilio、Sendbird 等云服务的替代方案。借助 OpenIM,开发者可以构建安全可靠的即时通讯应用,如 WeChat、Zoom、Slack 等。 本仓库基于开源版 OpenIM SDK 开发,提供了一款基于 Flutter 的即时通讯应用。您可以使用此应用程序作为 OpenIM SDK 的参考实现。 开发环境 在开始开发之前,请确保您的系统已安装以下软件: 操作系统:macOS 14.6 或更高版本 Flutter:版本 3.24.5(根据官网步骤进行安装) Git:用于代码版本控制 同时,您需要确保已经部署了最
102 10
|
1月前
|
前端开发 安全 开发工具
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
178 90
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
1月前
|
Dart 前端开发 Android开发
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
56 4
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
Web App开发 移动开发 JavaScript
weex sdk集成到Android工程三. weex服务项目搭建
1. 前言 前面介绍了app本地调用js的方式(js文件放在assert目录下面),其实大部分都是调用远程js,本篇介绍app如何调用远程js文件。
1167 0
|
4月前
|
Java Linux API
Android SDK
【10月更文挑战第21天】
160 1

热门文章

最新文章

推荐镜像

更多