Skip to content

Instantly share code, notes, and snippets.

@mulieriq
Last active August 21, 2020 17:00
Show Gist options
  • Save mulieriq/e1daae4f9f76572a539591e7622b70b2 to your computer and use it in GitHub Desktop.
Save mulieriq/e1daae4f9f76572a539591e7622b70b2 to your computer and use it in GitHub Desktop.
create call
class VideoCallPerosnalScreen extends StatefulWidget {
/// non-modifiable channel name of the page
final String channelName;
final String callerid;
final String receiverid;
/// Creates a call page with given channel name.
const VideoCallPerosnalScreen(
{Key key, this.callerid, this.receiverid, this.channelName})
: super(key: key);
@override
_VideoCallPerosnalScreenState createState() {
return new _VideoCallPerosnalScreenState();
}
}
class _VideoCallPerosnalScreenState extends State<VideoCallPerosnalScreen> {
static final _sessions = List<VideoSession>();
final _infoStrings = <String>[];
bool muted = false;
String username = " Muli";
updateChatroomNumber(number) {
return Firestore.instance.collection("videocon").document().setData({
widget.channelName: {"number": number}
});
}
updateDestroyChatRoom() {
return Firestore.instance.collection("videocon").document().delete();
}
@override
void dispose() {
// clean up native views & destroy sdk
_sessions.forEach((session) {
AgoraRtcEngine.removeNativeView(session.viewId);
});
_sessions.clear();
AgoraRtcEngine.leaveChannel();
super.dispose();
}
@override
void initState() {
Wakelock.enable();
super.initState();
// initialize agora sdk
initialize();
}
void initialize() {
if (APP_ID.isEmpty) {
setState(() {
_infoStrings
.add("APP_ID missing, please provide your APP_ID in settings.dart");
_infoStrings.add("Video Engine is not starting");
});
return;
}
_initAgoraRtcEngine();
_addAgoraEventHandlers();
// use _addRenderView everytime a native video view is needed
_addRenderView(0, (viewId) {
AgoraRtcEngine.setupLocalVideo(viewId, VideoRenderMode.Hidden);
AgoraRtcEngine.startPreview();
// state can access widget directly
AgoraRtcEngine.joinChannel(null, widget.channelName, null, 0);
});
}
/// Create agora sdk instance and initialze
Future<void> _initAgoraRtcEngine() async {
AgoraRtcEngine.create(APP_ID);
AgoraRtcEngine.enableVideo();
}
/// Add agora event handlers
void _addAgoraEventHandlers() {
AgoraRtcEngine.onError = (dynamic code) {
setState(() {
String info = 'onError: ' + code.toString();
_infoStrings.add(info);
});
};
AgoraRtcEngine.onJoinChannelSuccess =
(String channel, int uid, int elapsed) {
setState(() {
String info = 'onJoinChannel: ' + channel + ', uid: ' + uid.toString();
_infoStrings.add(info);
});
};
AgoraRtcEngine.onLeaveChannel = () {
setState(() {
_infoStrings.add('onLeaveChannel');
});
};
AgoraRtcEngine.onUserJoined = (int uid, int elapsed) {
setState(() {
String info = 'userJoined: ' + uid.toString();
_infoStrings.add(info);
_addRenderView(uid, (viewId) {
AgoraRtcEngine.setupRemoteVideo(viewId, VideoRenderMode.Hidden, uid);
});
});
};
AgoraRtcEngine.onUserOffline = (int uid, int reason) {
Firestore.instance
.collection("personalvideocalls")
.document(widget.callerid)
.delete()
.then((r) {
Firestore.instance
.collection("personalvideocalls")
.document(widget.receiverid)
.delete();
});
setState(() {
String info = 'userOffline: ' + uid.toString();
_infoStrings.add(info);
_removeRenderView(uid);
});
};
AgoraRtcEngine.onFirstRemoteVideoFrame =
(int uid, int width, int height, int elapsed) {
setState(() {
String info = 'firstRemoteVideo: ' +
uid.toString() +
' ' +
width.toString() +
'x' +
height.toString();
_infoStrings.add(info);
});
};
}
/// Create a native view and add a new video session object
/// The native viewId can be used to set up local/remote view
void _addRenderView(int uid, Function(int viewId) finished) {
Widget view = AgoraRtcEngine.createNativeView((viewId) {
setState(() {
_getVideoSession(uid).viewId = viewId;
if (finished != null) {
finished(viewId);
}
});
});
VideoSession session = VideoSession(uid, view);
_sessions.add(session);
}
/// Remove a native view and remove an existing video session object
void _removeRenderView(int uid) {
VideoSession session = _getVideoSession(uid);
if (session != null) {
_sessions.remove(session);
}
AgoraRtcEngine.removeNativeView(session.viewId);
}
/// Helper function to filter video session with uid
VideoSession _getVideoSession(int uid) {
return _sessions.firstWhere((session) {
return session.uid == uid;
});
}
/// Helper function to get list of native views
List<Widget> _getRenderViews() {
return _sessions.map((session) => session.view).toList();
}
/// Video view wrapper
Widget _videoView(
view,
) {
return Expanded(child: Container(child: view));
}
Widget _tvideoView(view, view2) {
return Expanded(
child: Container(
child: Stack(
children: <Widget>[
view,
Positioned(
right: MediaQuery.of(context).size.width * 0.05,
bottom: MediaQuery.of(context).size.height * 0.12,
child: Row(
children: <Widget>[
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(50)),
),
height: MediaQuery.of(context).size.width * 0.5,
width: MediaQuery.of(context).size.width * 0.4,
child: Card(
child: view2,
clipBehavior: Clip.hardEdge,
)
//color: Colors.red,
)
],
))
],
)));
}
Widget _tvideoView2(view, view2, view3) {
return Expanded(
child: Container(
child: Stack(
children: <Widget>[
view,
Positioned(
right: MediaQuery.of(context).size.width * 0.05,
bottom: MediaQuery.of(context).size.height * 0.12,
child: Row(
children: <Widget>[
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(50)),
),
height: MediaQuery.of(context).size.width * 0.5,
width: MediaQuery.of(context).size.width * 0.4,
child: Card(
child: view2,
clipBehavior: Clip.hardEdge,
)
//color: Colors.red,
),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(50)),
),
height: MediaQuery.of(context).size.width * 0.5,
width: MediaQuery.of(context).size.width * 0.4,
child: Card(
child: view3,
clipBehavior: Clip.hardEdge,
)
//color: Colors.red,
)
],
))
],
)));
}
/// Video view row wrapper
Widget _expandedVideoRow(List<Widget> views) {
List<Widget> wrappedViews = views
.map((Widget view) => _videoView(
view,
))
.toList();
return Expanded(child: Row(children: wrappedViews));
}
/// Video layout wrapper
Widget _viewRows() {
List<Widget> views = _getRenderViews();
print(views);
print(views.length);
switch (views.length) {
case 1:
return Container(
child: Column(
children: <Widget>[
// _tviews(views[0])]
_videoView(views[0])
],
));
case 2:
return Container(
child: Column(
children: <Widget>[_tvideoView(views[1], views[0])],
));
case 3:
return Container(
child: Column(
children: <Widget>[
_tvideoView(
//view[0]
views[2], //index 1 is mine
views[1], //index 2 callers
)
],
));
case 4:
updateChatroomNumber(4);
return Container(
child: Column(
children: <Widget>[
_expandedVideoRow(views.sublist(0, 2)),
_expandedVideoRow(views.sublist(2, 4))
],
));
case 5:
updateChatroomNumber(5);
return Container(
child: Column(
children: <Widget>[
_expandedVideoRow(views.sublist(0, 2)),
_expandedVideoRow(views.sublist(2, 5))
],
));
case 6:
updateChatroomNumber(6);
return Container(
child: Column(
children: <Widget>[
_expandedVideoRow(views.sublist(0, 2)),
_expandedVideoRow(views.sublist(2, 6))
],
));
case 7:
updateChatroomNumber(7);
return Container(
child: Column(
children: <Widget>[
_expandedVideoRow(views.sublist(0, 2)),
_expandedVideoRow(views.sublist(2, 7))
],
));
case 8:
updateChatroomNumber(8);
return Container(
child: Column(
children: <Widget>[
_expandedVideoRow(views.sublist(0, 2)),
_expandedVideoRow(views.sublist(2, 8))
],
));
case 9:
updateChatroomNumber(9);
return Container(
child: Column(
children: <Widget>[
_expandedVideoRow(views.sublist(0, 2)),
_expandedVideoRow(views.sublist(2, 9))
],
));
case 10:
updateChatroomNumber(10);
return Container(
child: Column(
children: <Widget>[
_expandedVideoRow(views.sublist(0, 2)),
_expandedVideoRow(views.sublist(2, 10))
],
));
default:
}
return Container();
}
/// Toolbar layout
Widget _toolbar() {
return Container(
alignment: Alignment.bottomCenter,
padding: EdgeInsets.symmetric(vertical: 48),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RawMaterialButton(
onPressed: () => _onToggleMute(),
child: new Icon(
muted ? Icons.mic : Icons.mic_off,
color: muted ? Colors.white : Colors.blueAccent,
size: 20.0,
),
shape: new CircleBorder(),
elevation: 2.0,
fillColor: muted ? Colors.blueAccent : Colors.white,
padding: const EdgeInsets.all(12.0),
),
RawMaterialButton(
onPressed: () {
return Firestore.instance
.collection("personalvideocalls")
.document(widget.callerid)
.delete()
.then((r) {
Firestore.instance
.collection("personalvideocalls")
.document(widget.receiverid)
.delete();
}).then((r) {
Navigator.pop(context);
});
},
child: new Icon(
Icons.call_end,
color: Colors.white,
size: 35.0,
),
shape: new CircleBorder(),
elevation: 2.0,
fillColor: Colors.redAccent,
padding: const EdgeInsets.all(15.0),
),
RawMaterialButton(
onPressed: () => _onSwitchCamera(),
child: new Icon(
Icons.switch_camera,
color: Colors.blueAccent,
size: 20.0,
),
shape: new CircleBorder(),
elevation: 2.0,
fillColor: Colors.white,
padding: const EdgeInsets.all(12.0),
)
],
),
);
}
/// Info panel to show logs
Widget _panel() {
return Container(
padding: EdgeInsets.symmetric(vertical: 48),
alignment: Alignment.bottomCenter,
child: FractionallySizedBox(
heightFactor: 0.5,
child: Container(
padding: EdgeInsets.symmetric(vertical: 48),
child: ListView.builder(
reverse: true,
itemCount: _infoStrings.length,
itemBuilder: (BuildContext context, int index) {
if (_infoStrings.length == 0) {
return null;
}
return Padding(
padding:
EdgeInsets.symmetric(vertical: 3, horizontal: 10),
child: Row(mainAxisSize: MainAxisSize.min, children: [
Flexible(
child: Container(
padding: EdgeInsets.symmetric(
vertical: 2, horizontal: 5),
decoration: BoxDecoration(
//color: Colors.yellowAccent,
borderRadius: BorderRadius.circular(5)),
child: Text(_infoStrings[index],
style:
TextStyle(color: Colors.blueGrey))))
]));
})),
));
}
void _onCallEnd(BuildContext context) {
dispose();
Navigator.pop(context);
//dispose();
}
void _onToggleMute() {
setState(() {
muted = !muted;
});
AgoraRtcEngine.muteLocalAudioStream(muted);
}
void _onSwitchCamera() {
AgoraRtcEngine.switchCamera();
}
@override
Widget build(BuildContext context) {
return Scaffold(
// appBar: AppBar(
// title: Text('Conference Room'),
// ),
backgroundColor: Colors.black,
body: Center(
child: Stack(
children: <Widget>[_viewRows(), /* _panel(),*/ _toolbar()],
)));
}
}
class VoiceCallPage extends StatefulWidget {
final String callid;
final String receiverid;
final String callerid;
final String callername;
final String callerphoto;
final String channelName;
VoiceCallPage(
{this.callerid,
this.callername,
this.channelName,
this.callid,
this.receiverid,
this.callerphoto});
@override
_VoiceCallPageState createState() => _VoiceCallPageState();
}
class _VoiceCallPageState extends State<VoiceCallPage> {
String getTimerTime(int start) {
int minutes = (start ~/ 60);
String sMinute = '';
if (minutes.toString().length == 1) {
sMinute = '0' + minutes.toString();
} else
sMinute = minutes.toString();
int seconds = (start % 60);
String sSeconds = '';
if (seconds.toString().length == 1) {
sSeconds = '0' + seconds.toString();
} else
sSeconds = seconds.toString();
return sMinute + ':' + sSeconds;
}
@override
void initState() {
super.initState();
FlutterRingtonePlayer.playRingtone();
}
@override
void dispose() {
super.dispose();
FlutterRingtonePlayer.stop();
}
handleCameraAndMic() async {
await PermissionHandler().requestPermissions(
[PermissionGroup.camera, PermissionGroup.microphone]);
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xff172630),
body: SafeArea(
child: Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
color: Color(0xff172630),
),
padding: EdgeInsets.all(50.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(
height: MediaQuery.of(context).size.height * 0.01,
),
Text(
'Incoming Video Call',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.w300,
fontSize: 15),
),
SizedBox(
height: MediaQuery.of(context).size.height * 0.02,
),
Text(
'${widget.callername}',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.w900,
fontSize: 20),
),
SizedBox(
height: MediaQuery.of(context).size.height * 0.03,
),
SizedBox(
height: 20.0,
),
CircleAvatar(
radius: MediaQuery.of(context).size.width * 0.25,
// backgroundImage:
child: CachedNetworkImage(
imageBuilder: (context, imageProvider) => Container(
width: MediaQuery.of(context).size.width * 0.5,
height: MediaQuery.of(context).size.width * 0.5,
decoration: BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
image: imageProvider, fit: BoxFit.cover),
),
),
// fit: BoxFit.cover,
fadeInCurve: Curves.easeInOutCirc,
fadeInDuration: Duration(seconds: 2),
fadeOutCurve: Curves.easeInOutCirc,
fadeOutDuration: Duration(seconds: 2),
imageUrl: widget.callerphoto == null
? "lib/assets/mcculogo.png"
: widget.callerphoto,
useOldImageOnUrlChange: true,
placeholder: (context, url) => Icon(Icons.person),
errorWidget: (context, url, error) => Image.asset(
"lib/assets/mcculogo.png",
fit: BoxFit.cover,
)),
// NetworkImage(
// snapshot.data.documents[i]
// .data['userImage']),
),
SizedBox(
height: MediaQuery.of(context).size.height * 0.15,
),
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
FunctionalButton(
title: 'Receive',
color: Colors.green,
icon: Icons.videocam,
onPressed: () {
FlutterRingtonePlayer.stop();
Firestore.instance
.collection("personalvideocalls")
.document(widget.callerid)
.updateData({"received_by_recepient": true}).then(
(r) {
handleCameraAndMic();
Navigator.push(
context,
CupertinoPageRoute(
builder: (context) => VideoCallPerosnalScreen(
callerid: widget.callerid,
receiverid: widget.receiverid,
channelName: widget.channelName,
)));
});
///place instance to callers db
// Firestore.instance
// .collection("personalvideocalls")
// .document(widget.callerid)
// .collection(widget.receiverid)
// .document(widget.callid)
// .updateData({
// "received_by_recepient": true,
// } //)
// ).then((r) {
// Firestore.instance
// .collection("personalvideocalls")
// .document(widget.receiverid)
// .collection(widget.callerid)
// .document(widget.callid)
// .updateData(
// {"received_by_recepient": true},
// ).then((r) async {
// // update input validation
// // await for camera and mic permissions before pushing video page
// //await _handleCameraAndMic();
// // push video page with given channel name
// Navigator.push(
// context,
// CupertinoPageRoute(
// builder: (context) => new CallPage(
// channelName: widget.channelName,
// )));
// });
// });
},
),
FunctionalButton(
title: 'End',
color: Colors.red,
icon: Icons.videocam_off,
onPressed: () {
///place instance to callers db
Firestore.instance
.collection("personalvideocalls")
.document(widget.receiverid)
.delete();
Firestore.instance
.collection("personalvideocalls")
.document(widget.callerid)
.delete();
FlutterRingtonePlayer.stop();
// Navigator.pop(context);
},
),
],
),
// FloatingActionButton(
// onPressed: () {
// Navigator.pop(context);
// },
// elevation: 50.0,
// shape: CircleBorder(side: BorderSide(color: Colors.red)),
// mini: false,
// child: Icon(
// Icons.call_end,
// color: Colors.red,
// ),
// backgroundColor: Colors.red[100],
// ),
SizedBox(
height: MediaQuery.of(context).size.height * 0.02,
),
// Text(
// "Waiting Time : ${_timmer}",
// style: TextStyle(
// color: Colors.red,
// fontWeight: FontWeight.w300,
// fontSize: 15),
// ),
],
),
),
),
);
}
}
class FunctionalButton extends StatefulWidget {
final title;
final icon;
final color;
final Function() onPressed;
const FunctionalButton(
{Key key, this.title, this.color, this.icon, this.onPressed})
: super(key: key);
@override
_FunctionalButtonState createState() => _FunctionalButtonState();
}
class _FunctionalButtonState extends State<FunctionalButton> {
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
RawMaterialButton(
onPressed: widget.onPressed,
splashColor: Colors.red,
fillColor: Colors.white,
elevation: 10.0,
shape: CircleBorder(),
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Icon(
widget.icon,
size: 30.0,
color: widget.color,
),
),
),
Container(
margin: EdgeInsets.symmetric(vertical: 10.0, horizontal: 2.0),
child: Text(
widget.title,
style: TextStyle(fontSize: 15.0, color: Colors.white),
),
)
],
);
}
}
var channelid = generateChannelid() {
return Random().nextInt(1000).toString();
}
placeVideoCall() {
///place instance to callers db
Firestore.instance
.collection("personalvideocalls")
.document(widget.senderId)
// .collection(widget.receiverid)
.setData({
"callerId": null,
"callerDeleteId": widget.senderId,
"callerName": widget.senderName,
"callerImage": widget.senderImage,
"iscaller": true, // used to identify who s placing the call
"callingChannel": channelid,
"receiverId": widget.receiverid,
"receiverName": widget.receverName,
"receiverImage": widget.receiverImage,
"received_by_recepient":
false, //used to determine if the receiver picked the call
"outgoing": true, //haitumiki sawa ..to show he made the call
"time": DateTime.now().millisecondsSinceEpoch.toString(),
}).then((r) {
Firestore.instance
.collection("personalvideocalls")
.document(widget.receiverid)
//.collection(widget.senderId)
.setData({
"callerId": widget.senderId,
"callerDeleteId": widget.senderId,
"callerName": widget.senderName,
"callerImage": widget.senderImage,
"iscaller": false,
"callingChannel": channelid,
"receiverId": widget.receiverid,
"receiverName": widget.receverName,
"receiverImage": widget.receiverImage,
"received_by_recepient": false, //kwa receiver this haitumiki
"incoming": true,
"time": DateTime.now().millisecondsSinceEpoch.toString(),
}).then((r) {
});
});
}
class OutgoingVideoCall extends StatefulWidget {
final String recipientid;
final String recipientname;
final String recipientphoto;
final String channelName;
OutgoingVideoCall(
{this.recipientid,
this.recipientname,
this.channelName,
this.recipientphoto});
@override
_OutgoingVideoCallState createState() => _OutgoingVideoCallState();
}
class _OutgoingVideoCallState extends State<OutgoingVideoCall> {
Timer _timmerInstance;
int _start = 0;
String _timmer = '';
void startTimmer() {
var oneSec = Duration(seconds: 1);
_timmerInstance = Timer.periodic(
oneSec,
(Timer timer) => setState(() {
if (_start < 0) {
_timmerInstance.cancel();
} else {
_start = _start + 1;
_timmer = getTimerTime(_start);
}
}));
}
String getTimerTime(int start) {
int minutes = (start ~/ 60);
String sMinute = '';
if (minutes.toString().length == 1) {
sMinute = '0' + minutes.toString();
} else
sMinute = minutes.toString();
int seconds = (start % 60);
String sSeconds = '';
if (seconds.toString().length == 1) {
sSeconds = '0' + seconds.toString();
} else
sSeconds = seconds.toString();
return sMinute + ':' + sSeconds;
}
@override
void initState() {
super.initState();
startTimmer();
// Ringtone.play();
}
@override
void dispose() {
super.dispose();
_timmerInstance.cancel();
FlutterRingtonePlayer.stop();
}
@override
Widget build(BuildContext context) {
return ScopedModelDescendant<Scoped>(
builder: (BuildContext context, Widget child, Scoped model) {
return ReceiverLayout(
scaffold: Scaffold(
backgroundColor: Color(0xff172630),
body: SafeArea(
child: Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
color: Color(0xff172630),
),
padding: EdgeInsets.all(50.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(
height: MediaQuery.of(context).size.height * 0.01,
),
Text(
'Outgoing Video Call',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.w300,
fontSize: 15),
),
SizedBox(
height: MediaQuery.of(context).size.height * 0.02,
),
Text(
'${widget.recipientname}',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.w900,
fontSize: 20),
),
SizedBox(
height: MediaQuery.of(context).size.height * 0.03,
),
SizedBox(
height: 20.0,
),
CircleAvatar(
radius: MediaQuery.of(context).size.width * 0.25,
// backgroundImage:
child: CachedNetworkImage(
imageBuilder: (context, imageProvider) => Container(
width: MediaQuery.of(context).size.width * 0.5,
height: MediaQuery.of(context).size.width * 0.5,
decoration: BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
image: imageProvider, fit: BoxFit.cover),
),
),
// fit: BoxFit.cover,
fadeInCurve: Curves.easeInOutCirc,
fadeInDuration: Duration(seconds: 2),
fadeOutCurve: Curves.easeInOutCirc,
fadeOutDuration: Duration(seconds: 2),
imageUrl: widget.recipientphoto == null
? "lib/assets/mcculogo.png"
: widget.recipientphoto,
useOldImageOnUrlChange: true,
placeholder: (context, url) => Icon(Icons.person),
errorWidget: (context, url, error) => Image.asset(
"lib/assets/mcculogo.png",
fit: BoxFit.cover,
)),
),
SizedBox(
height: MediaQuery.of(context).size.height * 0.15,
),
FloatingActionButton(
onPressed: () {
Firestore.instance
.collection("personalvideocalls")
.document(model.userId)
.delete()
.then((r) {
Firestore.instance
.collection("personalvideocalls")
.document(widget.recipientid)
.delete();
});
FlutterRingtonePlayer.stop();
// Navigator.pop(context);
},
elevation: 50.0,
shape: CircleBorder(side: BorderSide(color: Colors.red)),
mini: false,
child: Icon(
Icons.call_end,
color: Colors.red,
),
backgroundColor: Colors.red[100],
),
SizedBox(
height: MediaQuery.of(context).size.height * 0.02,
),
],
),
),
),
),
);
});
}
}
class FunctionalButton extends StatefulWidget {
final title;
final icon;
final color;
final Function() onPressed;
const FunctionalButton(
{Key key, this.title, this.color, this.icon, this.onPressed})
: super(key: key);
@override
_FunctionalButtonState createState() => _FunctionalButtonState();
}
class _FunctionalButtonState extends State<FunctionalButton> {
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
RawMaterialButton(
onPressed: widget.onPressed,
splashColor: Colors.red,
fillColor: Colors.white,
elevation: 10.0,
shape: CircleBorder(),
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Icon(
widget.icon,
size: 30.0,
color: widget.color,
),
),
),
Container(
margin: EdgeInsets.symmetric(vertical: 10.0, horizontal: 2.0),
child: Text(
widget.title,
style: TextStyle(fontSize: 15.0, color: Colors.white),
),
)
],
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment