
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍
背景说明要提一点:我们所有的开发耗尽2个月的时间,目前只是整合与记录并且呈现过程,大家不要想的太简单,自己试试就知道了哈,而不是你们以为的很快很简单,这点请必须要知道。
闲话不多,开源仓库地址,可以观摩已经写好的代码:
https://gitee.com/youyacao/ff-flutter
https://www.youyacao.cn/freefirend
·完善了vip购买页面的其他功能 ·增加了用户邀请码页面 ·增加了申请主播资料填写页面 ·增加了安全中心介绍页 ·增加了帮助中心介绍页 ·创建腾讯云直播SDK相关信息 ·创建即时通讯sdk相关信息
assets/images/invite_box.png | Bin 0 -> 340684 bytes
assets/images/invite_friend_icon.png | Bin 0 -> 13944 bytes
assets/images/invite_gold_coin.png | Bin 0 -> 17238 bytes
assets/images/vip_advance.png | Bin 0 -> 10671 bytes
assets/images/vip_all_videos.png | Bin 0 -> 17366 bytes
assets/images/vip_auto_renew.png | Bin 0 -> 6721 bytes
assets/images/vip_hd.png | Bin 0 -> 15988 bytes
assets/images/vip_no_ads.png | Bin 0 -> 16945 bytes
lib/routes/app_pages.dart | 30 ++++
lib/routes/app_routes.dart | 5 +
lib/screens/account/widgets/menu_list.dart | 87 ++++++----
lib/screens/account/widgets/user_info.dart | 27 +--
lib/screens/anchor_apply/index.dart | 90 ++++++++++
.../anchor_apply/widgets/anchor_apply_form.dart | 155 +++++++++++++++++
lib/screens/help_center/index.dart | 75 ++++++++
.../help_center/widgets/help_menu_item.dart | 45 +++++
lib/screens/invite_friends/index.dart | 22 +++
.../invite_friends/widgets/invite_card.dart | 188 +++++++++++++++++++++
.../invite_friends/widgets/invite_header.dart | 41 +++++
lib/screens/personal_data/index.dart | 33 ++++
.../personal_data/widgets/personal_data_form.dart | 147 ++++++++++++++++
lib/screens/security_center/index.dart | 79 +++++++++
.../widgets/security_menu_item.dart | 45 +++++
lib/screens/vip/index.dart | 27 ++-
lib/screens/vip/widgets/member_benefits.dart | 78 +++++++++
lib/screens/vip/widgets/member_combo.dart | 4 +-
lib/screens/vip/widgets/vip_purchase.dart | 90 ++++++++++
27 files changed, 1218 insertions(+), 50 deletions(-)
create mode 100644 assets/images/invite_box.png
create mode 100644 assets/images/invite_friend_icon.png
create mode 100644 assets/images/invite_gold_coin.png
create mode 100644 assets/images/vip_advance.png
create mode 100644 assets/images/vip_all_videos.png
create mode 100644 assets/images/vip_auto_renew.png
create mode 100644 assets/images/vip_hd.png
create mode 100644 assets/images/vip_no_ads.png
create mode 100644 lib/screens/anchor_apply/index.dart
create mode 100644 lib/screens/anchor_apply/widgets/anchor_apply_form.dart
create mode 100644 lib/screens/help_center/index.dart
create mode 100644 lib/screens/help_center/widgets/help_menu_item.dart
create mode 100644 lib/screens/invite_friends/index.dart
create mode 100644 lib/screens/invite_friends/widgets/invite_card.dart
create mode 100644 lib/screens/invite_friends/widgets/invite_header.dart
create mode 100644 lib/screens/personal_data/index.dart
create mode 100644 lib/screens/personal_data/widgets/personal_data_form.dart
create mode 100644 lib/screens/security_center/index.dart
create mode 100644 lib/screens/security_center/widgets/security_menu_item.dart
create mode 100644 lib/screens/vip/widgets/member_benefits.dart
create mode 100644 lib/screens/vip/widgets/vip_purchase.dart先看看结果

个人中心的

邀请页面

直播页面

帮助中心页面以及安全中心页面 ,类似就一个代替

购买vip页面完善。
先看个人中心页面的变化:
personal_data_form.dart
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class PersonalDataForm extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 60.w),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 60.h),
_buildLabel('Profile picture'),
SizedBox(height: 20.h),
// 头像选择区域
Container(
width: 140.w,
height: 140.h,
decoration: BoxDecoration(
color: const Color(0xFF393939),
borderRadius: BorderRadius.circular(20.r),
),
child: Center(
child: Icon(
Icons.add,
color: Colors.white,
size: 48.sp,
),
),
),
SizedBox(height: 40.h),
_buildLabel('Name'),
SizedBox(height: 20.h),
_buildTextField('Name'),
SizedBox(height: 40.h),
_buildLabel('Date of birth'),
SizedBox(height: 20.h),
_buildTextField('Date of birth', suffixIcon: Icons.calendar_today),
SizedBox(height: 40.h),
_buildLabel('Gender'),
SizedBox(height: 20.h),
_buildDropdown('Choose your gender'),
SizedBox(height: 40.h),
_buildLabel('Area'),
SizedBox(height: 20.h),
_buildDropdown('Choose your region'),
SizedBox(height: 60.h),
_buildConfirmButton(),
],
),
),
);
}
Widget _buildLabel(String text) {
return Text(
text,
style: TextStyle(
color: Colors.white,
fontSize: 32.sp,
fontWeight: FontWeight.w500,
),
);
}
Widget _buildTextField(String hint, {IconData? suffixIcon}) {
return Container(
height: 100.h,
decoration: BoxDecoration(
color: const Color(0xFF393939),
borderRadius: BorderRadius.circular(20.r),
),
child: TextField(
style: TextStyle(
color: Colors.white,
fontSize: 32.sp,
),
decoration: InputDecoration(
hintText: hint,
hintStyle: TextStyle(
color: Colors.grey,
fontSize: 32.sp,
),
border: InputBorder.none,
contentPadding: EdgeInsets.symmetric(horizontal: 30.w),
suffixIcon: suffixIcon != null
? Icon(
suffixIcon,
color: Colors.grey,
size: 48.sp,
)
: null,
),
),
);
}
Widget _buildDropdown(String hint) {
return Container(
height: 100.h,
padding: EdgeInsets.symmetric(horizontal: 30.w),
decoration: BoxDecoration(
color: const Color(0xFF393939),
borderRadius: BorderRadius.circular(20.r),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
hint,
style: TextStyle(
color: Colors.grey,
fontSize: 32.sp,
),
),
Icon(
Icons.keyboard_arrow_down,
color: Colors.grey,
size: 48.sp,
),
],
),
);
}
Widget _buildConfirmButton() {
return Container(
width: double.infinity,
height: 100.h,
decoration: BoxDecoration(
color: const Color(0xFFE56389),
borderRadius: BorderRadius.circular(50.r),
),
child: Center(
child: Text(
'Confirm Save',
style: TextStyle(
color: Colors.white,
fontSize: 36.sp,
fontWeight: FontWeight.bold,
),
),
),
);
}
}这段代码定义了一个名为 PersonalDataForm 的无状态小部件,用于显示个人资料表单。表单包含头像选择、姓名、出生日期、性别、地区输入框及确认按钮。各个输入项通过 _buildLabel、_buildTextField、_buildDropdown 和 _buildConfirmButton 方法构建。
控制流图
flowchart TD
A[开始] --> B[创建 SingleChildScrollView]
B --> C[创建 Padding]
C --> D[创建 Column]
D --> E{添加子组件}
E -->|Profile picture 标签| F[创建 _buildLabel]
F --> G[创建 SizedBox]
G --> H[创建 Container 头像选择区域]
H --> I[创建 SizedBox]
I --> J[创建 Name 标签]
J --> K[创建 SizedBox]
K --> L[创建 Name 输入框]
L --> M[创建 SizedBox]
M --> N[创建 Date of birth 标签]
N --> O[创建 SizedBox]
O --> P[创建 Date of birth 输入框]
P --> Q[创建 SizedBox]
Q --> R[创建 Gender 标签]
R --> S[创建 SizedBox]
S --> T[创建 Gender 下拉框]
T --> U[创建 SizedBox]
U --> V[创建 Area 标签]
V --> W[创建 SizedBox]
W --> X[创建 Area 下拉框]
X --> Y[创建 SizedBox]
Y --> Z[创建 Confirm Save 按钮]购买vip页面的代码:
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'widgets/vip_header.dart';
import 'widgets/vip_user_info.dart';
import 'widgets/member_combo.dart';
import 'widgets/member_benefits.dart';
import 'widgets/vip_purchase.dart';
class VipScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
body: SafeArea(
bottom: false, // 不处理底部安全区域
child: Column(
children: [
Expanded(
child: SingleChildScrollView(
child: Column(
children: [
VipHeader(),
VipUserInfo(),
MemberCombo(),
MemberBenefits(),
],
),
),
),
VipPurchase(),
],
),
),
);
}
}可以看到 首页只是用来引用组件,
vip_purchase.dart
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class VipPurchase extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.symmetric(horizontal: 30.w),
decoration: BoxDecoration(
color: const Color(0xFF393939),
borderRadius: BorderRadius.circular(4.r),
),
child: Column(
// mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 30.h),
Row(
children: [
Image.asset(
'assets/images/vip_auto_renew.png',
width: 32.w,
height: 32.h,
color: const Color(0xFFECD29F),
),
SizedBox(width: 20.w),
Text(
'Automatic renewal',
style: TextStyle(
color: const Color(0xFFECD29F),
fontSize: 32.sp,
),
),
],
),
SizedBox(
height: 133.h,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Text(
'Amount: ',
style: TextStyle(
color: Colors.white,
fontSize: 32.sp,
),
),
Text(
'\$89',
style: TextStyle(
color: const Color(0xFFECD29F),
fontSize: 32.sp,
fontWeight: FontWeight.bold,
),
),
],
),
GestureDetector(
onTap: () {
print('Buy clicked');
},
child: Container(
width: 340.w,
height: 70.h,
decoration: BoxDecoration(
color: const Color(0xFFE56389),
borderRadius: BorderRadius.circular(35.r),
),
child: Center(
child: Text(
'Buy',
style: TextStyle(
color: Colors.white,
fontSize: 36.sp,
fontWeight: FontWeight.bold,
),
),
),
),
),
],
),
),
],
),
);
}
}member_combo.dart
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class MemberCombo extends StatefulWidget {
@override
State<MemberCombo> createState() => _MemberComboState();
}
class _MemberComboState extends State<MemberCombo> {
int selectedIndex = 0;
final List<Map<String, dynamic>> memberTypes = [
{
'title': 'Regular member',
'icon': 'assets/images/vip_regular.png',
'darkColor': const Color(0xFF393939),
},
{
'title': 'Gold Membership',
'icon': 'assets/images/vip_gold.png',
'darkColor': const Color(0xFF393939),
},
{
'title': 'Diamond',
'icon': 'assets/images/vip_diamond.png',
'darkColor': const Color(0xFF393939),
},
];
final Gradient selectedGradient = const LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Color(0xFFECD29F),
Color(0xFFE1BA7F),
],
);
@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.only(top: 60.h),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsets.only(left: 30.w, bottom: 38.h),
child: Text(
'Member Combo',
style: TextStyle(
color: Colors.white,
fontSize: 40.sp,
fontWeight: FontWeight.bold,
),
),
),
SizedBox(
height: 186.h,
child: ListView.builder(
scrollDirection: Axis.horizontal,
padding: EdgeInsets.symmetric(horizontal: 30.w),
itemCount: memberTypes.length,
itemBuilder: (context, index) {
final isSelected = selectedIndex == index;
return GestureDetector(
onTap: () {
setState(() {
selectedIndex = index;
});
},
child: Container(
width: 296.w,
margin: EdgeInsets.only(right: 20.w),
decoration: BoxDecoration(
gradient: isSelected ? selectedGradient : null,
color:
isSelected ? null : memberTypes[index]['darkColor'],
borderRadius: BorderRadius.circular(30.r),
),
child: Stack(
children: [
Positioned(
left: 30.w,
top: 30.h,
child: Image.asset(
memberTypes[index]['icon'],
width: 48.w,
height: 48.h,
),
),
Positioned(
left: 30.w,
bottom: 30.h,
child: Text(
memberTypes[index]['title'],
style: TextStyle(
color: Colors.white,
fontSize: 28.sp,
fontWeight: FontWeight.w400,
),
),
),
],
),
),
);
},
),
),
],
),
);
}
}本章其他界面也没有复杂的部分,其他代码直接登录gitee 去看即可,已经公开的,我们接下来直接进入SDK应用创建部分
先是直播sdk,正常用户只有一次机会,14天测试期,要珍惜,如果测试完了过期的不能删除,也无法使用


核心资料是app name License URL和License Key

即时通讯的关键信息, SDKAppID:
1600071385
应用名称:
freefirend
密钥: 这里就脱敏一下。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。