parent
52e968477c
commit
3b24d5c572
After Width: | Height: | Size: 558 KiB |
@ -0,0 +1,27 @@
|
||||
|
||||
|
||||
import 'package:recook/constants/api_v2.dart';
|
||||
import 'package:recook/manager/http_manager.dart';
|
||||
import 'package:recook/pages/home/model/aku_video_list_model.dart';
|
||||
|
||||
class HomeFuc {
|
||||
|
||||
//视频列表
|
||||
static Future<AkuVideoListModel> getAkuVideoList(
|
||||
String title,int page
|
||||
) async {
|
||||
ResultData result = await HttpManager.post(
|
||||
APIV2.userAPI.getAkuVideoList, {'title': title,
|
||||
'page':{
|
||||
'limit':10,
|
||||
'page':page,
|
||||
}
|
||||
});
|
||||
|
||||
if (result.data != null) {
|
||||
if (result.data['data'] != null) {
|
||||
return AkuVideoListModel.fromJson(result.data['data']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
class AkuVideoListModel {
|
||||
List<AkuVideo> list;
|
||||
int total;
|
||||
|
||||
AkuVideoListModel({this.list, this.total});
|
||||
|
||||
AkuVideoListModel.fromJson(Map<String, dynamic> json) {
|
||||
if (json['list'] != null) {
|
||||
list = new List<AkuVideo>();
|
||||
json['list'].forEach((v) {
|
||||
list.add(new AkuVideo.fromJson(v));
|
||||
});
|
||||
}
|
||||
total = json['total'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||
if (this.list != null) {
|
||||
data['list'] = this.list.map((v) => v.toJson()).toList();
|
||||
}
|
||||
data['total'] = this.total;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
class AkuVideo {
|
||||
int id;
|
||||
String title;
|
||||
String subTitle;
|
||||
int type;//1为视频 2为图文
|
||||
int isDraft;
|
||||
String createDTime;
|
||||
String textBody;
|
||||
String coverUrl;
|
||||
String videoUrl;
|
||||
num numberOfHits;
|
||||
|
||||
AkuVideo(
|
||||
{this.id,
|
||||
this.title,
|
||||
this.subTitle,
|
||||
this.type,
|
||||
this.isDraft,
|
||||
this.createDTime,
|
||||
this.textBody,
|
||||
this.coverUrl,
|
||||
this.videoUrl,
|
||||
this.numberOfHits,
|
||||
});
|
||||
|
||||
AkuVideo.fromJson(Map<String, dynamic> json) {
|
||||
id = json['id'];
|
||||
title = json['title'];
|
||||
subTitle = json['sub_title'];
|
||||
type = json['type'];
|
||||
isDraft = json['is_draft'];
|
||||
createDTime = json['create_d_time'];
|
||||
textBody = json['text_body'];
|
||||
coverUrl = json['cover_url'];
|
||||
videoUrl = json['video_url'];
|
||||
numberOfHits = json['number_of_hits'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||
data['id'] = this.id;
|
||||
data['title'] = this.title;
|
||||
data['sub_title'] = this.subTitle;
|
||||
data['type'] = this.type;
|
||||
data['is_draft'] = this.isDraft;
|
||||
data['create_d_time'] = this.createDTime;
|
||||
data['text_body'] = this.textBody;
|
||||
data['cover_url'] = this.coverUrl;
|
||||
data['video_url'] = this.videoUrl;
|
||||
data['number_of_hits'] = this.numberOfHits;
|
||||
return data;
|
||||
}
|
||||
}
|
@ -0,0 +1,172 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:recook/base/base_store_state.dart';
|
||||
import 'package:recook/constants/api.dart';
|
||||
import 'package:recook/constants/constants.dart';
|
||||
import 'package:recook/constants/header.dart';
|
||||
import 'package:recook/constants/styles.dart';
|
||||
import 'package:recook/pages/home/function/home_fuc.dart';
|
||||
import 'package:recook/pages/home/model/aku_video_list_model.dart';
|
||||
import 'package:recook/widgets/custom_app_bar.dart';
|
||||
import 'package:recook/widgets/custom_cache_image.dart';
|
||||
import 'package:recook/widgets/progress/re_toast.dart';
|
||||
import 'package:recook/widgets/refresh_widget.dart';
|
||||
import 'package:recook/widgets/webView.dart';
|
||||
import 'package:velocity_x/velocity_x.dart';
|
||||
import 'package:flustars/flustars.dart';
|
||||
import 'package:chewie/chewie.dart';
|
||||
import 'package:video_player/video_player.dart';
|
||||
import 'package:webview_flutter/webview_flutter.dart';
|
||||
|
||||
class AkuCollegeDetailPage extends StatefulWidget {
|
||||
final AkuVideo akuVideo;
|
||||
|
||||
const AkuCollegeDetailPage({Key key, @required this.akuVideo})
|
||||
: super(key: key);
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
return _AkuCollegeDetailPageState();
|
||||
}
|
||||
}
|
||||
|
||||
class _AkuCollegeDetailPageState extends BaseStoreState<AkuCollegeDetailPage> {
|
||||
//final FijkPlayer player = FijkPlayer();
|
||||
|
||||
VideoPlayerController _videoPlayerController;
|
||||
ChewieController _chewieController;
|
||||
WebViewController _webViewController;
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
if (widget.akuVideo.type == 1) {
|
||||
_videoPlayerController = VideoPlayerController.network(
|
||||
Api.getImgUrl(widget.akuVideo.videoUrl));
|
||||
_videoPlayerController.initialize().then((_) {
|
||||
_chewieController = ChewieController(
|
||||
videoPlayerController: _videoPlayerController,
|
||||
aspectRatio: _videoPlayerController.value.aspectRatio,
|
||||
autoPlay: false,
|
||||
showControls: true,
|
||||
);
|
||||
|
||||
setState(() {});
|
||||
});
|
||||
}
|
||||
|
||||
// player.setDataSource(Api.getImgUrl(widget.akuVideo.videoUrl),
|
||||
// autoPlay: false);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_videoPlayerController?.dispose();
|
||||
_chewieController?.dispose();
|
||||
super.dispose();
|
||||
//player.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget buildContext(BuildContext context, {store}) {
|
||||
return Scaffold(
|
||||
backgroundColor: Color(0xFFFFFFFF),
|
||||
appBar: CustomAppBar(
|
||||
title: "".text.bold.size(18.rsp).make(),
|
||||
themeData: AppThemes.themeDataGrey.appBarTheme,
|
||||
),
|
||||
body: _bodyWidget(),
|
||||
);
|
||||
}
|
||||
|
||||
_bodyWidget() {
|
||||
return ListView(
|
||||
children: [
|
||||
40.hb,
|
||||
Row(
|
||||
children: [
|
||||
30.wb,
|
||||
Text(
|
||||
widget.akuVideo.title,
|
||||
maxLines: 2,
|
||||
softWrap: true,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
fontSize: 20.rsp,
|
||||
color: Color(0xFF333333),
|
||||
fontWeight: FontWeight.bold),
|
||||
).expand(),
|
||||
30.wb,
|
||||
],
|
||||
),
|
||||
20.hb,
|
||||
Row(
|
||||
children: [
|
||||
30.wb,
|
||||
Text(
|
||||
widget.akuVideo.subTitle,
|
||||
softWrap: true,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
fontSize: 12.rsp,
|
||||
color: Color(0xFF333333),
|
||||
),
|
||||
),
|
||||
40.wb,
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 3.rw),
|
||||
child: Text(
|
||||
_getDateTime(widget.akuVideo.createDTime),
|
||||
softWrap: true,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
fontSize: 12.rsp,
|
||||
color: Color(0xFF999999),
|
||||
),
|
||||
),
|
||||
),
|
||||
40.wb,
|
||||
Text(
|
||||
widget.akuVideo.numberOfHits.toString() + '人已学习',
|
||||
softWrap: true,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
fontSize: 12.rsp,
|
||||
color: Color(0xFF999999),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
widget.akuVideo.type == 1 ? _playVideo() : _playImagText()
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
_getDateTime(String date) {
|
||||
if (date.isEmpty) {
|
||||
return date;
|
||||
} else {
|
||||
DateTime dateTime = DateUtil.getDateTime(date);
|
||||
return DateUtil.formatDate(dateTime, format: 'yyyy-MM-dd');
|
||||
}
|
||||
}
|
||||
|
||||
_playVideo() {
|
||||
return Container(
|
||||
padding: EdgeInsets.only(top: 20.rw, left: 15.rw, right: 15.rw),
|
||||
height: 230.rw,
|
||||
child: _chewieController != null
|
||||
? Chewie(
|
||||
controller: _chewieController,
|
||||
)
|
||||
: SizedBox(),
|
||||
);
|
||||
}
|
||||
|
||||
// _playImagText() {
|
||||
// return Container(
|
||||
// height: 300.rw,
|
||||
// width: 500.rw,
|
||||
// child: HtmlWidget(),
|
||||
// );
|
||||
// }
|
||||
|
||||
}
|
@ -0,0 +1,260 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
import 'package:recook/base/base_store_state.dart';
|
||||
import 'package:recook/constants/api.dart';
|
||||
import 'package:recook/constants/constants.dart';
|
||||
import 'package:recook/constants/header.dart';
|
||||
import 'package:recook/constants/styles.dart';
|
||||
import 'package:recook/pages/home/function/home_fuc.dart';
|
||||
import 'package:recook/pages/home/model/aku_video_list_model.dart';
|
||||
import 'package:recook/widgets/custom_app_bar.dart';
|
||||
import 'package:recook/widgets/custom_cache_image.dart';
|
||||
import 'package:recook/widgets/progress/re_toast.dart';
|
||||
import 'package:recook/widgets/refresh_widget.dart';
|
||||
import 'package:velocity_x/velocity_x.dart';
|
||||
|
||||
|
||||
import 'aku_college_detail_page.dart';
|
||||
|
||||
class AkuCollegePage extends StatefulWidget {
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
return _AkuCollegePageState();
|
||||
}
|
||||
}
|
||||
|
||||
class _AkuCollegePageState extends BaseStoreState<AkuCollegePage> {
|
||||
GSRefreshController _refreshController =
|
||||
GSRefreshController(initialRefresh: true);
|
||||
TextEditingController _textEditController;
|
||||
AkuVideoListModel _akuVideoListModel;
|
||||
List<AkuVideo> _akuVideoList;
|
||||
String _searchText;
|
||||
int page = 1;
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget buildContext(BuildContext context, {store}) {
|
||||
return Scaffold(
|
||||
backgroundColor: Color(0xFFFFFFFF),
|
||||
appBar: CustomAppBar(
|
||||
title: "阿库学院".text.bold.size(18.rsp).make(),
|
||||
themeData: AppThemes.themeDataGrey.appBarTheme,
|
||||
),
|
||||
body: _bodyWidget(),
|
||||
);
|
||||
}
|
||||
|
||||
_bodyWidget() {
|
||||
return Column(
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: () {},
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
height: 160.rw,
|
||||
child: Image.asset(
|
||||
R.ASSETS_AKU_COLLEGE_PNG,
|
||||
fit: BoxFit.fill,
|
||||
),
|
||||
),
|
||||
),
|
||||
50.hb,
|
||||
Container(
|
||||
alignment: Alignment.center,
|
||||
width: 190.rw,
|
||||
height: 26.rw,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
offset: Offset(0, 2),
|
||||
color: Color(0x45B4B1B1),
|
||||
blurRadius: 4.rw,
|
||||
)
|
||||
],
|
||||
borderRadius: BorderRadius.all(Radius.circular(13.rw)),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: CupertinoTextField(
|
||||
keyboardType: TextInputType.text,
|
||||
controller: _textEditController,
|
||||
//textInputAction: TextInputAction.search,
|
||||
onChanged: (text) {},
|
||||
placeholder: "搜一下是否有您想要的内容",
|
||||
placeholderStyle: TextStyle(
|
||||
color: Color(0xFF999999),
|
||||
fontSize: 10.rsp,
|
||||
fontWeight: FontWeight.w300),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.all(Radius.circular(13.rw)),
|
||||
),
|
||||
style: TextStyle(color: Colors.black, fontSize: 14.rsp),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: 1.rw,
|
||||
height: 27.rw,
|
||||
color: Color(0xFFEEEDED),
|
||||
),
|
||||
Container(
|
||||
width: 37.rw,
|
||||
padding: EdgeInsets.symmetric(horizontal: 5),
|
||||
child: Icon(
|
||||
Icons.search,
|
||||
size: 15.rw,
|
||||
color: Color(0xFFC92219),
|
||||
),
|
||||
),
|
||||
],
|
||||
)),
|
||||
_buildListView(),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
_buildListView() {
|
||||
return Container(
|
||||
margin: EdgeInsets.only(left: 8.rw, right: 8.rw, top: 26.rw),
|
||||
child: RefreshWidget(
|
||||
controller: _refreshController,
|
||||
noData: '没有找到您想要的内容',
|
||||
onRefresh: () async {
|
||||
Function cancel = ReToast.loading();
|
||||
|
||||
_akuVideoListModel =
|
||||
await HomeFuc.getAkuVideoList(_searchText, page);
|
||||
|
||||
setState(() {});
|
||||
_refreshController.refreshCompleted();
|
||||
cancel();
|
||||
},
|
||||
onLoadMore: () async {
|
||||
if (_akuVideoListModel.list.length >=
|
||||
_akuVideoListModel.total) {
|
||||
_refreshController.loadComplete();
|
||||
_refreshController.loadNoData();
|
||||
} else {
|
||||
_akuVideoListModel =
|
||||
await HomeFuc.getAkuVideoList(_searchText, page++);
|
||||
_refreshController.loadComplete();
|
||||
}
|
||||
},
|
||||
body: _akuVideoListModel?.list != null
|
||||
? GridView.builder(
|
||||
shrinkWrap: true,
|
||||
padding: EdgeInsets.zero,
|
||||
gridDelegate:
|
||||
const SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 2,
|
||||
childAspectRatio: 170 / 162,
|
||||
mainAxisSpacing: 10,
|
||||
crossAxisSpacing: 17),
|
||||
itemCount: _akuVideoListModel.list.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return
|
||||
// Container(
|
||||
// color: Colors.red,
|
||||
// );
|
||||
_akuVideoItem(_akuVideoListModel.list[index]);
|
||||
},
|
||||
)
|
||||
: noDataView('没有找到您想要的内容')))
|
||||
.expand();
|
||||
}
|
||||
|
||||
_akuVideoItem(AkuVideo akuVideo) {
|
||||
return Container(
|
||||
margin: EdgeInsets.only(left: 4.rw, right: 4.rw, top: 4.rw),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(4.rw),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Color(0xFFDBDBDB),
|
||||
blurRadius: 4,
|
||||
offset: Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
//跳转页面
|
||||
Get.to(AkuCollegeDetailPage(akuVideo: akuVideo));
|
||||
},
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
Positioned(
|
||||
child: Container(
|
||||
child: CustomCacheImage(
|
||||
imageUrl: Api.getImgUrl(akuVideo.coverUrl),
|
||||
height: 90.rw,
|
||||
fit: BoxFit.fitWidth,
|
||||
),
|
||||
),
|
||||
),
|
||||
akuVideo.type == 1
|
||||
? Positioned(
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
child: Icon(CupertinoIcons.play_circle,
|
||||
size: 50, color: Colors.white),
|
||||
)
|
||||
: SizedBox()
|
||||
],
|
||||
),
|
||||
),
|
||||
10.hb,
|
||||
Row(
|
||||
children: [
|
||||
16.wb,
|
||||
Text(
|
||||
akuVideo.title,
|
||||
maxLines: 2,
|
||||
softWrap: true,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
fontSize: 12.rsp,
|
||||
color: Color(0xFF333333),
|
||||
fontWeight: FontWeight.bold),
|
||||
).expand(),
|
||||
16.wb,
|
||||
],
|
||||
),
|
||||
Spacer(),
|
||||
Row(
|
||||
children: [
|
||||
16.wb,
|
||||
Text(akuVideo.subTitle,
|
||||
style: TextStyle(fontSize: 10.rsp, color: Color(0xFF333333))),
|
||||
Spacer(),
|
||||
Text(akuVideo.numberOfHits.toString() + '人看过',
|
||||
style: TextStyle(fontSize: 10.rsp, color: Color(0xFF999999))),
|
||||
16.wb,
|
||||
],
|
||||
),
|
||||
20.hb,
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_getNum(int num) {}
|
||||
}
|
@ -0,0 +1,97 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:webview_flutter/webview_flutter.dart';
|
||||
|
||||
class WebViewLocalPage extends StatefulWidget {
|
||||
|
||||
String url;
|
||||
final String title;
|
||||
final bool isLocalUrl;
|
||||
|
||||
WebViewController _webViewController;
|
||||
|
||||
WebViewLocalPage({this.url, this.isLocalUrl = false, this.title});
|
||||
|
||||
@override
|
||||
_WebViewLocalPage createState() => _WebViewLocalPage();
|
||||
|
||||
|
||||
}
|
||||
|
||||
class _WebViewLocalPage extends State<WebViewLocalPage> {
|
||||
|
||||
JavascriptChannel jsBridge(BuildContext context) => JavascriptChannel(
|
||||
name: 'jsbridge', // 与h5 端的一致 不然收不到消息
|
||||
onMessageReceived: (JavascriptMessage message) async{
|
||||
debugPrint(message.message);
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: _buildAppbar(),
|
||||
body: _buildBody()
|
||||
);
|
||||
}
|
||||
|
||||
_buildAppbar() {
|
||||
return AppBar(
|
||||
elevation: 0,
|
||||
backgroundColor: Color(0xccd0d7),
|
||||
title: Text(widget.title, style: TextStyle(color: Colors.black),),
|
||||
centerTitle: true,
|
||||
leading: IconButton(icon: Icon(Icons.arrow_back, color: Color(0xFF23ADE5),), onPressed: () {
|
||||
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
_buildBody() {
|
||||
return Column(
|
||||
children: <Widget>[
|
||||
SizedBox(
|
||||
height: 1,
|
||||
width: double.infinity,
|
||||
child: const DecoratedBox(decoration: BoxDecoration(color: Color(0xFFEEEEEE))),
|
||||
),
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: WebView(
|
||||
initialUrl: widget.isLocalUrl ? Uri.dataFromString(widget.url, mimeType: 'text/html', encoding: Encoding.getByName('utf-8'))
|
||||
.toString(): widget.url,
|
||||
javascriptMode: JavascriptMode.unrestricted,
|
||||
javascriptChannels: <JavascriptChannel>[
|
||||
jsBridge(context)
|
||||
].toSet(),
|
||||
onWebViewCreated: (WebViewController controller){
|
||||
widget._webViewController = controller;
|
||||
if(widget.isLocalUrl){
|
||||
_loadHtmlAssets(controller);
|
||||
}else{
|
||||
controller.loadUrl(widget.url);
|
||||
}
|
||||
controller.canGoBack().then((value) => debugPrint(value.toString()));
|
||||
controller.canGoForward().then((value) => debugPrint(value.toString()));
|
||||
controller.currentUrl().then((value) => debugPrint(value));
|
||||
},
|
||||
onPageFinished: (String value){
|
||||
widget._webViewController.evaluateJavascript('document.title')
|
||||
.then((title) => debugPrint(title));
|
||||
},
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
//加载本地文件
|
||||
_loadHtmlAssets(WebViewController controller) async {
|
||||
String htmlPath = await rootBundle.loadString(widget.url);
|
||||
controller.loadUrl(Uri.dataFromString(htmlPath,mimeType: 'text/html', encoding: Encoding.getByName('utf-8'))
|
||||
.toString());
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in new issue