【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈

简介: 【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈

【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈

章节内容【03】

flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件

开发背景

接上一篇已经设计好目录,我们需要一步步来对应实现,另外此前注册页面完善样式bug-增加自定义可复用组件widgets

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

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

demo下载

实战开始

lib/
├── main.dart               # 应用入口文件
├── models/                 # 数据模型类
├── screens/                # 页面组件
│   ├── home_screen.dart    # 主页
│   ├── login_screen.dart   # 登录页面
│   └── register_screen.dart# 注册页面
├── widgets/                # 可复用的小部件
│   ├── custom_button.dart  # 自定义按钮
│   ├── custom_text_field.dart # 自定义文本框
│   └── ...
├── services/               # 网络请求、本地存储等服务
│   ├── api_service.dart    # API 请求服务
│   └── storage_service.dart# 本地存储服务
├── utils/                  # 工具类和辅助函数
│   ├── constants.dart      # 常量定义
│   ├── logger.dart         # 日志记录器配置
│   └── validators.dart     # 表单验证逻辑
└── theme/                  # 主题配置
    ├── app_theme.dart      # 主题样式配置

这是上一章我们规划的目录,但是这里明显└── theme/ 我们是用不上的 ,因此我们先把其他的建立起来

第一步,我们做的首页是一个register_screen注册首页,因此我们建立 register_screen.dart文件,然后我们要把main.dart入口文件的内容和注册页面的内容分开,因此

把main文件中只保留入口文件应该有的内容,整个注册页面的内容均放在register_screen.dart页面,并且实现启动app后第一个页面显示为register_screen.dart页面的内容

我们main.dart的内容为

#file:g:\clone\ff-flutter\lib\main.dart
import 'package:flutter/material.dart';
import 'package:logging/logging.dart';
import 'screens/register_screen.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 MaterialApp(
      debugShowCheckedModeBanner: false, // 设置这一属性为 false
      title: 'freefirend',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const RegisterScreen(), // 设置启动页面为 RegisterScreen
    );
  }
}

然后我们注册页面的内容为:

