【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈

简介: 【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈

【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈

章节内容【07】

【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面

开发背景

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

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

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

demo下载

实战开始

我们新建 index.dart,首先写页面,插入基础内容有两种,在Flutter中,Scaffold 和 Container 是两个非常重要的小部件,它们分别有不同的用途和功能。

这两个小部件写法是一直的,但是写页面大框架的时候我们需要选择Scaffold,我们在写底部菜单栏就应该选择 Container 。

扩展知识

return Scaffold( 和return Container( 的区别是什么

在Flutter中,Scaffold Container 是两个非常重要的小部件,它们分别有不同的用途和功能。

Scaffold

Scaffold 是一个用于实现Material Design布局结构的控件,通常用于创建一个完整的应用页面。它提供了一些特有的属性和功能,能够轻松实现应用常见的布局元素,例如应用栏(AppBar)、抽屉(Drawer)、浮动操作按钮(FloatingActionButton)、底部导航栏(BottomNavigationBar)等。

dart

Scaffold(
  appBar: AppBar(
    title: Text('My App'),
  ),
  body: Center(
    child: Text('Hello, world!'),
  ),
  floatingActionButton: FloatingActionButton(
    onPressed: () {},
    child: Icon(Icons.add),
  ),
)

Container

Container 是一个通用的小部件,它可以包含单个子组件并允许进行一些简单的布局配置。Container 主要用于包装和装饰子组件,比如设置边距、内边距、对齐方式、背景颜色、边框等属性。与 Scaffold 不同,Container 不提供预定义的布局结构。

dart

Container(
  padding: EdgeInsets.all(16.0),
  margin: EdgeInsets.all(16.0),
  alignment: Alignment.center,
  color: Colors.blue,
  child: Text(
    'Hello, world!',
    style: TextStyle(color: Colors.white),
  ),
)

总结

  • Scaffold:
  • 主要用于创建包含应用栏、抽屉、底部导航栏等常见布局元素的完整应用页面。
  • 提供了许多预定义的布局结构和功能。
  • Container:
  • 用于包装和装饰单个子组件,可以设置边距、内边距、对齐方式、背景颜色等属性。
  • 更通用但不提供预定义的布局结构。

我们插入

class IndexScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Color(0xFF1E1E1E), // 设置背景颜色为 #1E1E1E
      appBar: AppBar(
        title: Text('Index Screen'),
      ),
      body: Center(
        child: Text('Welcome to the Index Screen'),
      ),
    );
  }
}

首先我们来做首页:

我们再将页面其他内容 写入 scaffold 里面,正确融入进去

通常,我们会使用 Column 和 Row 来组织这些组件来实现,

当写顶部左边文字后,写右边下载图标和按钮,我们发现 iconlogo 不对,

import 'package:flutter/material.dart';
import 'package:logging/logging.dart';
class IndexScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Color(0xFF1E1E1E), // 设置背景颜色为 #1E1E1E
      appBar: AppBar(
        title: Text('Index Screen'),
      ),
      body: Column(
        children: [
          Padding(
            padding: const EdgeInsets.only(left: 16, top: 16, right: 16),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Text(
                  "Free Friend",
                  style: TextStyle(
                    color: Color(0xfff1f1f1),
                    fontSize: 32,
                    fontFamily: "SansSerif",
                    fontWeight: FontWeight.w700,
                  ),
                ),
                DownloadButton(),
              ],
            ),
          ),
          // 其他内容可以继续添加在这里
          Expanded(
            child: Center(
              child: Text('Welcome to the Index Screen'),
            ),
          ),
        ],
      ),
    );
  }
}
class DownloadButton extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ElevatedButton.icon(
      onPressed: () {
        // 处理下载逻辑
      },
      icon: FlutterLogo(size: 30),
      label: Text(
        "Download",
        style: TextStyle(
          color: Color(0xfff1f1f1),
          fontSize: 26,
          fontFamily: "PingFang SC",
          fontWeight: FontWeight.w800,
        ),
      ),
      style: ElevatedButton.styleFrom(
        primary: Color(0xffe7568c),
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(27),
        ),
        padding: EdgeInsets.symmetric(horizontal: 17, vertical: 9),
        minimumSize: Size(195, 54),
      ),
    );
  }
}

我们替换图标为

icon: Icon(Icons.system_update_alt, size: 30),

扩展知识-关于flutter图标库的

Flutter 提供了一整套 Material Design 图标库,包含了数百个常用图标。你可以使用这些图标来实现多种设计需求。Material Icons 是一个非常丰富的图标库,每个图标都有一个唯一的名称和代码点,可以在代码中直接引用。

使用示例

要在Flutter中使用这些图标,你需要导入 flutter/material.dart 包,然后使用 Icon 小部件和 Icons 类来引用图标。

dart

import 'package:flutter/material.dart';
void main() {
  runApp(MyApp());
}
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter Icons 示例'),
        ),
        body: Center(
          child: Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Icon(Icons.home, size: 50.0), // Home 图标
              SizedBox(width: 20),
              Icon(Icons.favorite, size: 50.0, color: Colors.red), // Favorite 图标
              SizedBox(width: 20),
              Icon(Icons.settings, size: 50.0), // Settings 图标
            ],
          ),
        ),
      ),
    );
  }
}

常用图标列表

以下是一些常用的图标和它们的名称:

图标

名称

用法

Icons.home

Icon(Icons.home)

Icons.favorite

Icon(Icons.favorite)

Icons.settings

Icon(Icons.settings)

Icons.search

Icon(Icons.search)

Icons.account_circle

Icon(Icons.account_circle)

Icons.add

Icon(Icons.add)

Icons.email

Icon(Icons.email)

Icons.alarm

Icon(Icons.alarm)

Icons.camera_alt

Icon(Icons.camera_alt)

Icons.check_circle

Icon(Icons.check_circle)

这些只是 Flutter Material Icons 库中的一小部分。要查看完整的图标列表和它们的名称,你可以访问 Material Icons 库,并在代码中相应地使用 Icons.<icon_name> 来引用图标。

以下是我们的代码 但是我们发现问题:

The named parameter ‘primary’ isn’t defined.
Try correcting the name to an existing named parameter’s name, or defining a named parameter with the name ‘primary’.

提示primary未定义

在 Flutter 中,ElevatedButton.styleFrom 方法并没有 primary 这个命名参数。相反,你应该使用 primaryColor 或 backgroundColor 来设置按钮的背景颜色。

import 'package:flutter/material.dart';
import 'package:logging/logging.dart';
class IndexScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Color(0xFF1E1E1E), // 设置背景颜色为 #1E1E1E
      appBar: AppBar(
        title: Text('Index Screen'),
      ),
      body: Column(
        children: [
          Padding(
            padding: const EdgeInsets.only(left: 16, top: 16, right: 16),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Text(
                  "Free Friend",
                  style: TextStyle(
                    color: Color(0xfff1f1f1),
                    fontSize: 32,
                    fontFamily: "SansSerif",
                    fontWeight: FontWeight.w700,
                  ),
                ),
                DownloadButton(),
              ],
            ),
          ),
          // 其他内容可以继续添加在这里
          Expanded(
            child: Center(
              child: Text('Welcome to the Index Screen'),
            ),
          ),
        ],
      ),
    );
  }
}
class DownloadButton extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ElevatedButton.icon(
      onPressed: () {
        // 处理下载逻辑
      },
      icon: Icon(Icons.system_update_alt, size: 30),
      label: Text(
        "Download",
        style: TextStyle(
          color: Color(0xfff1f1f1),
          fontSize: 26,
          fontFamily: "PingFang SC",
          fontWeight: FontWeight.w800,
        ),
      ),
      style: ElevatedButton.styleFrom(
        primary: Color(0xffe7568c),
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(27),
        ),
        padding: EdgeInsets.symmetric(horizontal: 17, vertical: 9),
        minimumSize: Size(195, 54),
      ),
    );
  }
}

扩展知识

在Flutter中,primary backgroundColor 都是用于设置颜色的属性,但它们用于不同的场景和目的。

primary

primary 颜色通常用于应用的主要颜色。这是Material Design中的一个核心概念,用于突出显示应用程序的品牌颜色和主要UI元素。它在应用的许多地方都会被用到,例如应用栏、浮动操作按钮(FAB)等。

dart

import 'package:flutter/material.dart';
void main() {
  runApp(MyApp());
}
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        primaryColor: Colors.blue, // 设置应用的主要颜色
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('Primary Color 示例'),
        ),
        body: Center(
          child: ElevatedButton(
            onPressed: () {},
            child: Text('按钮'),
          ),
        ),
      ),
    );
  }
}

backgroundColor

backgroundColor 用于设置组件或容器的背景颜色。它可以用于多种小部件,例如 ContainerScaffold AppBar 等。使用 backgroundColor 属性可以更具体地控制某个小部件的背景颜色。

dart

import 'package:flutter/material.dart';
void main() {
  runApp(MyApp());
}
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        backgroundColor: Colors.grey[200], // 设置 Scaffold 的背景颜色
        appBar: AppBar(
          title: Text('BackgroundColor 示例'),
          backgroundColor: Colors.blue, // 设置 AppBar 的背景颜色
        ),
        body: Center(
          child: Container(
            width: 200,
            height: 200,
            color: Colors.white, // 设置 Container 的背景颜色
            child: Center(child: Text('Hello, world!')),
          ),
        ),
      ),
    );
  }
}

总结

  • primary:
  • 用于设置应用的主要颜色。
  • 通常在主题中配置,影响整个应用的主要颜色元素。
  • 例如:ThemeData(primaryColor: Colors.blue)
  • backgroundColor:
  • 用于设置特定小部件或容器的背景颜色。
  • 可以单独配置,不影响其他小部件。
  • 例如:Container(color: Colors.white)Scaffold(backgroundColor: Colors.grey[200])

大白话 就是,小部件用backgroundColor,整个应用主题颜色采用primary,(关于创建切换theme主题才用的到)

我们社交app就一个模板,所以用不上,接下来我们放入 右侧的图标按钮以及下方的图标和文字,以下是代码:

import 'package:flutter/material.dart';
class IndexScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Color(0xFF1E1E1E), // 设置背景颜色为 #1E1E1E
      // appBar: AppBar(
      //   title: Text('Index Screen'),
      // ),
      body: Column(
        children: [
          Padding(
            padding: const EdgeInsets.only(left: 16, top: 16, right: 16),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Text(
                  "Free Friend",
                  style: TextStyle(
                    color: Color(0xfff1f1f1),
                    fontSize: 32,
                    fontFamily: "SansSerif",
                    fontWeight: FontWeight.w700,
                  ),
                ),
                Row(
                  children: [
                    DownloadButton(),
                    SizedBox(width: 16), // 添加间距
                    CustomIconButton(),
                  ],
                ),
              ],
            ),
          ),
          SizedBox(height: 16), // 添加间距
          Padding(
            padding: const EdgeInsets.only(left: 16),
            child: Row(
              mainAxisSize: MainAxisSize.min,
              mainAxisAlignment: MainAxisAlignment.start,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Container(
                  width: 36,
                  height: 36,
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.circular(8),
                    color: Color(0xffe7568c), // 设置背景颜色为 0xffe7568c
                  ),
                  child: Icon(
                    Icons.location_on,
                    size: 36,
                    color: Color(0xfff1f1f1), // 设置图标颜色为 0xfff1f1f1
                  ),
                ),
                SizedBox(width: 10),
                Text(
                  "America",
                  style: TextStyle(
                    color: Color(0xfff1f1f1),
                    fontSize: 32,
                    fontFamily: "SansSerif",
                    fontWeight: FontWeight.w700,
                  ),
                ),
              ],
            ),
          ),
          // 其他内容可以继续添加在这里
          Expanded(
            child: Center(
              child: Text('Welcome to the Index Screen'),
            ),
          ),
        ],
      ),
    );
  }
}
class DownloadButton extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ElevatedButton.icon(
      onPressed: () {
        // 处理下载逻辑
      },
      icon: Icon(
        Icons.system_update_alt,
        size: 30,
        color: Color(0xfff1f1f1), // 设置图标颜色为 0xfff1f1f1
      ),
      label: Text(
        "Download",
        style: TextStyle(
          color: Color(0xfff1f1f1),
          fontSize: 26,
          fontFamily: "PingFang SC",
          fontWeight: FontWeight.w800,
        ),
      ),
      style: ElevatedButton.styleFrom(
        backgroundColor: Color(0xffe7568c), // 使用 backgroundColor 替代 primary
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(27),
        ),
        padding: EdgeInsets.symmetric(horizontal: 17, vertical: 9),
        minimumSize: Size(195, 54),
      ),
    );
  }
}
class CustomIconButton extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      width: 54,
      height: 54,
      child: Stack(
        children: [
          Container(
            width: 54,
            height: 54,
            decoration: BoxDecoration(
              shape: BoxShape.circle,
              color: Color(0xff151313),
            ),
          ),
          Positioned.fill(
            child: Align(
              alignment: Alignment.center,
              child: Icon(
                Icons.notifications,
                size: 36,
                color: Color(0xfff1f1f1), // 设置图标颜色为 0xfff1f1f1
              ),
            ),
          ),
        ],
      ),
    );
  }
}

接着我们做下面的定位按钮以及文字,

如何将一个容器完全放置于左侧,使用 Padding 组件为 Row 添加左侧内边距 const EdgeInsets.only(left: 16),以确保整个容器放置在左侧,
以下是代码文件:

以下代码"America" 及其前面的图标 以及前面的图标 已经设置了容器在左侧,为什么还是显示在屏幕的中间
import 'package:flutter/material.dart';
class IndexScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Color(0xFF1E1E1E), // 设置背景颜色为 #1E1E1E
      body: Column(
        children: [
          Padding(
            padding: const EdgeInsets.only(left: 16, top: 16, right: 16),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Text(
                  "Free Friend",
                  style: TextStyle(
                    color: Color(0xfff1f1f1),
                    fontSize: 32,
                    fontFamily: "SansSerif",
                    fontWeight: FontWeight.w700,
                  ),
                ),
                Row(
                  children: [
                    DownloadButton(),
                    SizedBox(width: 16), // 添加间距
                    CustomIconButton(),
                  ],
                ),
              ],
            ),
          ),
          SizedBox(height: 16), // 添加间距
          Padding(
            padding: const EdgeInsets.only(left: 16),
            child: Row(
              mainAxisSize: MainAxisSize.min,
              mainAxisAlignment: MainAxisAlignment.start,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Container(
                  width: 36,
                  height: 36,
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.circular(8),
                    color: Color(0xffe7568c), // 设置背景颜色为 0xffe7568c
                  ),
                  child: Icon(
                    Icons.location_on,
                    size: 36,
                    color: Color(0xfff1f1f1), // 设置图标颜色为 0xfff1f1f1
                  ),
                ),
                SizedBox(width: 10),
                Text(
                  "America",
                  style: TextStyle(
                    color: Color(0xfff1f1f1),
                    fontSize: 32,
                    fontFamily: "SansSerif",
                    fontWeight: FontWeight.w700,
                  ),
                ),
              ],
            ),
          ),
          Expanded(
            child: Center(
              child: Text('Welcome to the Index Screen'),
            ),
          ),
        ],
      ),
    );
  }
}
class DownloadButton extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ElevatedButton.icon(
      onPressed: () {
        // 处理下载逻辑
      },
      icon: Icon(
        Icons.system_update_alt,
        size: 30,
        color: Color(0xfff1f1f1), // 设置图标颜色为 0xfff1f1f1
      ),
      label: Text(
        "Download",
        style: TextStyle(
          color: Color(0xfff1f1f1),
          fontSize: 26,
          fontFamily: "PingFang SC",
          fontWeight: FontWeight.w800,
        ),
      ),
      style: ElevatedButton.styleFrom(
        backgroundColor: Color(0xffe7568c), // 使用 backgroundColor 替代 primary
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(27),
        ),
        padding: EdgeInsets.symmetric(horizontal: 17, vertical: 9),
        minimumSize: Size(195, 54),
      ),
    );
  }
}
class CustomIconButton extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      width: 54,
      height: 54,
      child: Stack(
        children: [
          Container(
            width: 54,
            height: 54,
            decoration: BoxDecoration(
              shape: BoxShape.circle,
              color: Color(0xff151313),
            ),
          ),
          Positioned.fill(
            child: Align(
              alignment: Alignment.center,
              child: Icon(
                Icons.notifications,
                size: 36,
                color: Color(0xfff1f1f1), // 设置图标颜色为 0xfff1f1f1
              ),
            ),
          ),
        ],
      ),
    );
  }
}

但是实际并没有到左侧,因为需要进行如下处理,可以将 CrossAxisAlignment.start 添加到 Column 和 Row 的交叉轴对齐属性中,在 Column 中添加了 crossAxisAlignment: CrossAxisAlignment.start 属性,以确保所有子元素在交叉轴上对齐到左侧。这应该能使 “America” 及其前面的图标对齐到左侧,而不是显示在屏幕的中间。

import 'package:flutter/material.dart';
class IndexScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: const Color(0xFF1E1E1E), // 设置背景颜色为 #1E1E1E
      body: Column(
        crossAxisAlignment: CrossAxisAlignment.start, // 添加这个属性
        children: [
          Padding(
            padding: const EdgeInsets.only(left: 16, top: 16, right: 16),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                const Text(
                  "Free Friend",
                  style: TextStyle(
                    color: Color(0xfff1f1f1),
                    fontSize: 32,
                    fontFamily: "SansSerif",
                    fontWeight: FontWeight.w700,
                  ),
                ),
                Row(
                  children: [
                    DownloadButton(),
                    const SizedBox(width: 16), // 添加间距
                    CustomIconButton(),
                  ],
                ),
              ],
            ),
          ),
          const SizedBox(height: 16), // 添加间距
          Padding(
            padding: const EdgeInsets.only(left: 16),
            child: Row(
              mainAxisSize: MainAxisSize.min,
              mainAxisAlignment: MainAxisAlignment.start,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Container(
                  width: 36,
                  height: 36,
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.circular(8),
                    color: const Color(0xffe7568c), // 设置背景颜色为 0xffe7568c
                  ),
                  child: const Icon(
                    Icons.location_on,
                    size: 36,
                    color: Color(0xfff1f1f1), // 设置图标颜色为 0xfff1f1f1
                  ),
                ),
                const SizedBox(width: 10),
                const Text(
                  "America",
                  style: TextStyle(
                    color: Color(0xfff1f1f1),
                    fontSize: 32,
                    fontFamily: "SansSerif",
                    fontWeight: FontWeight.w700,
                  ),
                ),
              ],
            ),
          ),
          Expanded(
            child: Center(
              child: const Text('Welcome to the Index Screen'),
            ),
          ),
        ],
      ),
    );
  }
}
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),
        ),
        padding: const EdgeInsets.symmetric(horizontal: 17, vertical: 9),
        minimumSize: const Size(195, 54),
      ),
    );
  }
}
class CustomIconButton extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      width: 54,
      height: 54,
      child: Stack(
        children: [
          Container(
            width: 54,
            height: 54,
            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
              ),
            ),
          ),
        ],
      ),
    );
  }
}

显示效果

—— 晚点更新

目录
相关文章
|
2月前
|
存储 前端开发 安全
实现“永久登录”:针对蜻蜓Q系统的用户体验优化方案(前端uni-app+后端Laravel详解)-优雅草卓伊凡
实现“永久登录”:针对蜻蜓Q系统的用户体验优化方案(前端uni-app+后端Laravel详解)-优雅草卓伊凡
191 5
|
6月前
|
Android开发 数据安全/隐私保护 开发者
Android自定义view之模仿登录界面文本输入框(华为云APP)
本文介绍了一款自定义输入框的实现,包含静态效果、hint值浮动动画及功能扩展。通过组合多个控件完成界面布局,使用TranslateAnimation与AlphaAnimation实现hint文字上下浮动效果,支持密码加密解密显示、去除键盘回车空格输入、光标定位等功能。代码基于Android平台,提供完整源码与attrs配置,方便复用与定制。希望对开发者有所帮助。
125 0
|
7月前
|
人工智能 JSON 小程序
【一步步开发AI运动APP】七、自定义姿态动作识别检测——之规则配置检测
本文介绍了如何通过【一步步开发AI运动APP】系列博文,利用自定义姿态识别检测技术开发高性能的AI运动应用。核心内容包括:1) 自定义姿态识别检测,满足人像入镜、动作开始/停止等需求;2) Pose-Calc引擎详解,支持角度匹配、逻辑运算等多种人体分析规则;3) 姿态检测规则编写与执行方法;4) 完整示例展示左右手平举姿态检测。通过这些技术,开发者可轻松实现定制化运动分析功能。
|
1月前
|
人工智能 小程序 搜索推荐
【一步步开发AI运动APP】十二、自定义扩展新运动项目2
本文介绍如何基于uni-app运动识别插件实现“双手并举”自定义扩展运动,涵盖动作拆解、姿态检测规则构建及运动分析器代码实现,助力开发者打造个性化AI运动APP。
|
9月前
|
前端开发 安全 开发工具
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
589 90
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
6月前
|
人工智能 小程序 API
【一步步开发AI运动APP】九、自定义姿态动作识别检测——之关键点追踪
本文介绍了【一步步开发AI运动APP】系列中的关键点追踪技术。此前分享的系列博文助力开发者打造了多种AI健身场景的小程序,而新系列将聚焦性能更优的AI运动APP开发。文章重点讲解了“关键点位变化追踪”能力,适用于动态运动(如跳跃)分析,弥补了静态姿态检测的不足。通过`pose-calc`插件,开发者可设置关键点(如鼻子)、追踪方向(X或Y轴)及变化幅度。示例代码展示了如何在`uni-app`框架中使用`createPointTracker`实现关键点追踪,并结合人体识别结果完成动态分析。具体实现可参考文档与Demo示例。
|
5月前
《仿盒马》app开发技术分享-- 自定义标题栏&商品详情初探(9)
上一节我们实现了顶部toolbar的地址选择,会员码展示,首页的静态页面就先告一段落,这节我们来实现商品列表item的点击传值、自定义标题栏。
80 0
|
7月前
|
人工智能 小程序 API
【一步步开发AI运动APP】八、自定义姿态动作识别检测——之姿态相似度比较
本文介绍了如何通过姿态相似度比较技术简化AI运动应用开发。相比手动配置规则,插件`pose-calc`提供的姿态相似度比较器可快速评估两组人体关键点的整体与局部相似度,降低开发者工作量。文章还展示了在`uni-app`框架下调用姿态比较器的示例代码,并提供了桌面辅助工具以帮助提取标准动作样本,助力开发者打造性能更优、体验更好的AI运动APP。
|
9月前
|
Dart 前端开发 Android开发
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
298 4
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
9月前
|
开发框架 缓存 搜索推荐
PiliPala:开源项目真香,B站用户狂喜!这个开源APP竟能自定义主题+去广告?PiliPala隐藏功能大揭秘
嗨,大家好,我是小华同学。PiliPala 是一个基于 Flutter 开发的 BiliBili 第三方客户端,提供流畅、个性化的使用体验。核心功能包括视频浏览与推荐、用户互动、丰富的播放设置、多维度搜索和个性化主题等。相比官方客户端,PiliPala 功能更丰富、性能更优、界面更美观。
455 14

热门文章

最新文章

  • 1
    【App Service】部署War包到Azure云上遇404错误
  • 2
    前端如何存储数据:Cookie、LocalStorage 与 SessionStorage 全面解析
  • 3
    前端工程化演进之路:从手工作坊到AI驱动的智能化开发
  • 4
    Vue 3 + TypeScript 现代前端开发最佳实践(2025版指南)
  • 5
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(五):背景属性;float浮动和position定位;详细分析相对、绝对、固定三种定位方式;使用浮动并清除浮动副作用
  • 6
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(六):全方面分析css的Flex布局,从纵、横两个坐标开始进行居中、两端等元素分布模式;刨析元素间隔、排序模式等
  • 7
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(一):CSS发展史;CSS样式表的引入;CSS选择器使用,附带案例介绍
  • 8
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(八):学习transition过渡属性;本文学习property模拟、duration过渡时间指定、delay时间延迟 等多个参数
  • 9
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(九):强势分析Animation动画各类参数;从播放时间、播放方式、播放次数、播放方向、播放状态等多个方面,完全了解CSS3 Animation
  • 10
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(四):元素盒子模型;详细分析边框属性、盒子外边距
  • 1
    前端如何存储数据:Cookie、LocalStorage 与 SessionStorage 全面解析
    447
  • 2
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(九):强势分析Animation动画各类参数;从播放时间、播放方式、播放次数、播放方向、播放状态等多个方面,完全了解CSS3 Animation
    167
  • 3
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(八):学习transition过渡属性;本文学习property模拟、duration过渡时间指定、delay时间延迟 等多个参数
    179
  • 4
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(七):学习ransform属性;本文学习 rotate旋转、scale缩放、skew扭曲、tanslate移动、matrix矩阵 多个参数
    138
  • 5
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(六):全方面分析css的Flex布局,从纵、横两个坐标开始进行居中、两端等元素分布模式;刨析元素间隔、排序模式等
    228
  • 6
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(五):背景属性;float浮动和position定位;详细分析相对、绝对、固定三种定位方式;使用浮动并清除浮动副作用
    317
  • 7
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(四):元素盒子模型;详细分析边框属性、盒子外边距
    148
  • 8
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(三):元素继承关系、层叠样式规则、字体属性、文本属性;针对字体和文本作样式修改
    80
  • 9
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(二):CSS伪类:UI伪类、结构化伪类;通过伪类获得子元素的第n个元素;创建一个伪元素展示在页面中;获得最后一个元素;处理聚焦元素的样式
    145
  • 10
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(一):CSS发展史;CSS样式表的引入;CSS选择器使用,附带案例介绍
    200
  • 下一篇
    oss云网关配置