in_overlay_page.dart 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. import 'package:flutter/material.dart';
  2. import 'package:ijkplayer_example/i18n/i18n.dart';
  3. import 'package:flutter_ijkplayer/flutter_ijkplayer.dart';
  4. class InOverlayPage extends StatefulWidget {
  5. @override
  6. _InOverlayPageState createState() => _InOverlayPageState();
  7. }
  8. class _InOverlayPageState extends State<InOverlayPage> {
  9. IjkMediaController controller = IjkMediaController();
  10. OverlayEntry entry;
  11. @override
  12. void initState() {
  13. super.initState();
  14. controller.setDataSource(
  15. DataSource.network(
  16. "http://img.ksbbs.com/asset/Mon_1703/05cacb4e02f9d9e.mp4",
  17. ),
  18. autoPlay: true,
  19. );
  20. }
  21. @override
  22. void deactivate() {
  23. super.deactivate();
  24. entry?.remove();
  25. entry = null;
  26. }
  27. @override
  28. void dispose() {
  29. controller?.dispose();
  30. super.dispose();
  31. }
  32. @override
  33. Widget build(BuildContext context) {
  34. return Scaffold(
  35. appBar: AppBar(
  36. title: Text(currentI18n.overlayPageTitle),
  37. ),
  38. body: ListView(
  39. children: <Widget>[
  40. AspectRatio(
  41. child: IjkPlayer(
  42. mediaController: controller,
  43. ),
  44. aspectRatio: 1,
  45. ),
  46. FlatButton(
  47. child: Text("showInOverlay"),
  48. onPressed: showInOverlay,
  49. ),
  50. ],
  51. ),
  52. );
  53. }
  54. void showInOverlay() async {
  55. var info = await controller.getVideoInfo();
  56. OverlayEntry _entry;
  57. _entry = OverlayEntry(
  58. builder: (BuildContext context) {
  59. return OverlayWidget(
  60. controller: controller,
  61. initVideoInfo: info,
  62. onTapClose: () {
  63. _entry?.remove();
  64. },
  65. );
  66. },
  67. );
  68. Overlay.of(context).insert(_entry);
  69. }
  70. }
  71. class OverlayWidget extends StatefulWidget {
  72. final VideoInfo initVideoInfo;
  73. final IjkMediaController controller;
  74. final Function onTapClose;
  75. const OverlayWidget({
  76. Key key,
  77. this.initVideoInfo,
  78. this.controller,
  79. this.onTapClose,
  80. }) : super(key: key);
  81. @override
  82. _OverlayWidgetState createState() => _OverlayWidgetState();
  83. }
  84. class _OverlayWidgetState extends State<OverlayWidget> {
  85. double dx = 0;
  86. double dy = 0;
  87. @override
  88. Widget build(BuildContext context) {
  89. var size = Size(200, 200 * widget.initVideoInfo.ratio);
  90. return NotificationListener<OffsetNotication>(
  91. onNotification: (n) {
  92. dx += n.offset.dx;
  93. dy += n.offset.dy;
  94. setState(() {});
  95. return true;
  96. },
  97. child: Align(
  98. alignment: FractionalOffset.fromOffsetAndSize(Offset(dx, dy), size),
  99. child: Container(
  100. width: 200,
  101. child: AspectRatio(
  102. aspectRatio: widget.initVideoInfo.ratio,
  103. child: IjkPlayer(
  104. mediaController: widget.controller,
  105. controllerWidgetBuilder: (ctl) {
  106. return OverlayControllerWidget(
  107. controller: ctl,
  108. onTapClose: widget.onTapClose,
  109. );
  110. },
  111. ),
  112. ),
  113. ),
  114. ),
  115. );
  116. }
  117. }
  118. class OverlayControllerWidget extends StatefulWidget {
  119. final IjkMediaController controller;
  120. final Function onTapClose;
  121. const OverlayControllerWidget({
  122. Key key,
  123. this.controller,
  124. this.onTapClose,
  125. }) : super(key: key);
  126. @override
  127. _OverlayControllerWidgetState createState() =>
  128. _OverlayControllerWidgetState();
  129. }
  130. class _OverlayControllerWidgetState extends State<OverlayControllerWidget> {
  131. bool showController = false;
  132. @override
  133. Widget build(BuildContext context) {
  134. Widget child;
  135. if (!showController) {
  136. child = Container();
  137. } else {
  138. child = Container(
  139. color: Colors.black.withOpacity(0.6),
  140. child: Align(
  141. alignment: Alignment.topRight,
  142. child: Container(
  143. child: IconButton(
  144. color: Colors.white,
  145. icon: Icon(Icons.close),
  146. onPressed: widget.onTapClose,
  147. ),
  148. ),
  149. ),
  150. );
  151. }
  152. return GestureDetector(
  153. child: child,
  154. behavior: HitTestBehavior.opaque,
  155. onTap: () => setState(() => showController = !showController),
  156. // onLongPressMoveUpdate: (detail) {
  157. // print("onLongPressMoveUpdate detail = ${detail.offsetFromOrigin}");
  158. // },
  159. onPanUpdate: (detail) {
  160. print("onPanUpdate detail = ${detail.delta}");
  161. var notification = OffsetNotication()..offset = detail.delta;
  162. notification.dispatch(context);
  163. },
  164. );
  165. }
  166. }
  167. class OffsetNotication extends Notification {
  168. Offset offset;
  169. }