#file:g:\clone\ff-flutter\lib\screens\register_screen.dart
import 'package:flutter/material.dart';
import 'package:logging/logging.dart';
class RegisterScreen extends StatefulWidget {
  const RegisterScreen({super.key});
  @override
  State<RegisterScreen> createState() => _RegisterScreenState();
}
class _RegisterScreenState extends State<RegisterScreen> {
  // 示例国家地区号列表
  final List<String> countryCodes = ['+1', '+86', '+91', '+44', '+33'];
  // 默认选择的国家地区号
  String selectedCountryCode = '+1';
  // Checkbox 状态
  bool _agreedToTerms = false;
  @override
  Widget build(BuildContext context) {
    final logger = Logger('RegisterScreen');
    logger.info('Building RegisterScreen');
    return Scaffold(
      backgroundColor: const Color(0xFF1E1E1E), // 设置背景色为 #1E1E1E
      appBar: AppBar(
        title: const Text(
          'Free Friend',
          style: TextStyle(
            fontSize: 24.0, // 设置字体大小
            fontFamily: 'PingFang SC', // 设置字体为 PingFang SC
          ),
        ),
        centerTitle: true, // 居中标题
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              "Free Friend",
              style: TextStyle(
                color: Colors.white,
                fontSize: 61.87,
                fontFamily: "PingFang SC",
                fontWeight: FontWeight.w800,
              ),
            ),
            const SizedBox(height: 16.0),
            const Text(
              "Please login your account",
              style: TextStyle(
                color: Colors.white,
                fontSize: 32,
                fontFamily: "PingFang SC",
                fontWeight: FontWeight.w800,
              ),
            ),
            const SizedBox(height: 16.0),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,  // 使用 spaceBetween 对齐方式
              children: [
                Flexible(
                  flex: 1,  // 给 DropdownButtonFormField 分配一部分空间
                  child: DropdownButtonFormField<String>(
                    value: selectedCountryCode,
                    onChanged: (String? newValue) {
                      if (newValue != null) {
                        setState(() {
                          selectedCountryCode = newValue;
                        });
                      }
                    },
                    items: countryCodes.map<DropdownMenuItem<String>>((String value) {
                      return DropdownMenuItem<String>(
                        value: value,
                        child: Text(value),
                      );
                    }).toList(),
                    decoration: const InputDecoration(
                      labelText: '选择国家地区号',
                      border: OutlineInputBorder(),
                    ),
                    style: const TextStyle(fontSize: 16),  // 设置字体大小
                  ),
                ),
                const SizedBox(width: 8.0),
                Expanded(
                  flex: 2,  // 给 TextField 分配更多的空间
                  child: TextField(
                    decoration: const InputDecoration(
                      labelText: '请输入手机号',
                      border: OutlineInputBorder(),
                      hintStyle: TextStyle(color: Color(0xffa9a9a9)),
                    ),
                    keyboardType: TextInputType.phone,
                  ),
                ),
              ],
            ),
            const SizedBox(height: 16.0),
            TextField(
              decoration: const InputDecoration(
                labelText: '请输入密码',
                hintStyle: TextStyle(color: Color(0xffa9a9a9)),
                border: OutlineInputBorder(),
              ),
              obscureText: true,
            ),
            Row(
              mainAxisSize: MainAxisSize.min,
              mainAxisAlignment: MainAxisAlignment.start,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                Checkbox(
                  value: _agreedToTerms,
                  onChanged: (bool? value) {
                    setState(() {
                      _agreedToTerms = value ?? false;
                    });
                  },
                ),
                const SizedBox(width: 20),
                Text(
                  "You agree to our Terms",
                  style: TextStyle(
                    color: Colors.white,
                    fontSize: 32,
                    fontFamily: "PingFang SC",
                    fontWeight: FontWeight.w500,
                  ),
                ),
              ],
            ),
            const SizedBox(height: 24.0),
            ElevatedButton(
              onPressed: () {
                // 注册按钮点击事件
                logger.info('注册按钮被点击');
              },
              style: ElevatedButton.styleFrom(
                backgroundColor: Color(0xffe7568c), // 设置红色背景
                fixedSize: Size(630, 48), // 设置按钮宽度为 630
              ),
              child: Text(
                'Register',
                style: TextStyle(
                  color: Colors.white, // 设置文字颜色为白色
                  fontSize: 16.0, // 可以根据需要调整字体大小
                ),
              ),
            ),
            const SizedBox(height: 8.0),
            Expanded(
              child: Align(
                alignment: Alignment.bottomCenter,
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    Text(
                      "Already have an account?",
                      style: TextStyle(
                        color: Colors.white,
                        fontSize: 32,
                        fontFamily: "PingFang SC",
                        fontWeight: FontWeight.w800,
                      ),
                    ),
                    const SizedBox(height: 8.0),
                    OutlinedButton(
                      onPressed: () {
                        // 登录按钮点击事件
                        logger.info('登录按钮被点击');
                      },
                      style: OutlinedButton.styleFrom(
                        side: BorderSide(color: Colors.white, width: 2), // 设置边框颜色为白色
                        fixedSize: Size(630, 48), // 设置按钮宽度为 630
                        backgroundColor: Colors.transparent, // 去掉背景色
                      ),
                      child: Text(
                        'login',
                        style: TextStyle(
                          color: Colors.white, // 设置文字颜色为白色
                          fontSize: 16.0, // 可以根据需要调整字体大小
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

这里注意下

@override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false, // 设置这一属性为 false
      title: 'freefirend',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const RegisterScreen(), // 设置启动页面为 RegisterScreen
    );
  }

main中这里定义了第一个启动的页面,我们目前只有注册页面因此这里定制注册页,后续是肯定要改的,按照常规用户习惯,第一个界面应该是直播列表页面或者短视频列表页面才对。

很完美,不过我们发现最顶部的dubug标识消失了,但是debug内容没隐藏,因此

注释掉这段代码即可,因为这里是有用的有些页面看不出来是什么的时候。

我们注意到,两处细节要处理,第一处是地区选择这里不够显眼,第二处是输入手机号这里颜色也不对不显眼,

请输入手机号输入内容时候的文字需要改成 FFFFFF 颜色,把选择国家区号部分的数字也设置为FFFFFF颜色

我们需要对 register_screen.dart 文件进行相应的修改。具体步骤如下:

修改“请输入手机号”输入框的文字颜色:

在 TextField 的 style 属性中设置文字颜色为 FFFFFF。

修改“选择国家地区号”部分的数字颜色:

在 DropdownButtonFormField 的 style 属性中设置文字颜色为 FFFFFF。

decoration: const InputDecoration(
                      labelText: '选择国家地区号',
                      border: OutlineInputBorder(),
                    ),
                    style: const TextStyle(
                      fontSize: 16,
                      color: Colors.white, // 设置文字颜色为 FFFFFF
                    ),
                  ),
                ),
                const SizedBox(width: 8.0),
                Expanded(
                  flex: 2,  // 给 TextField 分配更多的空间
                  child: TextField(
                    decoration: const InputDecoration(
                      labelText: '请输入手机号',
                      border: OutlineInputBorder(),
                      hintStyle: TextStyle(color: Color(0xffa9a9a9)),
                    ),
                    style: const TextStyle(color: Colors.white), // 设置文字颜色为 FFFFFF
                    keyboardType: TextInputType.phone,
                  ),
                ),

也就是这一段代码了,

查看效果,很棒,但是这里还有问题,既然我们这个登录按钮和注册按钮在其他页面也能用的上,我们为什么不建立为自定义组件呢,因此这里我们需要复用,就要建立自定义组件,

诸多地方都要用的上,因此我们开始,等等,还发现个小问题,选择区号的,背景图颜色不对

那么修改以下代码:

decoration: const InputDecoration(
                      labelText: '选择国家地区号',
                      border: OutlineInputBorder(),
                    ),
                    style: const TextStyle(
                      fontSize: 16,
                      color: Colors.white, // 设置文字颜色为 FFFFFF
                    ),
                    dropdownColor: const Color(0xFF1E1E1E), // 设置弹窗背景色为 #1E1E1E
                  ),
                ),

细节到位,

在组件目录下我们建立blackbutton.dart 黑色按钮 和 pinkbutton.dart 粉色按钮

先扩展知识学一下

在Flutter中,自定义组件非常重要,可以提高代码的复用性和可维护性。将自定义组件放在 widgets 目录下,可以更好地组织代码,使项目结构更加清晰。这里是如何利用 widgets 目录来自定义和复用组件的示例。

widgets 目录的作用

widgets 目录通常用于存放自定义的小部件,这些小部件可能在应用的多个地方使用。通过将自定义组件集中在一个目录下,可以方便地管理和查找它们。

如何自定义复用组件

以下是一个简单的步骤,来创建和复用自定义组件:

  1. 创建一个新的 Dart 文件:在 widgets 目录下创建一个新的 Dart 文件,例如 custom_button.dart
  2. 定义自定义组件:在新文件中定义自定义组件。
  3. 在需要使用的地方导入和使用该组件

示范:

lib/
|-- widgets/
|   |-- custom_button.dart

自定义组件内容:

// lib/widgets/custom_button.dart
import 'package:flutter/material.dart';
class CustomButton extends StatelessWidget {
  final String text;
  final VoidCallback onPressed;
  CustomButton({required this.text, required this.onPressed});
  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: onPressed,
      child: Text(text),
    );
  }
}

调用自定义组件:

import 'package:flutter/material.dart';
import 'package:ff_social_app/widgets/custom_button.dart';
void main() {
  runApp(MyApp());
}
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('自定义组件示例'),
        ),
        body: Center(
          child: CustomButton(
            text: '点击我',
            onPressed: () {
              print('按钮被点击了');
            },
          ),
        ),
      ),
    );
  }
}

我们需要把注册按钮和登录按钮做成自定义组件方便复用,因此把Register按钮的做成自定义组件并且放在widgets目录下的pinkbutton.dart文件内,把logo登录按钮做成自定义组件并且放在widgets目录下的blackbutton.dart文件,需要保留目前的样式,并且在原register_screen.dart文件中 原位置中正常调用组件。

粉色按钮自定义组件内容:

#file:g:\clone\ff-flutter\lib\widgets\pinkbutton.dart
import 'package:flutter/material.dart';
import 'package:logging/logging.dart';
class PinkButton extends StatelessWidget {
  final String label;
  final VoidCallback onPressed;
  const PinkButton({
    required this.label,
    required this.onPressed,
    super.key,
  });
  @override
  Widget build(BuildContext context) {
    final logger = Logger('PinkButton');
    logger.info('Building PinkButton');
    return ElevatedButton(
      onPressed: onPressed,
      style: ElevatedButton.styleFrom(
        backgroundColor: const Color(0xffe7568c), // 设置红色背景
        fixedSize: const Size(630, 48), // 设置按钮宽度为 630
      ),
      child: Text(
        label,
        style: const TextStyle(
          color: Colors.white, // 设置文字颜色为白色
          fontSize: 16.0, // 可以根据需要调整字体大小
        ),
      ),
    );
  }
}

黑色按钮自定义组件内容:

#file:g:\clone\ff-flutter\lib\widgets\blackbutton.dart
import 'package:flutter/material.dart';
import 'package:logging/logging.dart';
class BlackButton extends StatelessWidget {
  final String label;
  final VoidCallback onPressed;
  const BlackButton({
    required this.label,
    required this.onPressed,
    super.key,
  });
  @override
  Widget build(BuildContext context) {
    final logger = Logger('BlackButton');
    logger.info('Building BlackButton');
    return OutlinedButton(
      onPressed: onPressed,
      style: OutlinedButton.styleFrom(
        side: const BorderSide(color: Colors.white, width: 2), // 设置边框颜色为白色
        fixedSize: const Size(630, 48), // 设置按钮宽度为 630
        backgroundColor: Colors.transparent, // 去掉背景色
      ),
      child: Text(
        label,
        style: const TextStyle(
          color: Colors.white, // 设置文字颜色为白色
          fontSize: 16.0, // 可以根据需要调整字体大小
        ),
      ),
    );
  }
}

然后我们在注册页引用这两个组件,在此同时,我们就需要简化我们原先已经写好的,避免重复,代码如下:

import 'package:flutter/material.dart';
import 'package:logging/logging.dart';
import 'package:ff_flutter/lib/widgets/pinkbutton.dart'; // 引入 PinkButton
import 'package:ff_flutter/lib/widgets/blackbutton.dart'; // 引入 BlackButton
class RegisterScreen extends StatefulWidget {
  const RegisterScreen({super.key});
  @override
  State<RegisterScreen> createState() => _RegisterScreenState();
}
class _RegisterScreenState extends State<RegisterScreen> {
  // 示例国家地区号列表
  final List<String> countryCodes = ['+1', '+86', '+91', '+44', '+33'];
  // 默认选择的国家地区号
  String selectedCountryCode = '+1';
  // Checkbox 状态
  bool _agreedToTerms = false;
  @override
  Widget build(BuildContext context) {
    final logger = Logger('RegisterScreen');
    logger.info('Building RegisterScreen');
    return Scaffold(
      backgroundColor: const Color(0xFF1E1E1E), // 设置背景色为 #1E1E1E
      // appBar: AppBar(
      //   title: const Text(
      //     'Free Friend',
      //     style: TextStyle(
      //       fontSize: 24.0, // 设置字体大小
      //       fontFamily: 'PingFang SC', // 设置字体为 PingFang SC
      //     ),
      //   ),
      //   centerTitle: true, // 居中标题
      // ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              "Free Friend",
              style: TextStyle(
                color: Colors.white,
                fontSize: 61.87,
                fontFamily: "PingFang SC",
                fontWeight: FontWeight.w800,
              ),
            ),
            const SizedBox(height: 16.0),
            const Text(
              "Please login your account",
              style: TextStyle(
                color: Colors.white,
                fontSize: 32,
                fontFamily: "PingFang SC",
                fontWeight: FontWeight.w800,
              ),
            ),
            const SizedBox(height: 16.0),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,  // 使用 spaceBetween 对齐方式
              children: [
                Flexible(
                  flex: 1,  // 给 DropdownButtonFormField 分配一部分空间
                  child: DropdownButtonFormField<String>(
                    value: selectedCountryCode,
                    onChanged: (String? newValue) {
                      if (newValue != null) {
                        setState(() {
                          selectedCountryCode = newValue;
                        });
                      }
                    },
                    items: countryCodes.map<DropdownMenuItem<String>>((String value) {
                      return DropdownMenuItem<String>(
                        value: value,
                        child: Text(
                          value,
                          style: const TextStyle(color: Colors.white), // 设置文字颜色为 FFFFFF
                        ),
                      );
                    }).toList(),
                    decoration: const InputDecoration(
                      labelText: '选择国家地区号',
                      border: OutlineInputBorder(),
                    ),
                    style: const TextStyle(
                      fontSize: 16,
                      color: Colors.white, // 设置文字颜色为 FFFFFF
                    ),
                    dropdownColor: const Color(0xFF1E1E1E), // 设置弹窗背景色为 #1E1E1E
                  ),
                ),
                const SizedBox(width: 8.0),
                Expanded(
                  flex: 2,  // 给 TextField 分配更多的空间
                  child: TextField(
                    decoration: const InputDecoration(
                      labelText: '请输入手机号',
                      border: OutlineInputBorder(),
                      hintStyle: TextStyle(color: Color(0xffa9a9a9)),
                    ),
                    style: const TextStyle(color: Colors.white), // 设置输入文字颜色为 FFFFFF
                    keyboardType: TextInputType.phone,
                  ),
                ),
              ],
            ),
            const SizedBox(height: 16.0),
            TextField(
              decoration: const InputDecoration(
                labelText: '请输入密码',
                hintStyle: TextStyle(color: Color(0xffa9a9a9)),
                border: OutlineInputBorder(),
              ),
              obscureText: true,
              style: const TextStyle(color: Colors.white), // 设置输入文字颜色为 FFFFFF
            ),
            Row(
              mainAxisSize: MainAxisSize.min,
              mainAxisAlignment: MainAxisAlignment.start,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                Checkbox(
                  value: _agreedToTerms,
                  onChanged: (bool? value) {
                    setState(() {
                      _agreedToTerms = value ?? false;
                    });
                  },
                ),
                const SizedBox(width: 20),
                Text(
                  "You agree to our Terms",
                  style: TextStyle(
                    color: Colors.white,
                    fontSize: 32,
                    fontFamily: "PingFang SC",
                    fontWeight: FontWeight.w500,
                  ),
                ),
              ],
            ),
            const SizedBox(height: 24.0),
            PinkButton(
              label: 'Register',
              onPressed: () {
                // 注册按钮点击事件
                logger.info('注册按钮被点击');
              },
            ),
            const SizedBox(height: 8.0),
            Expanded(
              child: Align(
                alignment: Alignment.bottomCenter,
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    Text(
                      "Already have an account?",
                      style: TextStyle(
                        color: Colors.white,
                        fontSize: 32,
                        fontFamily: "PingFang SC",
                        fontWeight: FontWeight.w800,
                      ),
                    ),
                    const SizedBox(height: 8.0),
                    BlackButton(
                      label: 'login',
                      onPressed: () {
                        // 登录按钮点击事件
                        logger.info('登录按钮被点击');
                      },
                    ),
                  ],
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

本文完成,本文对组件进行了完善修改,并且创建了自定义组件,其次还规划了我们整体目录并且创建了对应文件,下一篇我们即可把所有的注册页面写完,毕竟自定义组件都创建了,写几个页面还不是分分钟的事情?

目录
相关文章
|
人工智能 JSON 小程序
【一步步开发AI运动APP】七、自定义姿态动作识别检测——之规则配置检测
本文介绍了如何通过【一步步开发AI运动APP】系列博文,利用自定义姿态识别检测技术开发高性能的AI运动应用。核心内容包括:1) 自定义姿态识别检测,满足人像入镜、动作开始/停止等需求;2) Pose-Calc引擎详解,支持角度匹配、逻辑运算等多种人体分析规则;3) 姿态检测规则编写与执行方法;4) 完整示例展示左右手平举姿态检测。通过这些技术,开发者可轻松实现定制化运动分析功能。
|
Android开发 数据安全/隐私保护 开发者
Android自定义view之模仿登录界面文本输入框(华为云APP)
本文介绍了一款自定义输入框的实现,包含静态效果、hint值浮动动画及功能扩展。通过组合多个控件完成界面布局,使用TranslateAnimation与AlphaAnimation实现hint文字上下浮动效果,支持密码加密解密显示、去除键盘回车空格输入、光标定位等功能。代码基于Android平台,提供完整源码与attrs配置,方便复用与定制。希望对开发者有所帮助。
273 0
|
9月前
|
人工智能 小程序 搜索推荐
【一步步开发AI运动APP】十二、自定义扩展新运动项目2
本文介绍如何基于uni-app运动识别插件实现“双手并举”自定义扩展运动,涵盖动作拆解、姿态检测规则构建及运动分析器代码实现,助力开发者打造个性化AI运动APP。
|
11月前
|
存储 Java PHP
轻量化短视频电商直播带货APP源码全解析:核心功能与设计流程​
在电商直播热潮下,开发专属直播带货APP成为抢占市场关键。本文详解原生开发轻量化APP的核心功能与全流程设计,涵盖用户登录、商品浏览、直播互动、购物车、订单及售后功能,并介绍安卓端Java、苹果端Object-C、后台PHP的技术实现,助力打造高效优质的直播电商平台。
|
存储 消息中间件 前端开发
PHP后端与uni-app前端协同的校园圈子系统:校园社交场景的跨端开发实践
校园圈子系统校园论坛小程序采用uni-app前端框架,支持多端运行,结合PHP后端(如ThinkPHP/Laravel),实现用户认证、社交关系管理、动态发布与实时聊天功能。前端通过组件化开发和uni.request与后端交互,后端提供RESTful API处理业务逻辑并存储数据于MySQL。同时引入Redis缓存热点数据,RabbitMQ处理异步任务,优化系统性能。核心功能包括JWT身份验证、好友系统、WebSocket实时聊天及活动管理,确保高效稳定的用户体验。
746 4
PHP后端与uni-app前端协同的校园圈子系统:校园社交场景的跨端开发实践
|
安全 算法 小程序
【03】微信支付商户申请下户到配置完整流程-微信开放平台创建APP应用-填写上传基础资料-生成安卓证书-获取Apk签名-申请+配置完整流程-优雅草卓伊凡
【03】微信支付商户申请下户到配置完整流程-微信开放平台创建APP应用-填写上传基础资料-生成安卓证书-获取Apk签名-申请+配置完整流程-优雅草卓伊凡
1073 28
【03】微信支付商户申请下户到配置完整流程-微信开放平台创建APP应用-填写上传基础资料-生成安卓证书-获取Apk签名-申请+配置完整流程-优雅草卓伊凡
|
人工智能 小程序 API
【一步步开发AI运动APP】九、自定义姿态动作识别检测——之关键点追踪
本文介绍了【一步步开发AI运动APP】系列中的关键点追踪技术。此前分享的系列博文助力开发者打造了多种AI健身场景的小程序,而新系列将聚焦性能更优的AI运动APP开发。文章重点讲解了“关键点位变化追踪”能力,适用于动态运动(如跳跃)分析,弥补了静态姿态检测的不足。通过`pose-calc`插件,开发者可设置关键点(如鼻子)、追踪方向(X或Y轴)及变化幅度。示例代码展示了如何在`uni-app`框架中使用`createPointTracker`实现关键点追踪,并结合人体识别结果完成动态分析。具体实现可参考文档与Demo示例。
|
前端开发 算法 NoSQL
前端uin后端php社交软件源码,快速构建属于你的交友平台
这是一款功能全面的社交软件解决方案,覆盖多种场景需求。支持即时通讯(一对一聊天、群聊、文件传输、语音/视频通话)、内容动态(发布、点赞、评论)以及红包模块(接入支付宝、微信等第三方支付)。系统采用前后端分离架构,前端基于 UniApp,后端使用 PHP 框架(如 Laravel/Symfony),配合 MySQL/Redis 和自建 Socket 服务实现高效实时通信。提供用户认证(JWT 集成)、智能匹配算法等功能,助力快速上线,显著节约开发成本。
533 2
前端uin后端php社交软件源码,快速构建属于你的交友平台
《仿盒马》app开发技术分享-- 自定义标题栏&商品详情初探(9)
上一节我们实现了顶部toolbar的地址选择,会员码展示,首页的静态页面就先告一段落,这节我们来实现商品列表item的点击传值、自定义标题栏。
144 0
|
小程序
【04】微信支付商户申请下户到配置完整流程-微信开放平台移动APP应用通过-微信商户继续申请-微信开户函-视频声明-以及对公打款验证-申请+配置完整流程-优雅草卓伊凡
【04】微信支付商户申请下户到配置完整流程-微信开放平台移动APP应用通过-微信商户继续申请-微信开户函-视频声明-以及对公打款验证-申请+配置完整流程-优雅草卓伊凡
1137 1
【04】微信支付商户申请下户到配置完整流程-微信开放平台移动APP应用通过-微信商户继续申请-微信开户函-视频声明-以及对公打款验证-申请+配置完整流程-优雅草卓伊凡

热门文章

最新文章

  • 1
    前端如何存储数据:Cookie、LocalStorage 与 SessionStorage 全面解析
    1226
  • 2
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(九):强势分析Animation动画各类参数;从播放时间、播放方式、播放次数、播放方向、播放状态等多个方面,完全了解CSS3 Animation
    550
  • 3
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(八):学习transition过渡属性;本文学习property模拟、duration过渡时间指定、delay时间延迟 等多个参数
    425
  • 4
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(七):学习ransform属性;本文学习 rotate旋转、scale缩放、skew扭曲、tanslate移动、matrix矩阵 多个参数
    420
  • 5
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(六):全方面分析css的Flex布局,从纵、横两个坐标开始进行居中、两端等元素分布模式;刨析元素间隔、排序模式等
    537
  • 6
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(五):背景属性;float浮动和position定位;详细分析相对、绝对、固定三种定位方式;使用浮动并清除浮动副作用
    712
  • 7
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(四):元素盒子模型;详细分析边框属性、盒子外边距
    1358
  • 8
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(三):元素继承关系、层叠样式规则、字体属性、文本属性;针对字体和文本作样式修改
    306
  • 9
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(二):CSS伪类:UI伪类、结构化伪类;通过伪类获得子元素的第n个元素;创建一个伪元素展示在页面中;获得最后一个元素;处理聚焦元素的样式
    1135
  • 10
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(一):CSS发展史;CSS样式表的引入;CSS选择器使用,附带案例介绍
    494