添加登录页,语聊房页,tost插件封装,dio封装
This commit is contained in:
parent
1da36a36f7
commit
35822f4287
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
|
|
@ -4,23 +4,31 @@ PODS:
|
||||||
- Flutter
|
- Flutter
|
||||||
- AgoraIrisRTC_iOS (3.6.2-fix.1)
|
- AgoraIrisRTC_iOS (3.6.2-fix.1)
|
||||||
- Flutter (1.0.0)
|
- Flutter (1.0.0)
|
||||||
|
- fluttertoast (0.0.2):
|
||||||
|
- Flutter
|
||||||
|
- Toast
|
||||||
- "permission_handler (5.1.0+2)":
|
- "permission_handler (5.1.0+2)":
|
||||||
- Flutter
|
- Flutter
|
||||||
|
- Toast (4.0.0)
|
||||||
|
|
||||||
DEPENDENCIES:
|
DEPENDENCIES:
|
||||||
- agora_rtc_engine (from `.symlinks/plugins/agora_rtc_engine/ios`)
|
- agora_rtc_engine (from `.symlinks/plugins/agora_rtc_engine/ios`)
|
||||||
- Flutter (from `Flutter`)
|
- Flutter (from `Flutter`)
|
||||||
|
- fluttertoast (from `.symlinks/plugins/fluttertoast/ios`)
|
||||||
- permission_handler (from `.symlinks/plugins/permission_handler/ios`)
|
- permission_handler (from `.symlinks/plugins/permission_handler/ios`)
|
||||||
|
|
||||||
SPEC REPOS:
|
SPEC REPOS:
|
||||||
trunk:
|
trunk:
|
||||||
- AgoraIrisRTC_iOS
|
- AgoraIrisRTC_iOS
|
||||||
|
- Toast
|
||||||
|
|
||||||
EXTERNAL SOURCES:
|
EXTERNAL SOURCES:
|
||||||
agora_rtc_engine:
|
agora_rtc_engine:
|
||||||
:path: ".symlinks/plugins/agora_rtc_engine/ios"
|
:path: ".symlinks/plugins/agora_rtc_engine/ios"
|
||||||
Flutter:
|
Flutter:
|
||||||
:path: Flutter
|
:path: Flutter
|
||||||
|
fluttertoast:
|
||||||
|
:path: ".symlinks/plugins/fluttertoast/ios"
|
||||||
permission_handler:
|
permission_handler:
|
||||||
:path: ".symlinks/plugins/permission_handler/ios"
|
:path: ".symlinks/plugins/permission_handler/ios"
|
||||||
|
|
||||||
|
|
@ -28,7 +36,9 @@ SPEC CHECKSUMS:
|
||||||
agora_rtc_engine: ffc530eff766a38272568ebaead9341d73f58856
|
agora_rtc_engine: ffc530eff766a38272568ebaead9341d73f58856
|
||||||
AgoraIrisRTC_iOS: 9b11083bb79048ae4db7e2f56109cc51ac9e3834
|
AgoraIrisRTC_iOS: 9b11083bb79048ae4db7e2f56109cc51ac9e3834
|
||||||
Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a
|
Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a
|
||||||
|
fluttertoast: 6122fa75143e992b1d3470f61000f591a798cc58
|
||||||
permission_handler: ccb20a9fad0ee9b1314a52b70b76b473c5f8dab0
|
permission_handler: ccb20a9fad0ee9b1314a52b70b76b473c5f8dab0
|
||||||
|
Toast: 91b396c56ee72a5790816f40d3a94dd357abc196
|
||||||
|
|
||||||
PODFILE CHECKSUM: bd5ecd90bb4d3dada07dd6c6725bb70ab42e9619
|
PODFILE CHECKSUM: bd5ecd90bb4d3dada07dd6c6725bb70ab42e9619
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ class _TabsState extends State<Tabs> {
|
||||||
InformationPage(),
|
InformationPage(),
|
||||||
MinePage()
|
MinePage()
|
||||||
];
|
];
|
||||||
|
|
||||||
_TabsState(index) {
|
_TabsState(index) {
|
||||||
this._currentIndex = index;
|
this._currentIndex = index;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,13 @@ class _MyAppState extends State<MyApp> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
|
theme: ThemeData(
|
||||||
|
primarySwatch: Colors.pink,
|
||||||
|
splashColor: Colors.transparent, // 点击时的高亮效果设置为透明
|
||||||
|
highlightColor: Colors.transparent, // 长按时的扩散效果设置为透明
|
||||||
|
),
|
||||||
debugShowCheckedModeBanner: false,
|
debugShowCheckedModeBanner: false,
|
||||||
initialRoute: '/', //默认跳转页面
|
initialRoute: 'Login', // 默认跳转页面
|
||||||
theme: ThemeData(primarySwatch: Colors.pink),
|
|
||||||
onGenerateRoute: onGenerateRoute,
|
onGenerateRoute: onGenerateRoute,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,46 +1,14 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import '../Tab.dart';
|
import '../Tab.dart';
|
||||||
// import '../pages/routeParms/RouteParms.dart';
|
|
||||||
// import '../pages/routeParmsDT/RouteParmsDT.dart';
|
|
||||||
|
|
||||||
// import '../pages/login/Login.dart';
|
|
||||||
// import '../pages/login/RegisterFirsr.dart';
|
|
||||||
// import '../pages/login/RegisterSecond.dart';
|
|
||||||
// import '../pages/login/RegisterThird.dart';
|
|
||||||
// import '../pages/appBarDemo/AppBarDemo.dart';
|
|
||||||
// import '../pages/appBarDemo/AppBarController.dart';
|
|
||||||
// import '../pages/button/Button.dart';
|
|
||||||
// import '../pages/textField/TextField.dart';
|
|
||||||
// import '../pages/textField/Checkbox.dart';
|
|
||||||
// import '../pages/textField/Radio.dart';
|
|
||||||
// import '../pages/textField/FormDemo.dart';
|
|
||||||
// import '../pages/date/Date.dart';
|
|
||||||
// import '../pages/dialog/Dialog.dart';
|
|
||||||
// import '../pages/https/Https.dart';
|
|
||||||
// import '../views/home/Home.dart';
|
|
||||||
import '../views/palRoom/PalRoom.dart';
|
import '../views/palRoom/PalRoom.dart';
|
||||||
|
import '../views/createRoom/CreateRoom.dart';
|
||||||
|
import '../views/login/Login.dart';
|
||||||
|
|
||||||
final routes = {
|
final routes = {
|
||||||
'/': (context) => Tabs(),
|
'/': (context) => Tabs(),
|
||||||
'PalRoom': (context) => PalRoomPage(),
|
'PalRoom': (context) => PalRoomPage(),
|
||||||
// '/home': (context) => HomePage(),
|
'CreateRoom': (context) => CreateRoomPage(),
|
||||||
// '/routeParms': (context, {arguments}) => RouteParmsPage(arguments: arguments),
|
'Login': (context) => LoginPage(),
|
||||||
// '/RouteParmsDT': (context, {arguments}) =>
|
|
||||||
// RouteParmsDTPage(arguments: arguments),
|
|
||||||
// '/login': (context) => LoginPage(),
|
|
||||||
// '/registerFirsr': (context) => RegisterFirsrPage(),
|
|
||||||
// '/registerSecond': (context) => RegisterSecondPage(),
|
|
||||||
// '/registerThird': (context) => RegisterThirdPage(),
|
|
||||||
// '/appBarDemo': (context) => AppBarDemoPage(),
|
|
||||||
// '/appBarController': (context) => AppBarControllerPage(),
|
|
||||||
// '/button': (context) => ButtonPage(),
|
|
||||||
// '/textField': (context) => TextFieldPage(),
|
|
||||||
// '/checkbox': (context) => CheckboxPage(),
|
|
||||||
// '/radio': (context) => RadioPage(),
|
|
||||||
// '/formDemo': (context) => FormDemoPage(),
|
|
||||||
// '/date': (context) => DatePage(),
|
|
||||||
// '/dialog': (context) => DialogPage(),
|
|
||||||
// '/https': (context) => HttpsPage(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var onGenerateRoute = (RouteSettings settings) {
|
var onGenerateRoute = (RouteSettings settings) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,102 @@
|
||||||
|
import 'package:dio/dio.dart';
|
||||||
|
|
||||||
|
var token =
|
||||||
|
'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwidXNlcm5hbWUiOiJ0ZXN0MSJ9.GV21nLXeLwZI7lB5Mp2lk9kEBJl4kJOPtw7YXwXINrE';
|
||||||
|
|
||||||
|
// Dio dio = new Dio();
|
||||||
|
// dio.options = BaseOptions(
|
||||||
|
// baseUrl: 'http://101.35.117.69:9093/',
|
||||||
|
// connectTimeout: 5000,
|
||||||
|
// receiveTimeout: 5000,
|
||||||
|
// headers: {"Authorization": 'Bearer ${token}'},
|
||||||
|
// contentType: Headers.formUrlEncodedContentType,
|
||||||
|
// );
|
||||||
|
|
||||||
|
// dio.Interceptors.add(
|
||||||
|
// InterceptorsWrapper(
|
||||||
|
// onRequest: (options, handler) {},
|
||||||
|
// onResponse: (response, handler) {},
|
||||||
|
// onError: (DioError e, handler) {},
|
||||||
|
// ),
|
||||||
|
// );
|
||||||
|
|
||||||
|
class dioHttp {
|
||||||
|
static final options = BaseOptions(
|
||||||
|
baseUrl: 'http://101.35.117.69:9093/',
|
||||||
|
connectTimeout: 5000,
|
||||||
|
receiveTimeout: 5000,
|
||||||
|
headers: {"Authorization": 'Bearer ${token}'},
|
||||||
|
);
|
||||||
|
|
||||||
|
Dio dio = new Dio(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dio dio = new Dio(
|
||||||
|
// BaseOptions(
|
||||||
|
// baseUrl: 'http://101.35.117.69:9093/',
|
||||||
|
// connectTimeout: 5000,
|
||||||
|
// receiveTimeout: 5000,
|
||||||
|
// headers: {"Authorization": 'Bearer ${token}'},
|
||||||
|
// contentType: Headers.formUrlEncodedContentType,
|
||||||
|
// ),
|
||||||
|
// Interceptors.add(
|
||||||
|
// InterceptorsWrapper(
|
||||||
|
// onRequest: (options, handler) {},
|
||||||
|
// onResponse: (response, handler) {},
|
||||||
|
// onError: (DioError e, handler) {},
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// );
|
||||||
|
|
||||||
|
|
||||||
|
// //添加拦截器
|
||||||
|
// dio.interceptors.add(InterceptorsWrapper(
|
||||||
|
// onRequest:(options, handler){
|
||||||
|
// // Do something before request is sent
|
||||||
|
// return handler.next(options); //continue
|
||||||
|
// // 如果你想完成请求并返回一些自定义数据,你可以resolve一个Response对象 `handler.resolve(response)`。
|
||||||
|
// // 这样请求将会被终止,上层then会被调用,then中返回的数据将是你的自定义response.
|
||||||
|
// //
|
||||||
|
// // 如果你想终止请求并触发一个错误,你可以返回一个`DioError`对象,如`handler.reject(error)`,
|
||||||
|
// // 这样请求将被中止并触发异常,上层catchError会被调用。
|
||||||
|
// },
|
||||||
|
// onResponse:(response,handler) {
|
||||||
|
// // Do something with response data
|
||||||
|
// return handler.next(response); // continue
|
||||||
|
// // 如果你想终止请求并触发一个错误,你可以 reject 一个`DioError`对象,如`handler.reject(error)`,
|
||||||
|
// // 这样请求将被中止并触发异常,上层catchError会被调用。
|
||||||
|
// },
|
||||||
|
// onError: (DioError e, handler) {
|
||||||
|
// // Do something with response error
|
||||||
|
// return handler.next(e);//continue
|
||||||
|
// // 如果你想完成请求并返回一些自定义数据,可以resolve 一个`Response`,如`handler.resolve(response)`。
|
||||||
|
// // 这样请求将会被终止,上层then会被调用,then中返回的数据将是你的自定义response.
|
||||||
|
// }
|
||||||
|
// ));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// // 发起一个 GET 请求:
|
||||||
|
// Response response;
|
||||||
|
// var dio = Dio();
|
||||||
|
// response = await dio.get('/test?id=12&name=wendu');
|
||||||
|
// print(response.data.toString());
|
||||||
|
// // 上面的请求也可以这样做
|
||||||
|
// response = await dio.get('/test', queryParameters: {'id': 12, 'name': 'wendu'});
|
||||||
|
// print(response.data.toString());
|
||||||
|
|
||||||
|
// // 发起一个 POST 请求:
|
||||||
|
// response = await dio.post('/test', data: {'id': 12, 'name': 'wendu'});
|
||||||
|
|
||||||
|
// // 发起多个并发请求:
|
||||||
|
// response = await Future.wait([dio.post('/info'), dio.get('/token')]);
|
||||||
|
|
||||||
|
// // 下载文件:
|
||||||
|
// response = await dio.download('https://www.google.com/', './xx.html');
|
||||||
|
|
||||||
|
// // 发送 FormData:
|
||||||
|
// var formData = FormData.fromMap({
|
||||||
|
// 'name': 'wendux',
|
||||||
|
// 'age': 25,
|
||||||
|
// });
|
||||||
|
// var response = await dio.post('/info', data: formData);
|
||||||
|
|
@ -0,0 +1,98 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:fluttertoast/fluttertoast.dart';
|
||||||
|
|
||||||
|
// 普通气泡弹框
|
||||||
|
// 使用:showToast("xxxxxxx");
|
||||||
|
void showToast(
|
||||||
|
String text, {
|
||||||
|
gravity: ToastGravity.CENTER,
|
||||||
|
toastLength: Toast.LENGTH_SHORT,
|
||||||
|
}) {
|
||||||
|
Fluttertoast.showToast(
|
||||||
|
msg: text,
|
||||||
|
toastLength: Toast.LENGTH_SHORT,
|
||||||
|
gravity: ToastGravity.CENTER,
|
||||||
|
timeInSecForIosWeb: 3,
|
||||||
|
backgroundColor: Colors.grey[600], // 灰色背景
|
||||||
|
fontSize: 16.0,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 一个加载中的动画,不传text时,默认显示文字Loading...
|
||||||
|
// 使用:showLoading(context, 'xxxxxxx');
|
||||||
|
void showLoading(context, text) {
|
||||||
|
text = text ?? "Loading...";
|
||||||
|
showDialog(
|
||||||
|
barrierDismissible: false,
|
||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
return Center(
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(3.0),
|
||||||
|
boxShadow: [
|
||||||
|
// 阴影
|
||||||
|
BoxShadow(
|
||||||
|
color: Colors.black12,
|
||||||
|
//offset: Offset(2.0,2.0),
|
||||||
|
blurRadius: 10.0,
|
||||||
|
)
|
||||||
|
]),
|
||||||
|
padding: EdgeInsets.all(16),
|
||||||
|
margin: EdgeInsets.all(16),
|
||||||
|
constraints: BoxConstraints(minHeight: 120, minWidth: 180),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: <Widget>[
|
||||||
|
SizedBox(
|
||||||
|
height: 30,
|
||||||
|
width: 30,
|
||||||
|
child: CircularProgressIndicator(
|
||||||
|
strokeWidth: 3,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 20.0),
|
||||||
|
child: Text(
|
||||||
|
text,
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 带有确定取消按钮的提示框,content是提示框的内容文字,confirmCallback是点击确定按钮的回调
|
||||||
|
// 使用:showConfirmDialog(context, '确认xxxxxxx吗?', () {print('xxxxxxx');});
|
||||||
|
void showConfirmDialog(
|
||||||
|
BuildContext context, String content, Function confirmCallback) {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
return AlertDialog(
|
||||||
|
title: Text("提示"),
|
||||||
|
content: Text(content),
|
||||||
|
actions: <Widget>[
|
||||||
|
FlatButton(
|
||||||
|
onPressed: () {
|
||||||
|
confirmCallback();
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
child: Text("确认"),
|
||||||
|
),
|
||||||
|
FlatButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
child: Text("取消"),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,315 @@
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class CreateRoomPage extends StatefulWidget {
|
||||||
|
CreateRoomPage({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<CreateRoomPage> createState() => _CreateRoomPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CreateRoomPageState extends State<CreateRoomPage> {
|
||||||
|
final _formKey = GlobalKey<FormState>();
|
||||||
|
final _roomName = TextEditingController();
|
||||||
|
bool flag = false;
|
||||||
|
|
||||||
|
List patternList = [
|
||||||
|
RadioModel(
|
||||||
|
true,
|
||||||
|
'普通',
|
||||||
|
),
|
||||||
|
RadioModel(
|
||||||
|
false,
|
||||||
|
'相亲',
|
||||||
|
),
|
||||||
|
RadioModel(
|
||||||
|
false,
|
||||||
|
'拍卖',
|
||||||
|
),
|
||||||
|
RadioModel(
|
||||||
|
false,
|
||||||
|
'KTV',
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
|
List tagList = [
|
||||||
|
RadioModel(
|
||||||
|
true,
|
||||||
|
'交友',
|
||||||
|
),
|
||||||
|
RadioModel(
|
||||||
|
false,
|
||||||
|
'音乐',
|
||||||
|
),
|
||||||
|
RadioModel(
|
||||||
|
false,
|
||||||
|
'游戏',
|
||||||
|
),
|
||||||
|
RadioModel(
|
||||||
|
false,
|
||||||
|
'连麦聊',
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
|
Widget _buttonstyle(theme, parameter) {
|
||||||
|
return Container(
|
||||||
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
width: 80.0,
|
||||||
|
height: 40.0,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(2)),
|
||||||
|
border: Border.all(
|
||||||
|
width: 1,
|
||||||
|
color: parameter.isSelected
|
||||||
|
? theme
|
||||||
|
: Color.fromRGBO(222, 222, 222, 1)),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
"${parameter.buttonText}",
|
||||||
|
style: TextStyle(
|
||||||
|
color: parameter.isSelected
|
||||||
|
? theme
|
||||||
|
: Color.fromRGBO(51, 51, 51, 1)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
elevation: 0, // z轴阴影
|
||||||
|
titleSpacing: 0, // 标题与其他控件的间隔
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
leading: IconButton(
|
||||||
|
icon: Icon(Icons.arrow_back_ios, color: Colors.black),
|
||||||
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
|
),
|
||||||
|
title: Text(
|
||||||
|
'创建派对房间',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Color.fromRGBO(51, 51, 51, 1),
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
resizeToAvoidBottomInset: false,
|
||||||
|
body: Container(
|
||||||
|
padding: EdgeInsets.all(15),
|
||||||
|
child: Form(
|
||||||
|
key: _formKey,
|
||||||
|
// autovalidateMode: AutovalidateMode.onUserInteraction, // 自动验证
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
|
TextFormField(
|
||||||
|
controller: _roomName,
|
||||||
|
validator: (value) {
|
||||||
|
return value!.trim().isEmpty ? '请输入房间名' : null;
|
||||||
|
},
|
||||||
|
style: TextStyle(fontSize: 16.0),
|
||||||
|
textInputAction: TextInputAction.next,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
hintText: '输入房间名',
|
||||||
|
hintStyle:
|
||||||
|
TextStyle(color: Color.fromRGBO(187, 187, 187, 1)),
|
||||||
|
contentPadding:
|
||||||
|
EdgeInsets.all(15.0), // 输入内容距离上下左右距离,该属性控制高度
|
||||||
|
fillColor: Color.fromRGBO(247, 248, 250, 1), // 输入框的背景填充颜色
|
||||||
|
filled: true,
|
||||||
|
suffixIcon: IconButton(
|
||||||
|
icon: Image.asset(
|
||||||
|
'images/createRoom/refresh.png',
|
||||||
|
width: 12.0,
|
||||||
|
height: 17.0,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
_roomName.clear();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
border: OutlineInputBorder(
|
||||||
|
borderRadius: BorderRadius.circular(10),
|
||||||
|
borderSide: BorderSide.none,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 25.0),
|
||||||
|
|
||||||
|
// 房间模式_单选框
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.fromLTRB(0, 0, 0, 25),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'房间模式',
|
||||||
|
textAlign: TextAlign.left,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.0,
|
||||||
|
color: Color.fromRGBO(153, 153, 153, 1),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 15),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: List<Widget>.generate(patternList.length,
|
||||||
|
(index) {
|
||||||
|
return InkWell(
|
||||||
|
child: _buttonstyle(
|
||||||
|
Color.fromRGBO(21, 185, 208, 1),
|
||||||
|
patternList[index]),
|
||||||
|
onTap: () {
|
||||||
|
setState(() {
|
||||||
|
patternList.forEach(
|
||||||
|
(element) => element.isSelected = false);
|
||||||
|
print(patternList[index].buttonText);
|
||||||
|
patternList[index].isSelected = true;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
// 房间标签_单选框
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.fromLTRB(0, 0, 0, 25),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'房间标签',
|
||||||
|
textAlign: TextAlign.left,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14.0,
|
||||||
|
color: Color.fromRGBO(153, 153, 153, 1),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 15),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children:
|
||||||
|
List<Widget>.generate(tagList.length, (index) {
|
||||||
|
return InkWell(
|
||||||
|
child: _buttonstyle(
|
||||||
|
Color.fromRGBO(239, 134, 146, 1),
|
||||||
|
tagList[index]),
|
||||||
|
onTap: () {
|
||||||
|
setState(() {
|
||||||
|
tagList.forEach(
|
||||||
|
(element) => element.isSelected = false);
|
||||||
|
print(tagList[index].buttonText);
|
||||||
|
tagList[index].isSelected = true;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
Divider(
|
||||||
|
height: 1.0,
|
||||||
|
color: Color.fromRGBO(235, 235, 235, 1),
|
||||||
|
),
|
||||||
|
SizedBox(height: 25.0),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'房间密码',
|
||||||
|
style: TextStyle(color: Colors.black, fontSize: 16.0),
|
||||||
|
),
|
||||||
|
CupertinoSwitch(
|
||||||
|
value: flag,
|
||||||
|
activeColor: Color.fromRGBO(21, 185, 208, 1),
|
||||||
|
onChanged: (value) {
|
||||||
|
setState(() {
|
||||||
|
flag = value;
|
||||||
|
print(flag);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(height: 40.0),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'修改密码',
|
||||||
|
style: TextStyle(color: Colors.black, fontSize: 16.0),
|
||||||
|
),
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
print('箭头图标被点击');
|
||||||
|
},
|
||||||
|
child: Icon(
|
||||||
|
size: 16.0,
|
||||||
|
Icons.arrow_forward_ios,
|
||||||
|
color: Color.fromRGBO(153, 153, 153, 1),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'派对房间管理规范',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Color.fromRGBO(153, 153, 153, 1),
|
||||||
|
fontSize: 12.0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(height: 5.0),
|
||||||
|
ElevatedButton(
|
||||||
|
child: const Text(
|
||||||
|
'创建',
|
||||||
|
style: TextStyle(fontSize: 16.0, color: Colors.white),
|
||||||
|
),
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
primary: Color.fromRGBO(21, 185, 208, 1),
|
||||||
|
minimumSize: Size(188, 50),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(30)),
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
if (_formKey.currentState!.validate()) {
|
||||||
|
print('表单验证通过!');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
SizedBox(height: 52.0),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class RadioModel {
|
||||||
|
bool isSelected;
|
||||||
|
final String buttonText;
|
||||||
|
RadioModel(
|
||||||
|
this.isSelected,
|
||||||
|
this.buttonText,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,89 @@
|
||||||
|
// import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
// class CustomRadioWidget extends StatefulWidget {
|
||||||
|
// // final List list;
|
||||||
|
|
||||||
|
// CustomRadioWidget({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
// @override
|
||||||
|
// State<CustomRadioWidget> createState() => _CustomRadioWidgetState();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// class _CustomRadioWidgetState extends State<CustomRadioWidget> {
|
||||||
|
// Widget _buttonstyle(theme, parameter) {
|
||||||
|
// return Container(
|
||||||
|
// child: Stack(
|
||||||
|
// children: [
|
||||||
|
// Container(
|
||||||
|
// width: 80.0,
|
||||||
|
// height: 40.0,
|
||||||
|
// decoration: BoxDecoration(
|
||||||
|
// borderRadius: BorderRadius.all(Radius.circular(2)),
|
||||||
|
// border: Border.all(
|
||||||
|
// width: 1,
|
||||||
|
// color: parameter.isSelected
|
||||||
|
// ? theme
|
||||||
|
// : Color.fromRGBO(222, 222, 222, 1)),
|
||||||
|
// ),
|
||||||
|
// child: Center(
|
||||||
|
// child: Text(
|
||||||
|
// "${parameter.buttonText}",
|
||||||
|
// style: TextStyle(
|
||||||
|
// color: parameter.isSelected
|
||||||
|
// ? theme
|
||||||
|
// : Color.fromRGBO(51, 51, 51, 1)),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
||||||
|
// @override
|
||||||
|
// Widget build(BuildContext context) {
|
||||||
|
// return Container(
|
||||||
|
// padding: EdgeInsets.fromLTRB(0, 0, 0, 25),
|
||||||
|
// child: Column(
|
||||||
|
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
// children: [
|
||||||
|
// Text(
|
||||||
|
// '房间模式',
|
||||||
|
// textAlign: TextAlign.left,
|
||||||
|
// style: TextStyle(
|
||||||
|
// fontSize: 14.0,
|
||||||
|
// color: Color.fromRGBO(153, 153, 153, 1),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// SizedBox(height: 15),
|
||||||
|
// Row(
|
||||||
|
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
// children: List<Widget>.generate(widget.list.length, (index) {
|
||||||
|
// return InkWell(
|
||||||
|
// child: _buttonstyle(
|
||||||
|
// Color.fromRGBO(21, 185, 208, 1), widget.list[index]),
|
||||||
|
// onTap: () {
|
||||||
|
// setState(() {
|
||||||
|
// widget.list
|
||||||
|
// .forEach((element) => element.isSelected = false);
|
||||||
|
// print(widget.list[index].buttonText);
|
||||||
|
// widget.list[index].isSelected = true;
|
||||||
|
// });
|
||||||
|
// },
|
||||||
|
// );
|
||||||
|
// }),
|
||||||
|
// ),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// class RadioModel {
|
||||||
|
// bool isSelected;
|
||||||
|
// final String buttonText;
|
||||||
|
// RadioModel(
|
||||||
|
// this.isSelected,
|
||||||
|
// this.buttonText,
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
@ -0,0 +1,177 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import '../../utils/showToast.dart';
|
||||||
|
import '../../utils/dioHttp.dart';
|
||||||
|
|
||||||
|
class LoginPage extends StatefulWidget {
|
||||||
|
LoginPage({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<LoginPage> createState() => _LoginPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _LoginPageState extends State<LoginPage> {
|
||||||
|
final _formKey = GlobalKey<FormState>();
|
||||||
|
final _userName = TextEditingController();
|
||||||
|
final _password = TextEditingController();
|
||||||
|
bool checked = true;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
appBar: AppBar(
|
||||||
|
elevation: 0, // z轴阴影
|
||||||
|
titleSpacing: 0, // 标题与其他控件的间隔
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
leading: IconButton(
|
||||||
|
icon: Icon(Icons.arrow_back_ios, color: Colors.black),
|
||||||
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
|
),
|
||||||
|
title: Text(
|
||||||
|
'登录',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Color.fromRGBO(51, 51, 51, 1),
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
body: Padding(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 30),
|
||||||
|
child: Form(
|
||||||
|
key: _formKey,
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
height: 80,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'您好,欢迎登录',
|
||||||
|
style: TextStyle(fontSize: 28, fontWeight: FontWeight.w800),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 20,
|
||||||
|
),
|
||||||
|
TextFormField(
|
||||||
|
controller: _userName,
|
||||||
|
validator: (value) {
|
||||||
|
return value!.trim().isEmpty ? '请输入账号' : null;
|
||||||
|
},
|
||||||
|
decoration: InputDecoration(
|
||||||
|
labelText: "账号",
|
||||||
|
labelStyle: TextStyle(color: Color.fromRGBO(21, 185, 208, 1)),
|
||||||
|
enabledBorder: UnderlineInputBorder(
|
||||||
|
borderSide:
|
||||||
|
BorderSide(color: Color.fromRGBO(187, 187, 187, 1)),
|
||||||
|
),
|
||||||
|
focusedBorder: UnderlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: Color.fromRGBO(21, 185, 208, 1),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
style: TextStyle(fontSize: 16),
|
||||||
|
keyboardType: TextInputType.phone,
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 20,
|
||||||
|
),
|
||||||
|
TextFormField(
|
||||||
|
controller: _password,
|
||||||
|
validator: (value) {
|
||||||
|
return value!.trim().isEmpty ? '请输入密码' : null;
|
||||||
|
},
|
||||||
|
decoration: InputDecoration(
|
||||||
|
labelText: "密码",
|
||||||
|
labelStyle: TextStyle(color: Color.fromRGBO(21, 185, 208, 1)),
|
||||||
|
enabledBorder: UnderlineInputBorder(
|
||||||
|
borderSide:
|
||||||
|
BorderSide(color: Color.fromRGBO(187, 187, 187, 1)),
|
||||||
|
),
|
||||||
|
focusedBorder: UnderlineInputBorder(
|
||||||
|
borderSide: BorderSide(
|
||||||
|
color: Color.fromRGBO(21, 185, 208, 1),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
style: TextStyle(fontSize: 16),
|
||||||
|
obscureText: true,
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Checkbox(
|
||||||
|
value: checked,
|
||||||
|
activeColor: Color.fromRGBO(21, 185, 208, 1),
|
||||||
|
onChanged: (value) {
|
||||||
|
setState(() {
|
||||||
|
checked = !checked;
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
Text(
|
||||||
|
'同意',
|
||||||
|
style: TextStyle(fontSize: 14),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'《服务协议》',
|
||||||
|
style: TextStyle(fontSize: 14, color: Colors.blue),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
'和',
|
||||||
|
style: TextStyle(fontSize: 14),
|
||||||
|
),
|
||||||
|
Text('《隐私政策》',
|
||||||
|
style: TextStyle(fontSize: 14, color: Colors.blue)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 50,
|
||||||
|
),
|
||||||
|
ElevatedButton(
|
||||||
|
child: Text(
|
||||||
|
'登录',
|
||||||
|
style: TextStyle(fontSize: 16.0, color: Colors.white),
|
||||||
|
),
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
primary: Color.fromRGBO(21, 185, 208, 1),
|
||||||
|
minimumSize: Size(MediaQuery.of(context).size.width, 50),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(30)),
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
if (_formKey.currentState!.validate()) {
|
||||||
|
print('表单验证通过!');
|
||||||
|
if (!checked) {
|
||||||
|
print('请勾选服务协议和隐私政策');
|
||||||
|
} else {
|
||||||
|
dioHttp().dio.post('chat/api/auth/login', data: {
|
||||||
|
"username": _userName.text,
|
||||||
|
"password": _password.text,
|
||||||
|
}).then((res) {
|
||||||
|
print(res);
|
||||||
|
});
|
||||||
|
|
||||||
|
// print('请求登录接口业务逻辑');
|
||||||
|
|
||||||
|
// showToast("请求登录接口业务逻辑");
|
||||||
|
|
||||||
|
// showLoading(context, '加载中...');
|
||||||
|
// Future.delayed(Duration(seconds: 3), () {
|
||||||
|
// Navigator.of(context).pop();
|
||||||
|
// });
|
||||||
|
|
||||||
|
// showConfirmDialog(context, '确认xxxxxxx吗?', () {
|
||||||
|
// print('xxxxxxx');
|
||||||
|
// });
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -28,7 +28,7 @@ class PalRoomPage extends StatefulWidget {
|
||||||
|
|
||||||
class _PalRoomPageState extends State<PalRoomPage> {
|
class _PalRoomPageState extends State<PalRoomPage> {
|
||||||
final _users = <int>[]; // 用户id数组
|
final _users = <int>[]; // 用户id数组
|
||||||
final _infoStrings = <String>[]; // 状态文字信息列表
|
final _infoStrings = []; // 状态文字信息列表
|
||||||
bool viewPanel = true; // 是否显示状态文字信息列表
|
bool viewPanel = true; // 是否显示状态文字信息列表
|
||||||
bool muted = false; // 是否开麦
|
bool muted = false; // 是否开麦
|
||||||
bool volume = true; // 音量
|
bool volume = true; // 音量
|
||||||
|
|
@ -49,14 +49,17 @@ class _PalRoomPageState extends State<PalRoomPage> {
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_infoStrings.insert(
|
_infoStrings.insert(0, {
|
||||||
0, '最新插入的item-${widget.userName}-${widget.channelName}-${widget.role}');
|
'type': 'system',
|
||||||
|
'content': '信息-${widget.userName}-${widget.channelName}-${widget.role}'
|
||||||
|
});
|
||||||
|
|
||||||
|
initialize();
|
||||||
|
|
||||||
if (widget.role == ClientRole.Broadcaster) {
|
if (widget.role == ClientRole.Broadcaster) {
|
||||||
// 判断若是主播,进入就初始化引擎并连接上麦
|
_infoStrings.insert(0, {'type': 'system', 'content': '您身份为主播,已经上麦状态'});
|
||||||
initialize();
|
|
||||||
_infoStrings.insert(0, '您身份为主播,已经上麦状态');
|
|
||||||
} else if (widget.role == ClientRole.Audience) {
|
} else if (widget.role == ClientRole.Audience) {
|
||||||
_infoStrings.insert(0, '您身份为观众,点击麦克风图标上麦'); // 判断若非主播,进入提示连麦
|
_infoStrings.insert(0, {'type': 'system', 'content': '您身份为观众,点击麦克风图标上麦'});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -72,8 +75,11 @@ class _PalRoomPageState extends State<PalRoomPage> {
|
||||||
// 判断appid是否存在
|
// 判断appid是否存在
|
||||||
if (APP_ID.isEmpty) {
|
if (APP_ID.isEmpty) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_infoStrings.insert(0, 'APP ID缺失,请在settings.dart中提供您的APP ID');
|
_infoStrings.insert(0, {
|
||||||
_infoStrings.insert(0, 'Agora引擎没有启动');
|
'type': 'system',
|
||||||
|
'content': 'APP ID缺失,请在settings.dart中提供您的APP ID'
|
||||||
|
});
|
||||||
|
_infoStrings.insert(0, {'type': 'system', 'content': 'Agora引擎没有启动'});
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -85,11 +91,13 @@ class _PalRoomPageState extends State<PalRoomPage> {
|
||||||
await _engine.setAudioProfile(AudioProfile.SpeechStandard,
|
await _engine.setAudioProfile(AudioProfile.SpeechStandard,
|
||||||
AudioScenario.ChatRoomEntertainment); // 设置音频编码属性和音频场景
|
AudioScenario.ChatRoomEntertainment); // 设置音频编码属性和音频场景
|
||||||
await _engine.setChannelProfile(ChannelProfile.LiveBroadcasting);
|
await _engine.setChannelProfile(ChannelProfile.LiveBroadcasting);
|
||||||
await _engine.setClientRole(widget.role!);
|
|
||||||
|
if (widget.role == ClientRole.Broadcaster) {
|
||||||
|
await _engine.setClientRole(ClientRole.Broadcaster);
|
||||||
|
}
|
||||||
|
_engine.joinChannel(Token, widget.channelName, null, 0); // 加入频道
|
||||||
|
|
||||||
_addAgoraEventHandlers(); // 调用状态文字信息列表方法
|
_addAgoraEventHandlers(); // 调用状态文字信息列表方法
|
||||||
|
|
||||||
_engine.joinChannel(Token, widget.channelName, null, 0); // 加入频道
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _addAgoraEventHandlers() {
|
void _addAgoraEventHandlers() {
|
||||||
|
|
@ -98,20 +106,20 @@ class _PalRoomPageState extends State<PalRoomPage> {
|
||||||
// 错误
|
// 错误
|
||||||
setState(() {
|
setState(() {
|
||||||
final info = '错误 $code';
|
final info = '错误 $code';
|
||||||
_infoStrings.insert(0, info);
|
_infoStrings.insert(0, {'type': 'system', 'content': info});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
joinChannelSuccess: (channel, uid, elapsed) {
|
joinChannelSuccess: (channel, uid, elapsed) {
|
||||||
// 加入频道成功
|
// 加入频道成功
|
||||||
setState(() {
|
setState(() {
|
||||||
final info = '加入频道: $channel, uid: $uid';
|
final info = '加入频道: $channel, uid: $uid';
|
||||||
_infoStrings.insert(0, info);
|
_infoStrings.insert(0, {'type': 'system', 'content': info});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
leaveChannel: (stats) {
|
leaveChannel: (stats) {
|
||||||
// 离开频道
|
// 离开频道
|
||||||
setState(() {
|
setState(() {
|
||||||
_infoStrings.insert(0, '离开频道');
|
_infoStrings.insert(0, {'type': 'system', 'content': '离开频道'});
|
||||||
_users.clear();
|
_users.clear();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
@ -119,7 +127,7 @@ class _PalRoomPageState extends State<PalRoomPage> {
|
||||||
// 用户加入
|
// 用户加入
|
||||||
setState(() {
|
setState(() {
|
||||||
final info = '用户加入: $uid';
|
final info = '用户加入: $uid';
|
||||||
_infoStrings.insert(0, info);
|
_infoStrings.insert(0, {'type': 'system', 'content': info});
|
||||||
_users.add(uid);
|
_users.add(uid);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
@ -127,7 +135,7 @@ class _PalRoomPageState extends State<PalRoomPage> {
|
||||||
// 用户离线
|
// 用户离线
|
||||||
setState(() {
|
setState(() {
|
||||||
final info = '用户离线: $uid , reason: $reason';
|
final info = '用户离线: $uid , reason: $reason';
|
||||||
_infoStrings.insert(0, info);
|
_infoStrings.insert(0, {'type': 'system', 'content': info});
|
||||||
_users.remove(uid);
|
_users.remove(uid);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
@ -135,15 +143,95 @@ class _PalRoomPageState extends State<PalRoomPage> {
|
||||||
// 远程视频第一帧
|
// 远程视频第一帧
|
||||||
setState(() {
|
setState(() {
|
||||||
final info = 'First Remote Video Frame: $uid';
|
final info = 'First Remote Video Frame: $uid';
|
||||||
_infoStrings.insert(0, info);
|
_infoStrings.insert(0, {'type': 'system', 'content': info});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
clientRoleChanged: (oldRole, newRole) {
|
||||||
|
// 直播场景下用户角色切换成功回调
|
||||||
|
setState(() {
|
||||||
|
final info = '用户旧身份$oldRole,用户新身份$newRole';
|
||||||
|
_infoStrings.insert(0, {'type': 'system', 'content': info});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 头部
|
||||||
Widget _head() {
|
Widget _head() {
|
||||||
|
// 底部弹框组件
|
||||||
|
_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';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 申请连麦需要改变身份为主播!
|
||||||
|
_engine.setClientRole(ClientRole.Broadcaster);
|
||||||
|
|
||||||
|
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.setClientRole(ClientRole.Audience);
|
||||||
|
|
||||||
|
Navigator.pop(context);
|
||||||
|
print("下麦:${list[index]['content']}");
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ListTile(
|
||||||
|
title: Text(
|
||||||
|
"取消",
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
onTap: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
child: Column(
|
child: ListView(
|
||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
padding: EdgeInsets.fromLTRB(0, 27, 0, 5),
|
padding: EdgeInsets.fromLTRB(0, 27, 0, 5),
|
||||||
|
|
@ -187,9 +275,9 @@ class _PalRoomPageState extends State<PalRoomPage> {
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
crossAxisSpacing: 40,
|
crossAxisSpacing: 40,
|
||||||
mainAxisSpacing: 35,
|
mainAxisSpacing: 30,
|
||||||
crossAxisCount: 4,
|
crossAxisCount: 4,
|
||||||
childAspectRatio: 1 / 1.2,
|
childAspectRatio: 1 / 1.25,
|
||||||
),
|
),
|
||||||
itemCount: list.length,
|
itemCount: list.length,
|
||||||
itemBuilder: (BuildContext context, int index) {
|
itemBuilder: (BuildContext context, int index) {
|
||||||
|
|
@ -200,7 +288,8 @@ class _PalRoomPageState extends State<PalRoomPage> {
|
||||||
// 观众身份的时候点击上麦克图标
|
// 观众身份的时候点击上麦克图标
|
||||||
_modelBottomSheet(index); // 调用底部弹框方法
|
_modelBottomSheet(index); // 调用底部弹框方法
|
||||||
} else {
|
} else {
|
||||||
_infoStrings.insert(0, '您身份为主播,已经上麦状态');
|
_infoStrings.insert(
|
||||||
|
0, {'type': 'system', 'content': '您身份为主播,已经上麦状态'});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
@ -239,19 +328,45 @@ class _PalRoomPageState extends State<PalRoomPage> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 消息列表
|
||||||
Widget _planel() {
|
Widget _planel() {
|
||||||
|
_filtering(type, content) {
|
||||||
|
switch (type) {
|
||||||
|
case 'system':
|
||||||
|
return Container(
|
||||||
|
child: Text(
|
||||||
|
'系统公告:$content',
|
||||||
|
style: TextStyle(color: Color.fromRGBO(155, 154, 170, 1)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
case 'speak':
|
||||||
|
return Container(
|
||||||
|
child: Text(
|
||||||
|
'聊天消息:$content',
|
||||||
|
style: TextStyle(color: Color.fromRGBO(155, 154, 170, 1)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
case 'gift':
|
||||||
|
return Container(
|
||||||
|
child: Text(
|
||||||
|
'礼物消息:$content',
|
||||||
|
style: TextStyle(color: Color.fromRGBO(155, 154, 170, 1)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return Visibility(
|
return Visibility(
|
||||||
visible: viewPanel,
|
visible: viewPanel,
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: EdgeInsets.symmetric(vertical: 48),
|
padding: EdgeInsets.symmetric(vertical: 60),
|
||||||
alignment: Alignment.bottomCenter,
|
alignment: Alignment.bottomCenter,
|
||||||
child: FractionallySizedBox(
|
child: FractionallySizedBox(
|
||||||
heightFactor: 0.5,
|
heightFactor: 0.5,
|
||||||
child: Container(
|
child: Container(
|
||||||
// decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
// color: Colors.black,
|
color: Colors.black,
|
||||||
// ),
|
),
|
||||||
// padding: EdgeInsets.symmetric(vertical: 48),
|
|
||||||
child: ListView.builder(
|
child: ListView.builder(
|
||||||
reverse: true,
|
reverse: true,
|
||||||
itemCount: _infoStrings.length,
|
itemCount: _infoStrings.length,
|
||||||
|
|
@ -274,12 +389,8 @@ class _PalRoomPageState extends State<PalRoomPage> {
|
||||||
color: Color.fromRGBO(50, 51, 71, 1),
|
color: Color.fromRGBO(50, 51, 71, 1),
|
||||||
borderRadius: BorderRadius.circular(5),
|
borderRadius: BorderRadius.circular(5),
|
||||||
),
|
),
|
||||||
child: Text(
|
child: _filtering(_infoStrings[index]['type'],
|
||||||
_infoStrings[index],
|
_infoStrings[index]['content']),
|
||||||
style: TextStyle(
|
|
||||||
color: Color.fromRGBO(155, 154, 170, 1),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
@ -293,6 +404,7 @@ class _PalRoomPageState extends State<PalRoomPage> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 底部输入框控制台
|
||||||
Widget _footer() {
|
Widget _footer() {
|
||||||
final _input = TextEditingController();
|
final _input = TextEditingController();
|
||||||
return Container(
|
return Container(
|
||||||
|
|
@ -431,12 +543,14 @@ class _PalRoomPageState extends State<PalRoomPage> {
|
||||||
),
|
),
|
||||||
SizedBox(width: 5),
|
SizedBox(width: 5),
|
||||||
Container(
|
Container(
|
||||||
padding: EdgeInsets.fromLTRB(6, 1, 6, 1),
|
padding: EdgeInsets.fromLTRB(6, 2, 6, 2),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.all(Radius.circular(2)),
|
borderRadius: BorderRadius.all(Radius.circular(2)),
|
||||||
color: Color.fromRGBO(47, 47, 59, 1),
|
color: Color.fromRGBO(47, 47, 59, 1),
|
||||||
),
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'在线:121',
|
'在线:121',
|
||||||
|
|
@ -489,72 +603,4 @@ class _PalRoomPageState extends State<PalRoomPage> {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 底部弹框方法
|
|
||||||
_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);
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ class _PartyPageState extends State<PartyPage> {
|
||||||
actions: [
|
actions: [
|
||||||
IconButton(
|
IconButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
print('create图标被点击');
|
Navigator.pushNamed(context, 'CreateRoom');
|
||||||
},
|
},
|
||||||
icon: Image.asset(
|
icon: Image.asset(
|
||||||
'images/party/create.png',
|
'images/party/create.png',
|
||||||
|
|
|
||||||
35
pubspec.lock
35
pubspec.lock
|
|
@ -57,6 +57,13 @@ packages:
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.5"
|
version: "1.0.5"
|
||||||
|
dio:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: dio
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "4.0.6"
|
||||||
fake_async:
|
fake_async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -86,6 +93,20 @@ packages:
|
||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
|
fluttertoast:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: fluttertoast
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "7.1.8"
|
||||||
|
http_parser:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: http_parser
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "4.0.1"
|
||||||
js:
|
js:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
@ -203,6 +224,20 @@ packages:
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.4.9"
|
version: "0.4.9"
|
||||||
|
typed_data:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: typed_data
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "1.3.1"
|
||||||
|
validators:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: validators
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.0"
|
||||||
vector_math:
|
vector_math:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,9 @@ dependencies:
|
||||||
cupertino_icons: ^1.0.2
|
cupertino_icons: ^1.0.2
|
||||||
agora_rtc_engine: ^5.2.0
|
agora_rtc_engine: ^5.2.0
|
||||||
permission_handler: ^8.3.0
|
permission_handler: ^8.3.0
|
||||||
|
validators: ^3.0.0
|
||||||
|
dio: ^4.0.6
|
||||||
|
fluttertoast: ^7.1.6
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|
@ -107,6 +110,8 @@ flutter:
|
||||||
- images/palRoom/whiteLeft.png
|
- images/palRoom/whiteLeft.png
|
||||||
- images/palRoom/whiteRight.png
|
- images/palRoom/whiteRight.png
|
||||||
|
|
||||||
|
- images/createRoom/refresh.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
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue