创建消息页面,交友语聊页面

This commit is contained in:
apple 2022-07-25 14:42:34 +08:00
parent dd610eee1f
commit 1da36a36f7
32 changed files with 1309 additions and 44 deletions

View File

@ -31,4 +31,22 @@
android:name="flutterEmbedding"
android:value="2" />
</application>
<!-- 麦克风权限 -->
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<!-- 相机权限 -->
<uses-permission android:name="android.permission.CAMRA"/>
<!-- 蓝牙权限 -->
<uses-permission android:name="android.permission.BLUETOOTH"/>
<!-- “位置”组的权限选项 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<!-- “存储”组的权限选 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- 写权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- 读权限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
</manifest>

View File

@ -15,6 +15,10 @@ allprojects {
repositories {
google()
mavenCentral()
maven { url 'https://www.jitpack.io' }
// maven { url 'https://maven.aliyun.com/repository/google' }
// maven { url 'https://maven.aliyun.com/repository/jcenter' }
// maven { url 'http://maven.aliyun.com/nexus/content/groups/public' }
}
}

BIN
images/palRoom/add.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 634 B

BIN
images/palRoom/face.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
images/palRoom/more.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 511 B

BIN
images/palRoom/photo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
images/palRoom/tip.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 605 B

BIN
images/palRoom/voice1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
images/palRoom/voice2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
images/palRoom/volume.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 763 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 330 B

BIN
images/party/banner.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 253 KiB

BIN
images/party/create.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
images/party/live.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
images/party/photo1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

BIN
images/party/search.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -1 +1,2 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"

View File

@ -1 +1,2 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"

83
ios/Podfile Normal file
View File

@ -0,0 +1,83 @@
# Uncomment this line to define a global platform for your project
# platform :ios, '9.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
project 'Runner', {
'Debug' => :debug,
'Profile' => :release,
'Release' => :release,
}
def flutter_root
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
unless File.exist?(generated_xcode_build_settings_path)
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
end
File.foreach(generated_xcode_build_settings_path) do |line|
matches = line.match(/FLUTTER_ROOT\=(.*)/)
return matches[1].strip if matches
end
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
end
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
flutter_ios_podfile_setup
target 'Runner' do
use_frameworks!
use_modular_headers!
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
end
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
target.build_configurations.each do |config|
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
'$(inherited)',
## dart: PermissionGroup.calendar
# 'PERMISSION_EVENTS=0',
## dart: PermissionGroup.reminders
# 'PERMISSION_REMINDERS=0',
## dart: PermissionGroup.contacts
# 'PERMISSION_CONTACTS=0',
## dart: PermissionGroup.camera
'PERMISSION_CAMERA=1',
## dart: PermissionGroup.microphone
'PERMISSION_MICROPHONE=1',
## dart: PermissionGroup.speech
# 'PERMISSION_SPEECH_RECOGNIZER=0',
## dart: PermissionGroup.photos
'PERMISSION_PHOTOS=1',
## dart: [PermissionGroup.location, PermissionGroup.locationAlways, PermissionGroup.locationWhenInUse]
'PERMISSION_LOCATION=1',
## dart: PermissionGroup.notification
# 'PERMISSION_NOTIFICATIONS=0',
## dart: PermissionGroup.mediaLibrary
'PERMISSION_MEDIA_LIBRARY=1',
## dart: PermissionGroup.sensors
# 'PERMISSION_SENSORS=0',
## dart: PermissionGroup.bluetooth
'PERMISSION_BLUETOOTH=1'
]
end
end
end

35
ios/Podfile.lock Normal file
View File

@ -0,0 +1,35 @@
PODS:
- agora_rtc_engine (5.2.0):
- AgoraIrisRTC_iOS (= 3.6.2-fix.1)
- Flutter
- AgoraIrisRTC_iOS (3.6.2-fix.1)
- Flutter (1.0.0)
- "permission_handler (5.1.0+2)":
- Flutter
DEPENDENCIES:
- agora_rtc_engine (from `.symlinks/plugins/agora_rtc_engine/ios`)
- Flutter (from `Flutter`)
- permission_handler (from `.symlinks/plugins/permission_handler/ios`)
SPEC REPOS:
trunk:
- AgoraIrisRTC_iOS
EXTERNAL SOURCES:
agora_rtc_engine:
:path: ".symlinks/plugins/agora_rtc_engine/ios"
Flutter:
:path: Flutter
permission_handler:
:path: ".symlinks/plugins/permission_handler/ios"
SPEC CHECKSUMS:
agora_rtc_engine: ffc530eff766a38272568ebaead9341d73f58856
AgoraIrisRTC_iOS: 9b11083bb79048ae4db7e2f56109cc51ac9e3834
Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a
permission_handler: ccb20a9fad0ee9b1314a52b70b76b473c5f8dab0
PODFILE CHECKSUM: bd5ecd90bb4d3dada07dd6c6725bb70ab42e9619
COCOAPODS: 1.11.3

View File

@ -7,6 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
08976713930F537FC16A9989 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9F89E0C1576E5175DA507E0A /* Pods_Runner.framework */; };
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
@ -29,9 +30,11 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
01002F18FF266E3CBA08DFF1 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
46C7DE6EE46B02CD476DC689 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
@ -42,6 +45,8 @@
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
9F89E0C1576E5175DA507E0A /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
EE80022A6CA95021663A9546 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -49,6 +54,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
08976713930F537FC16A9989 /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -72,6 +78,8 @@
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */,
D098840440D5B4B6826A83D3 /* Pods */,
CA63AB0B2A7C800A1A254681 /* Frameworks */,
);
sourceTree = "<group>";
};
@ -98,6 +106,25 @@
path = Runner;
sourceTree = "<group>";
};
CA63AB0B2A7C800A1A254681 /* Frameworks */ = {
isa = PBXGroup;
children = (
9F89E0C1576E5175DA507E0A /* Pods_Runner.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
D098840440D5B4B6826A83D3 /* Pods */ = {
isa = PBXGroup;
children = (
01002F18FF266E3CBA08DFF1 /* Pods-Runner.debug.xcconfig */,
46C7DE6EE46B02CD476DC689 /* Pods-Runner.release.xcconfig */,
EE80022A6CA95021663A9546 /* Pods-Runner.profile.xcconfig */,
);
name = Pods;
path = Pods;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@ -105,12 +132,14 @@
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
C41E0D688505E9EBCE1BB5DA /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
A2955506D9FCC1C68D094BA7 /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
@ -197,6 +226,45 @@
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
A2955506D9FCC1C68D094BA7 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
C41E0D688505E9EBCE1BB5DA /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */

View File

@ -4,4 +4,7 @@
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>

View File

@ -24,6 +24,27 @@
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<!-- 新增 -->
<key>NSCameraUsageDescription</key>
<string>访问相机</string>
<key>NSMicrophoneUsageDescription</key>
<string>访问麦克风</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>访问相册</string>
<key>NSLocationUsageDescription</key>
<string>获取位置</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>在使用期间需要获取您的位置</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>始终访问位置</string>
<key>NSCalendarsUsageDescription</key>
<string>访问日历</string>
<key>NSBluetoothPeripheralUsageDescription</key>
<string>访问蓝牙</string>
<key>NSAppleMusicUsageDescription</key>
<string>访问媒体资料库</string>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>

View File

@ -43,6 +43,7 @@ class _TabsState extends State<Tabs> {
this._currentIndex = index;
});
},
backgroundColor: Colors.white,
items: [
BottomNavigationBarItem(
icon: Image.asset(
@ -112,42 +113,42 @@ class _TabsState extends State<Tabs> {
)
],
),
drawer: Drawer(
child: Column(
children: [
Row(
children: [
Expanded(
child: DrawerHeader(
child: Text("Drawer组件"),
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(
'https://www.itying.com/images/flutter/2.png'),
fit: BoxFit.cover),
),
),
)
],
),
ListTile(
title: Text('我的空间'),
leading: Icon(Icons.home),
),
ListTile(
title: Text('设置'),
leading: Icon(Icons.settings),
onTap: () {
Navigator.of(context).pop(); //
Navigator.of(context).pushNamed('/routeParms');
},
)
],
),
),
endDrawer: Drawer(
child: Text('右侧抽屉'),
),
// drawer: Drawer(
// child: Column(
// children: [
// Row(
// children: [
// Expanded(
// child: DrawerHeader(
// child: Text("Drawer组件"),
// decoration: BoxDecoration(
// image: DecorationImage(
// image: NetworkImage(
// 'https://www.itying.com/images/flutter/2.png'),
// fit: BoxFit.cover),
// ),
// ),
// )
// ],
// ),
// ListTile(
// title: Text('我的空间'),
// leading: Icon(Icons.home),
// ),
// ListTile(
// title: Text('设置'),
// leading: Icon(Icons.settings),
// onTap: () {
// Navigator.of(context).pop(); //
// Navigator.of(context).pushNamed('/routeParms');
// },
// )
// ],
// ),
// ),
// endDrawer: Drawer(
// child: Text('右侧抽屉'),
// ),
);
}
}

View File

@ -18,9 +18,11 @@ import '../Tab.dart';
// import '../pages/dialog/Dialog.dart';
// import '../pages/https/Https.dart';
// import '../views/home/Home.dart';
import '../views/palRoom/PalRoom.dart';
final routes = {
'/': (context) => Tabs(),
'PalRoom': (context) => PalRoomPage(),
// '/home': (context) => HomePage(),
// '/routeParms': (context, {arguments}) => RouteParmsPage(arguments: arguments),
// '/RouteParmsDT': (context, {arguments}) =>
@ -40,6 +42,7 @@ final routes = {
// '/dialog': (context) => DialogPage(),
// '/https': (context) => HttpsPage(),
};
var onGenerateRoute = (RouteSettings settings) {
//
final String? name = settings.name;

3
lib/utils/settings.dart Normal file
View File

@ -0,0 +1,3 @@
const APP_ID = '809529cf18814549a0249802512a7508';
const Token =
'006809529cf18814549a0249802512a7508IAAPcoSQKL/h/B6xy0PPG/XdoZUWas07EdCBtxLe7HH4Hz4vjswAAAAAEABsSV6NzT/fYgEAAQDKP99i';

View File

@ -320,11 +320,8 @@ class _RoomComponentState extends State<RoomComponent> {
],
),
),
SizedBox(
height: 10,
), //
Container(
padding: EdgeInsets.only(left: 10),
padding: EdgeInsets.only(left: 10, top: 10),
child: Text(
item['title'],
overflow: TextOverflow.ellipsis,

View File

@ -0,0 +1,560 @@
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:agora_rtc_engine/rtc_engine.dart';
import 'package:permission_handler/permission_handler.dart';
import '../../utils/settings.dart';
//
//
//
//
// (线)
//
// 退()
class PalRoomPage extends StatefulWidget {
final String userName;
final String channelName;
final ClientRole? role;
PalRoomPage({Key? key, this.userName = '', this.channelName = '', this.role})
: super(key: key);
@override
State<PalRoomPage> createState() => _PalRoomPageState();
}
class _PalRoomPageState extends State<PalRoomPage> {
final _users = <int>[]; // id数组
final _infoStrings = <String>[]; //
bool viewPanel = true; //
bool muted = false; //
bool volume = true; //
late RtcEngine _engine; //
//
List list = [
{'name': '', 'content': false, 'image': 'images/palRoom/voice2.png'},
{'name': '', 'content': false, 'image': 'images/palRoom/voice2.png'},
{'name': '', 'content': false, 'image': 'images/palRoom/voice2.png'},
{'name': '', 'content': false, 'image': 'images/palRoom/voice2.png'},
{'name': '', 'content': false, 'image': 'images/palRoom/voice2.png'},
{'name': '', 'content': false, 'image': 'images/palRoom/voice2.png'},
{'name': '', 'content': false, 'image': 'images/palRoom/voice2.png'},
{'name': '', 'content': false, 'image': 'images/palRoom/voice2.png'},
];
@override
void initState() {
super.initState();
_infoStrings.insert(
0, '最新插入的item-${widget.userName}-${widget.channelName}-${widget.role}');
if (widget.role == ClientRole.Broadcaster) {
//
initialize();
_infoStrings.insert(0, '您身份为主播,已经上麦状态');
} else if (widget.role == ClientRole.Audience) {
_infoStrings.insert(0, '您身份为观众,点击麦克风图标上麦'); //
}
}
@override
void dispose() {
super.dispose();
_users.clear();
_engine.leaveChannel();
_engine.destroy();
}
Future<void> initialize() async {
// appid是否存在
if (APP_ID.isEmpty) {
setState(() {
_infoStrings.insert(0, 'APP ID缺失请在settings.dart中提供您的APP ID');
_infoStrings.insert(0, 'Agora引擎没有启动');
});
return;
}
_engine = await RtcEngine.create(APP_ID); //
await _engine.enableAudio(); //
await _engine.setDefaultAudioRouteToSpeakerphone(
true); //
await _engine.setAudioProfile(AudioProfile.SpeechStandard,
AudioScenario.ChatRoomEntertainment); //
await _engine.setChannelProfile(ChannelProfile.LiveBroadcasting);
await _engine.setClientRole(widget.role!);
_addAgoraEventHandlers(); //
_engine.joinChannel(Token, widget.channelName, null, 0); //
}
void _addAgoraEventHandlers() {
_engine.setEventHandler(RtcEngineEventHandler(
error: (code) {
//
setState(() {
final info = '错误 $code';
_infoStrings.insert(0, info);
});
},
joinChannelSuccess: (channel, uid, elapsed) {
//
setState(() {
final info = '加入频道: $channel, uid: $uid';
_infoStrings.insert(0, info);
});
},
leaveChannel: (stats) {
//
setState(() {
_infoStrings.insert(0, '离开频道');
_users.clear();
});
},
userJoined: (uid, elapsed) {
//
setState(() {
final info = '用户加入: $uid';
_infoStrings.insert(0, info);
_users.add(uid);
});
},
userOffline: (uid, reason) {
// 线
setState(() {
final info = '用户离线: $uid , reason: $reason';
_infoStrings.insert(0, info);
_users.remove(uid);
});
},
firstRemoteVideoFrame: (uid, width, height, elapsed) {
//
setState(() {
final info = 'First Remote Video Frame: $uid';
_infoStrings.insert(0, info);
});
},
));
}
Widget _head() {
return Container(
child: Column(
children: [
Container(
padding: EdgeInsets.fromLTRB(0, 27, 0, 5),
alignment: Alignment.topCenter,
child: Image.asset(
'images/palRoom/photo.png',
width: 70,
height: 70,
),
),
Container(
margin: EdgeInsets.only(bottom: 30),
alignment: Alignment.topCenter,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 18,
height: 18,
alignment: Alignment.center,
decoration: BoxDecoration(
color: Color.fromRGBO(245, 173, 29, 1),
borderRadius: BorderRadius.circular(2),
),
child: Text(
'',
style: TextStyle(
color: Colors.white,
fontSize: 12,
),
),
),
SizedBox(width: 5),
Text('以冬', style: TextStyle(color: Colors.white, fontSize: 14)),
],
),
),
Container(
child: GridView.builder(
padding: EdgeInsets.all(15),
shrinkWrap: true,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisSpacing: 40,
mainAxisSpacing: 35,
crossAxisCount: 4,
childAspectRatio: 1 / 1.2,
),
itemCount: list.length,
itemBuilder: (BuildContext context, int index) {
return GestureDetector(
onTap: () {
setState(() {
if (widget.role == ClientRole.Audience) {
//
_modelBottomSheet(index); //
} else {
_infoStrings.insert(0, '您身份为主播,已经上麦状态');
}
});
},
child: Column(
children: [
Container(
width: 55,
height: 55,
margin: EdgeInsets.only(bottom: 5),
decoration: BoxDecoration(
color: Color.fromRGBO(52, 51, 69, 1),
borderRadius: BorderRadius.circular(50),
),
child: Center(
child: Image.asset(
list[index]['image'],
width: list[index]['content'] ? 55 : 14,
height: list[index]['content'] ? 55 : 21,
),
),
),
Text(
list[index]['name'],
textAlign: TextAlign.center,
style: TextStyle(color: Colors.white, fontSize: 12),
),
],
),
);
;
},
),
),
],
),
);
}
Widget _planel() {
return Visibility(
visible: viewPanel,
child: Container(
padding: EdgeInsets.symmetric(vertical: 48),
alignment: Alignment.bottomCenter,
child: FractionallySizedBox(
heightFactor: 0.5,
child: Container(
// decoration: BoxDecoration(
// color: Colors.black,
// ),
// padding: EdgeInsets.symmetric(vertical: 48),
child: ListView.builder(
reverse: true,
itemCount: _infoStrings.length,
itemBuilder: (BuildContext context, int index) {
if (_infoStrings.isEmpty) {
return Text('null');
}
return Padding(
padding: EdgeInsets.symmetric(vertical: 5, horizontal: 15),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Flexible(
child: Container(
padding: EdgeInsets.symmetric(
vertical: 10,
horizontal: 10,
),
decoration: BoxDecoration(
color: Color.fromRGBO(50, 51, 71, 1),
borderRadius: BorderRadius.circular(5),
),
child: Text(
_infoStrings[index],
style: TextStyle(
color: Color.fromRGBO(155, 154, 170, 1),
),
),
),
),
],
),
);
},
),
),
),
),
);
}
Widget _footer() {
final _input = TextEditingController();
return Container(
width: double.infinity,
alignment: Alignment.bottomCenter,
padding: EdgeInsets.symmetric(
vertical: 18,
horizontal: 15,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
GestureDetector(
//
onTap: () {
setState(() {
volume = !volume;
});
_engine.adjustPlaybackSignalVolume(
volume ? 100 : 0); //
},
child: Icon(volume ? Icons.volume_up : Icons.volume_off,
color: Color.fromRGBO(201, 201, 201, 1), size: 25.0),
),
GestureDetector(
//
onTap: () {
setState(() {
muted = !muted;
});
_engine.muteLocalAudioStream(muted); //
},
child: Icon(muted ? Icons.mic_off : Icons.mic,
color: Color.fromRGBO(201, 201, 201, 1), size: 25.0),
),
GestureDetector(
child: Icon(Icons.tag_faces,
color: Color.fromRGBO(201, 201, 201, 1), size: 25.0),
),
Container(
width: 220,
padding: EdgeInsets.symmetric(horizontal: 10),
decoration: BoxDecoration(
color: Color.fromRGBO(52, 51, 69, 1),
borderRadius: BorderRadius.circular(30),
),
child: TextField(
controller: _input,
decoration: InputDecoration(
isDense: true,
border: InputBorder.none,
hintText: '我来说几句',
hintStyle: TextStyle(
fontSize: 12,
color: Color.fromRGBO(138, 138, 146, 1),
),
),
style: TextStyle(
fontSize: 12,
color: Colors.white,
),
textInputAction: TextInputAction.send, //
),
),
GestureDetector(
child: Icon(Icons.add,
color: Color.fromRGBO(201, 201, 201, 1), size: 25.0),
),
],
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: true,
appBar: AppBar(
elevation: 0, // z轴阴影
titleSpacing: 0, //
backgroundColor: Color.fromRGBO(27, 28, 48, 1),
title: Container(
height: 60,
decoration: BoxDecoration(
color: Color.fromRGBO(27, 28, 48, 1),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox(
child: Padding(
padding: EdgeInsets.only(right: 5),
child: ClipOval(
child: Image.asset(
'images/palRoom/photo.png',
width: 46,
height: 46,
),
),
),
),
Expanded(
flex: 1,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Row(
children: [
Text(
'以冬',
style: TextStyle(color: Colors.white, fontSize: 12),
),
SizedBox(width: 5),
Text(
'ID309060',
style: TextStyle(
color: Color.fromRGBO(242, 174, 30, 1),
fontSize: 10,
),
),
],
),
Row(
children: [
Text.rich(
TextSpan(
style: TextStyle(
fontSize: 10,
color: Colors.white,
),
children: [
TextSpan(text: '交友'),
TextSpan(text: ' | '),
TextSpan(text: '房间名:成人避风港'),
]),
),
SizedBox(width: 5),
Container(
padding: EdgeInsets.fromLTRB(6, 1, 6, 1),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(2)),
color: Color.fromRGBO(47, 47, 59, 1),
),
child: Row(
children: [
Text(
'在线121',
style: TextStyle(
fontSize: 10,
color: Colors.white,
),
),
SizedBox(width: 5),
Image.asset(
'images/palRoom/whiteRight.png',
width: 5,
height: 8,
),
],
),
)
],
),
],
),
)
],
),
),
actions: [
IconButton(
onPressed: () {
print('more图标被点击');
setState(() {
viewPanel = !viewPanel;
});
},
icon: Image.asset(
'images/palRoom/more.png',
fit: BoxFit.cover,
width: 20.0,
height: 5.0,
),
),
],
),
backgroundColor: Color.fromRGBO(27, 28, 48, 1),
body: Stack(
children: [
_head(),
_planel(),
_footer(),
],
),
);
}
//
_modelBottomSheet(index) async {
showModalBottomSheet(
context: context,
builder: (context) {
return Container(
height: 150.0,
child: Column(
children: [
list[index]['content'] == false
? ListTile(
title: Text(
"连线上麦",
textAlign: TextAlign.center,
),
onTap: () {
setState(() {
for (var i = 0; i < list.length; i++) {
if (i == index) {
list[index]['content'] = true;
list[index]['name'] = '_users';
list[index]['image'] = 'images/palRoom/photo.png';
} else {
list[i]['content'] = false;
list[i]['name'] = '';
list[i]['image'] = 'images/palRoom/voice2.png';
}
}
});
initialize();
_engine.joinChannel(
Token, widget.channelName, null, 0); //
Navigator.pop(context);
print("连线上麦:${list[index]['content']}");
},
)
: ListTile(
title: Text(
"离开下麦",
textAlign: TextAlign.center,
),
onTap: () {
setState(() {
list[index]['content'] = false;
list[index]['name'] = '';
list[index]['image'] = 'images/palRoom/voice2.png';
});
_engine.leaveChannel();
print("离开下麦:${list[index]['content']}");
Navigator.pop(context);
},
),
ListTile(
title: Text(
"取消",
textAlign: TextAlign.center,
),
onTap: () {
Navigator.pop(context);
}),
],
),
);
},
);
}
}

View File

@ -1,4 +1,9 @@
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:agora_rtc_engine/rtc_engine.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:will_play/views/palRoom/PalRoom.dart';
class PartyPage extends StatefulWidget {
PartyPage({Key? key}) : super(key: key);
@ -8,10 +13,403 @@ class PartyPage extends StatefulWidget {
}
class _PartyPageState extends State<PartyPage> {
final _search = TextEditingController();
final _tabDataList = [
Tab(text: '关注'),
Tab(text: '推荐'),
Tab(text: '相亲'),
Tab(text: 'KTV'),
Tab(text: '交友'),
Tab(text: '音乐'),
];
@override
Widget build(BuildContext context) {
return Container(
child: Text('派对'),
return DefaultTabController(
initialIndex: 1, //
length: 6,
child: Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
elevation: 0, // z轴阴影
leading: null,
titleSpacing: 10, //
backgroundColor: Colors.white,
title: Container(
height: 35,
margin: EdgeInsetsDirectional.only(end: 25),
padding: EdgeInsets.fromLTRB(20, 0, 20, 0),
decoration: BoxDecoration(
color: Color.fromRGBO(247, 247, 247, 1),
borderRadius: BorderRadius.circular(30),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox(
child: Padding(
padding: EdgeInsets.only(right: 5),
child: Image.asset(
'images/party/search.png',
width: 17.0,
height: 17.0,
fit: BoxFit.cover,
),
),
),
Expanded(
flex: 1,
child: TextField(
controller: _search,
decoration: InputDecoration(
isDense: true,
border: InputBorder.none,
hintText: '搜索房间号',
hintStyle: TextStyle(
fontSize: 12,
color: Color.fromRGBO(203, 203, 203, 1),
),
),
style: TextStyle(
fontSize: 12,
color: Colors.black,
),
textInputAction: TextInputAction.search, //
),
),
],
),
),
actions: [
IconButton(
onPressed: () {
print('create图标被点击');
},
icon: Image.asset(
'images/party/create.png',
fit: BoxFit.cover,
width: 22.0,
height: 22.0,
),
),
],
bottom: TabBar(
// isScrollable: true,
indicatorSize: TabBarIndicatorSize.label, //
indicatorColor: Color.fromRGBO(255, 255, 255, 0), //
labelColor: Colors.black, // label颜色
labelStyle: TextStyle(fontSize: 18), // label的Style
unselectedLabelStyle: TextStyle(fontSize: 14), // label的Style
unselectedLabelColor:
Color.fromRGBO(153, 153, 153, 1), // label颜色
tabs: _tabDataList,
enableFeedback: true,
onTap: (index) {
print(_tabDataList[index]);
},
),
),
body: TabBarView(
children: [
ViewsWidget(),
ViewsWidget(),
ViewsWidget(),
ViewsWidget(),
ViewsWidget(),
ViewsWidget(),
],
),
),
);
}
}
// tab视图页
class ViewsWidget extends StatefulWidget {
ViewsWidget({Key? key}) : super(key: key);
@override
State<ViewsWidget> createState() => _ViewsWidgetState();
}
class _ViewsWidgetState extends State<ViewsWidget> {
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Column(
children: [
Banner(),
Lists(),
],
),
);
}
}
//
class Banner extends StatefulWidget {
Banner({Key? key}) : super(key: key);
@override
State<Banner> createState() => _BannerState();
}
class _BannerState extends State<Banner> {
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Container(
padding: EdgeInsets.fromLTRB(15, 15, 15, 0),
child: GestureDetector(
child: Image.asset('images/party/banner.png'),
onTap: () {
print('Banner on tap');
},
),
),
);
}
}
//
class Lists extends StatefulWidget {
Lists({Key? key}) : super(key: key);
@override
State<Lists> createState() => _ListsState();
}
class _ListsState extends State<Lists> {
final List _list = [
{
"photo": "images/party/photo1.png",
"name": "小明",
"num": "12",
"title": "今日听君歌一曲",
"type": "music",
"sex": "0",
"role": ClientRole.Broadcaster,
},
{
"photo": "images/party/photo1.png",
"name": "小红",
"num": "12",
"title": "成年人的避风港",
"type": "pal",
"sex": "1",
"role": ClientRole.Audience,
},
{
"photo": "images/party/photo1.png",
"name": "小黑",
"num": "12",
"title": "今日听君歌一曲",
"type": "auction",
"sex": "0",
"role": ClientRole.Audience,
},
{
"photo": "images/party/photo1.png",
"name": "小白",
"num": "122",
"title": "今日听君歌一曲",
"type": "family",
"sex": "0",
"role": ClientRole.Audience,
},
];
//
Future<void> _handleCameraAndMic(Permission permission) async {
PermissionStatus status = await permission.request();
print('权限状态$status');
if (!status.isGranted) {
openAppSettings();
}
}
//
Future<void> onJoin(name, role) async {
await _handleCameraAndMic(Permission.camera);
await _handleCameraAndMic(Permission.microphone);
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => PalRoomPage(
userName: name,
channelName: 'call',
role: role,
),
),
);
}
List<Widget> _tempList() {
var tempList = _list.map((value) {
return GestureDetector(
onTap: () => onJoin(value['name'], value['role']),
child: Container(
height: 75,
padding: EdgeInsets.all(5),
margin: EdgeInsets.fromLTRB(15, 30, 15, 0),
width: double.infinity,
decoration: BoxDecoration(
color: Color.fromRGBO(255, 255, 255, 1),
borderRadius: BorderRadius.all(Radius.circular(50)),
boxShadow: [
BoxShadow(
color: Color.fromRGBO(0, 0, 0, 0.1),
offset: Offset(0.0, 1.0), // xy轴偏移量
blurRadius: 1.0, //
spreadRadius: 1.0 //
)
],
),
child: Row(
children: [
ClipOval(
child: Image.asset(
value['photo'],
width: 65,
height: 65,
),
),
SizedBox(
width: 10,
),
Expanded(
flex: 1,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
children: [
typeElement(type: value['type']),
Container(
child: Text(
value['title'],
style: TextStyle(
color: Color.fromRGBO(51, 51, 51, 1),
fontSize: 16),
),
)
],
),
SizedBox(height: 9),
Row(
children: [
Image.asset(
'images/party/live.png',
width: 17,
height: 18,
),
SizedBox(width: 5),
Text(
value["num"] + '',
style: TextStyle(
color: Color.fromRGBO(153, 153, 153, 1),
fontSize: 12),
)
],
),
],
)),
],
),
),
);
});
return tempList.toList();
}
@override
Widget build(BuildContext context) {
return Column(
children: _tempList(),
);
}
}
//
class typeElement extends StatelessWidget {
String type;
var typeData = {
"music": {
'title': "音乐",
'color': [
Color.fromRGBO(207, 167, 248, 1),
Color.fromRGBO(133, 157, 254, 1),
],
},
"pal": {
"title": "交友",
'color': [
Color.fromRGBO(207, 167, 248, 1),
Color.fromRGBO(133, 157, 254, 1),
],
},
"auction": {
"title": "拍卖",
"color": [
Color.fromRGBO(249, 163, 125, 1),
Color.fromRGBO(251, 218, 137, 1),
]
},
"family": {
'title': "家族",
"color": [
Color.fromRGBO(85, 221, 236, 1),
Color.fromRGBO(66, 224, 154, 1),
]
},
};
var textData = {"music": '音乐', "pal": '交友', "auction": '拍卖', "family": '家族'};
var colorData = {
"music": [
Color.fromRGBO(207, 167, 248, 1),
Color.fromRGBO(133, 157, 254, 1),
],
"pal": [
Color.fromRGBO(254, 174, 205, 1),
Color.fromRGBO(247, 111, 162, 1),
],
"auction": [
Color.fromRGBO(249, 163, 125, 1),
Color.fromRGBO(251, 218, 137, 1),
],
"family": [
Color.fromRGBO(85, 221, 236, 1),
Color.fromRGBO(66, 224, 154, 1),
],
};
typeElement({Key? key, this.type = ''}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
width: 32,
height: 16,
margin: EdgeInsets.only(right: 5),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(8),
),
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: colorData[type] ?? [],
),
),
child: Text(
textData[type] ?? "",
textAlign: TextAlign.center,
style: TextStyle(color: Colors.white, fontSize: 10),
),
);
}
}

View File

@ -1,6 +1,13 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
agora_rtc_engine:
dependency: "direct main"
description:
name: agora_rtc_engine
url: "https://pub.flutter-io.cn"
source: hosted
version: "5.2.0"
async:
dependency: transitive
description:
@ -74,6 +81,25 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
flutter_web_plugins:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
js:
dependency: transitive
description:
name: js
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.6.4"
json_annotation:
dependency: transitive
description:
name: json_annotation
url: "https://pub.flutter-io.cn"
source: hosted
version: "4.6.0"
lints:
dependency: transitive
description:
@ -109,6 +135,27 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.8.1"
permission_handler:
dependency: "direct main"
description:
name: permission_handler
url: "https://pub.flutter-io.cn"
source: hosted
version: "8.3.0"
permission_handler_platform_interface:
dependency: transitive
description:
name: permission_handler_platform_interface
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.7.0"
plugin_platform_interface:
dependency: transitive
description:
name: plugin_platform_interface
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.2"
sky_engine:
dependency: transitive
description: flutter
@ -164,4 +211,5 @@ packages:
source: hosted
version: "2.1.2"
sdks:
dart: ">=2.17.5 <3.0.0"
dart: ">=2.17.0 <3.0.0"
flutter: ">=2.5.0"

View File

@ -18,7 +18,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
version: 1.0.0+1
environment:
sdk: ">=2.17.5 <3.0.0"
sdk: ">=2.17.0 <3.0.0"
# Dependencies specify other packages that your package needs in order to work.
# To automatically upgrade your package dependencies to the latest versions
@ -33,6 +33,8 @@ dependencies:
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
agora_rtc_engine: ^5.2.0
permission_handler: ^8.3.0
dev_dependencies:
flutter_test:
@ -67,6 +69,7 @@ flutter:
- images/tabs/discover_no.png
- images/tabs/mine_active.png
- images/tabs/mine_no.png
- images/home/header.png
- images/home/photo.png
- images/home/gold.png
@ -86,6 +89,24 @@ flutter:
- images/home/girl.png
- images/home/man.png
- images/home/right_arrow_green.png
- images/party/banner.png
- images/party/create.png
- images/party/live.png
- images/party/search.png
- images/party/photo1.png
- images/palRoom/more.png
- images/palRoom/add.png
- images/palRoom/face.png
- images/palRoom/photo.png
- images/palRoom/tip.png
- images/palRoom/voice1.png
- images/palRoom/voice2.png
- images/palRoom/volume.png
- images/palRoom/whiteLeft.png
- images/palRoom/whiteRight.png
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware