创建消息页面,交友语聊页面
|
|
@ -31,4 +31,22 @@
|
||||||
android:name="flutterEmbedding"
|
android:name="flutterEmbedding"
|
||||||
android:value="2" />
|
android:value="2" />
|
||||||
</application>
|
</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>
|
</manifest>
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,10 @@ allprojects {
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
mavenCentral()
|
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' }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
After Width: | Height: | Size: 634 B |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 511 B |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 605 B |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 763 B |
|
After Width: | Height: | Size: 330 B |
|
After Width: | Height: | Size: 253 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
|
@ -1 +1,2 @@
|
||||||
|
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
|
||||||
#include "Generated.xcconfig"
|
#include "Generated.xcconfig"
|
||||||
|
|
|
||||||
|
|
@ -1 +1,2 @@
|
||||||
|
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
|
||||||
#include "Generated.xcconfig"
|
#include "Generated.xcconfig"
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* 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 */; };
|
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
|
||||||
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
|
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
|
||||||
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
|
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
|
||||||
|
|
@ -29,9 +30,11 @@
|
||||||
/* End PBXCopyFilesBuildPhase section */
|
/* End PBXCopyFilesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXFileReference 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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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 */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
|
@ -49,6 +54,7 @@
|
||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
08976713930F537FC16A9989 /* Pods_Runner.framework in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
|
@ -72,6 +78,8 @@
|
||||||
9740EEB11CF90186004384FC /* Flutter */,
|
9740EEB11CF90186004384FC /* Flutter */,
|
||||||
97C146F01CF9000F007C117D /* Runner */,
|
97C146F01CF9000F007C117D /* Runner */,
|
||||||
97C146EF1CF9000F007C117D /* Products */,
|
97C146EF1CF9000F007C117D /* Products */,
|
||||||
|
D098840440D5B4B6826A83D3 /* Pods */,
|
||||||
|
CA63AB0B2A7C800A1A254681 /* Frameworks */,
|
||||||
);
|
);
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
|
@ -98,6 +106,25 @@
|
||||||
path = Runner;
|
path = Runner;
|
||||||
sourceTree = "<group>";
|
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 */
|
/* End PBXGroup section */
|
||||||
|
|
||||||
/* Begin PBXNativeTarget section */
|
/* Begin PBXNativeTarget section */
|
||||||
|
|
@ -105,12 +132,14 @@
|
||||||
isa = PBXNativeTarget;
|
isa = PBXNativeTarget;
|
||||||
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
|
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
|
||||||
buildPhases = (
|
buildPhases = (
|
||||||
|
C41E0D688505E9EBCE1BB5DA /* [CP] Check Pods Manifest.lock */,
|
||||||
9740EEB61CF901F6004384FC /* Run Script */,
|
9740EEB61CF901F6004384FC /* Run Script */,
|
||||||
97C146EA1CF9000F007C117D /* Sources */,
|
97C146EA1CF9000F007C117D /* Sources */,
|
||||||
97C146EB1CF9000F007C117D /* Frameworks */,
|
97C146EB1CF9000F007C117D /* Frameworks */,
|
||||||
97C146EC1CF9000F007C117D /* Resources */,
|
97C146EC1CF9000F007C117D /* Resources */,
|
||||||
9705A1C41CF9048500538489 /* Embed Frameworks */,
|
9705A1C41CF9048500538489 /* Embed Frameworks */,
|
||||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
|
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
|
||||||
|
A2955506D9FCC1C68D094BA7 /* [CP] Embed Pods Frameworks */,
|
||||||
);
|
);
|
||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
|
|
@ -197,6 +226,45 @@
|
||||||
shellPath = /bin/sh;
|
shellPath = /bin/sh;
|
||||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
|
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 */
|
/* End PBXShellScriptBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXSourcesBuildPhase section */
|
/* Begin PBXSourcesBuildPhase section */
|
||||||
|
|
|
||||||
|
|
@ -4,4 +4,7 @@
|
||||||
<FileRef
|
<FileRef
|
||||||
location = "group:Runner.xcodeproj">
|
location = "group:Runner.xcodeproj">
|
||||||
</FileRef>
|
</FileRef>
|
||||||
|
<FileRef
|
||||||
|
location = "group:Pods/Pods.xcodeproj">
|
||||||
|
</FileRef>
|
||||||
</Workspace>
|
</Workspace>
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,27 @@
|
||||||
<string>$(FLUTTER_BUILD_NUMBER)</string>
|
<string>$(FLUTTER_BUILD_NUMBER)</string>
|
||||||
<key>LSRequiresIPhoneOS</key>
|
<key>LSRequiresIPhoneOS</key>
|
||||||
<true/>
|
<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>
|
<key>UILaunchStoryboardName</key>
|
||||||
<string>LaunchScreen</string>
|
<string>LaunchScreen</string>
|
||||||
<key>UIMainStoryboardFile</key>
|
<key>UIMainStoryboardFile</key>
|
||||||
|
|
|
||||||
73
lib/Tab.dart
|
|
@ -43,6 +43,7 @@ class _TabsState extends State<Tabs> {
|
||||||
this._currentIndex = index;
|
this._currentIndex = index;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
backgroundColor: Colors.white,
|
||||||
items: [
|
items: [
|
||||||
BottomNavigationBarItem(
|
BottomNavigationBarItem(
|
||||||
icon: Image.asset(
|
icon: Image.asset(
|
||||||
|
|
@ -112,42 +113,42 @@ class _TabsState extends State<Tabs> {
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
drawer: Drawer(
|
// drawer: Drawer(
|
||||||
child: Column(
|
// child: Column(
|
||||||
children: [
|
// children: [
|
||||||
Row(
|
// Row(
|
||||||
children: [
|
// children: [
|
||||||
Expanded(
|
// Expanded(
|
||||||
child: DrawerHeader(
|
// child: DrawerHeader(
|
||||||
child: Text("Drawer组件"),
|
// child: Text("Drawer组件"),
|
||||||
decoration: BoxDecoration(
|
// decoration: BoxDecoration(
|
||||||
image: DecorationImage(
|
// image: DecorationImage(
|
||||||
image: NetworkImage(
|
// image: NetworkImage(
|
||||||
'https://www.itying.com/images/flutter/2.png'),
|
// 'https://www.itying.com/images/flutter/2.png'),
|
||||||
fit: BoxFit.cover),
|
// fit: BoxFit.cover),
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
)
|
// )
|
||||||
],
|
// ],
|
||||||
),
|
// ),
|
||||||
ListTile(
|
// ListTile(
|
||||||
title: Text('我的空间'),
|
// title: Text('我的空间'),
|
||||||
leading: Icon(Icons.home),
|
// leading: Icon(Icons.home),
|
||||||
),
|
// ),
|
||||||
ListTile(
|
// ListTile(
|
||||||
title: Text('设置'),
|
// title: Text('设置'),
|
||||||
leading: Icon(Icons.settings),
|
// leading: Icon(Icons.settings),
|
||||||
onTap: () {
|
// onTap: () {
|
||||||
Navigator.of(context).pop(); //隐藏侧边栏
|
// Navigator.of(context).pop(); //隐藏侧边栏
|
||||||
Navigator.of(context).pushNamed('/routeParms');
|
// Navigator.of(context).pushNamed('/routeParms');
|
||||||
},
|
// },
|
||||||
)
|
// )
|
||||||
],
|
// ],
|
||||||
),
|
// ),
|
||||||
),
|
// ),
|
||||||
endDrawer: Drawer(
|
// endDrawer: Drawer(
|
||||||
child: Text('右侧抽屉'),
|
// child: Text('右侧抽屉'),
|
||||||
),
|
// ),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,9 +18,11 @@ import '../Tab.dart';
|
||||||
// import '../pages/dialog/Dialog.dart';
|
// import '../pages/dialog/Dialog.dart';
|
||||||
// import '../pages/https/Https.dart';
|
// import '../pages/https/Https.dart';
|
||||||
// import '../views/home/Home.dart';
|
// import '../views/home/Home.dart';
|
||||||
|
import '../views/palRoom/PalRoom.dart';
|
||||||
|
|
||||||
final routes = {
|
final routes = {
|
||||||
'/': (context) => Tabs(),
|
'/': (context) => Tabs(),
|
||||||
|
'PalRoom': (context) => PalRoomPage(),
|
||||||
// '/home': (context) => HomePage(),
|
// '/home': (context) => HomePage(),
|
||||||
// '/routeParms': (context, {arguments}) => RouteParmsPage(arguments: arguments),
|
// '/routeParms': (context, {arguments}) => RouteParmsPage(arguments: arguments),
|
||||||
// '/RouteParmsDT': (context, {arguments}) =>
|
// '/RouteParmsDT': (context, {arguments}) =>
|
||||||
|
|
@ -40,6 +42,7 @@ final routes = {
|
||||||
// '/dialog': (context) => DialogPage(),
|
// '/dialog': (context) => DialogPage(),
|
||||||
// '/https': (context) => HttpsPage(),
|
// '/https': (context) => HttpsPage(),
|
||||||
};
|
};
|
||||||
|
|
||||||
var onGenerateRoute = (RouteSettings settings) {
|
var onGenerateRoute = (RouteSettings settings) {
|
||||||
// 统一处理
|
// 统一处理
|
||||||
final String? name = settings.name;
|
final String? name = settings.name;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
const APP_ID = '809529cf18814549a0249802512a7508';
|
||||||
|
const Token =
|
||||||
|
'006809529cf18814549a0249802512a7508IAAPcoSQKL/h/B6xy0PPG/XdoZUWas07EdCBtxLe7HH4Hz4vjswAAAAAEABsSV6NzT/fYgEAAQDKP99i';
|
||||||
|
|
@ -320,11 +320,8 @@ class _RoomComponentState extends State<RoomComponent> {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(
|
|
||||||
height: 10,
|
|
||||||
), //设置上下的间距
|
|
||||||
Container(
|
Container(
|
||||||
padding: EdgeInsets.only(left: 10),
|
padding: EdgeInsets.only(left: 10, top: 10),
|
||||||
child: Text(
|
child: Text(
|
||||||
item['title'],
|
item['title'],
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,9 @@
|
||||||
import 'package:flutter/material.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 'package:will_play/views/palRoom/PalRoom.dart';
|
||||||
|
|
||||||
class PartyPage extends StatefulWidget {
|
class PartyPage extends StatefulWidget {
|
||||||
PartyPage({Key? key}) : super(key: key);
|
PartyPage({Key? key}) : super(key: key);
|
||||||
|
|
@ -8,10 +13,403 @@ class PartyPage extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _PartyPageState extends State<PartyPage> {
|
class _PartyPageState extends State<PartyPage> {
|
||||||
|
final _search = TextEditingController();
|
||||||
|
final _tabDataList = [
|
||||||
|
Tab(text: '关注'),
|
||||||
|
Tab(text: '推荐'),
|
||||||
|
Tab(text: '相亲'),
|
||||||
|
Tab(text: 'KTV'),
|
||||||
|
Tab(text: '交友'),
|
||||||
|
Tab(text: '音乐'),
|
||||||
|
];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Container(
|
return DefaultTabController(
|
||||||
child: Text('派对'),
|
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),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
50
pubspec.lock
|
|
@ -1,6 +1,13 @@
|
||||||
# Generated by pub
|
# Generated by pub
|
||||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||||
packages:
|
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:
|
async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -74,6 +81,25 @@ packages:
|
||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
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:
|
lints:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -109,6 +135,27 @@ packages:
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.8.1"
|
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:
|
sky_engine:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description: flutter
|
description: flutter
|
||||||
|
|
@ -164,4 +211,5 @@ packages:
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.2"
|
version: "2.1.2"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=2.17.5 <3.0.0"
|
dart: ">=2.17.0 <3.0.0"
|
||||||
|
flutter: ">=2.5.0"
|
||||||
|
|
|
||||||
23
pubspec.yaml
|
|
@ -18,7 +18,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
|
||||||
version: 1.0.0+1
|
version: 1.0.0+1
|
||||||
|
|
||||||
environment:
|
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.
|
# Dependencies specify other packages that your package needs in order to work.
|
||||||
# To automatically upgrade your package dependencies to the latest versions
|
# 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.
|
# The following adds the Cupertino Icons font to your application.
|
||||||
# Use with the CupertinoIcons class for iOS style icons.
|
# Use with the CupertinoIcons class for iOS style icons.
|
||||||
cupertino_icons: ^1.0.2
|
cupertino_icons: ^1.0.2
|
||||||
|
agora_rtc_engine: ^5.2.0
|
||||||
|
permission_handler: ^8.3.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|
@ -67,6 +69,7 @@ flutter:
|
||||||
- images/tabs/discover_no.png
|
- images/tabs/discover_no.png
|
||||||
- images/tabs/mine_active.png
|
- images/tabs/mine_active.png
|
||||||
- images/tabs/mine_no.png
|
- images/tabs/mine_no.png
|
||||||
|
|
||||||
- images/home/header.png
|
- images/home/header.png
|
||||||
- images/home/photo.png
|
- images/home/photo.png
|
||||||
- images/home/gold.png
|
- images/home/gold.png
|
||||||
|
|
@ -86,6 +89,24 @@ flutter:
|
||||||
- images/home/girl.png
|
- images/home/girl.png
|
||||||
- images/home/man.png
|
- images/home/man.png
|
||||||
- images/home/right_arrow_green.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
|
# An image asset can refer to one or more resolution-specific "variants", see
|
||||||
# https://flutter.dev/assets-and-images/#resolution-aware
|
# https://flutter.dev/assets-and-images/#resolution-aware
|
||||||
|
|
||||||
|
|
|
||||||