parent
b025d6dfa0
commit
19e23f66a4
@ -0,0 +1,146 @@
|
||||
import 'package:akuCommunity/model/common/img_model.dart';
|
||||
|
||||
class CommunityTopicModel {
|
||||
int id;
|
||||
int createId;
|
||||
int isComment;
|
||||
int isLike;
|
||||
String createName;
|
||||
String content;
|
||||
String gambitTitle;
|
||||
String createDate;
|
||||
List<LikeNames> likeNames;
|
||||
List<ImgModel> imgUrls;
|
||||
List<ImgModel> headSculptureImgUrl;
|
||||
List<GambitThemeCommentVoList> gambitThemeCommentVoList;
|
||||
|
||||
CommunityTopicModel(
|
||||
{this.id,
|
||||
this.createId,
|
||||
this.isComment,
|
||||
this.isLike,
|
||||
this.createName,
|
||||
this.content,
|
||||
this.gambitTitle,
|
||||
this.createDate,
|
||||
this.likeNames,
|
||||
this.imgUrls,
|
||||
this.headSculptureImgUrl,
|
||||
this.gambitThemeCommentVoList});
|
||||
|
||||
CommunityTopicModel.fromJson(Map<String, dynamic> json) {
|
||||
id = json['id'];
|
||||
createId = json['createId'];
|
||||
isComment = json['isComment'];
|
||||
isLike = json['isLike'];
|
||||
createName = json['createName'];
|
||||
content = json['content'];
|
||||
gambitTitle = json['gambitTitle'];
|
||||
createDate = json['createDate'];
|
||||
if (json['likeNames'] != null) {
|
||||
likeNames = new List<LikeNames>();
|
||||
json['likeNames'].forEach((v) {
|
||||
likeNames.add(new LikeNames.fromJson(v));
|
||||
});
|
||||
}
|
||||
if (json['imgUrls'] != null) {
|
||||
imgUrls = new List<ImgModel>();
|
||||
json['imgUrls'].forEach((v) {
|
||||
imgUrls.add(new ImgModel.fromJson(v));
|
||||
});
|
||||
} else
|
||||
imgUrls = [];
|
||||
if (json['headSculptureImgUrl'] != null) {
|
||||
headSculptureImgUrl = new List<ImgModel>();
|
||||
json['headSculptureImgUrl'].forEach((v) {
|
||||
headSculptureImgUrl.add(new ImgModel.fromJson(v));
|
||||
});
|
||||
} else
|
||||
headSculptureImgUrl = [];
|
||||
if (json['gambitThemeCommentVoList'] != null) {
|
||||
gambitThemeCommentVoList = new List<GambitThemeCommentVoList>();
|
||||
json['gambitThemeCommentVoList'].forEach((v) {
|
||||
gambitThemeCommentVoList.add(new GambitThemeCommentVoList.fromJson(v));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||
data['id'] = this.id;
|
||||
data['createId'] = this.createId;
|
||||
data['isComment'] = this.isComment;
|
||||
data['isLike'] = this.isLike;
|
||||
data['createName'] = this.createName;
|
||||
data['content'] = this.content;
|
||||
data['gambitTitle'] = this.gambitTitle;
|
||||
data['createDate'] = this.createDate;
|
||||
if (this.likeNames != null) {
|
||||
data['likeNames'] = this.likeNames.map((v) => v.toJson()).toList();
|
||||
}
|
||||
if (this.imgUrls != null) {
|
||||
data['imgUrls'] = this.imgUrls.map((v) => v.toJson()).toList();
|
||||
}
|
||||
if (this.headSculptureImgUrl != null) {
|
||||
data['headSculptureImgUrl'] =
|
||||
this.headSculptureImgUrl.map((v) => v.toJson()).toList();
|
||||
}
|
||||
if (this.gambitThemeCommentVoList != null) {
|
||||
data['gambitThemeCommentVoList'] =
|
||||
this.gambitThemeCommentVoList.map((v) => v.toJson()).toList();
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
class LikeNames {
|
||||
int id;
|
||||
String name;
|
||||
|
||||
LikeNames({this.id, this.name});
|
||||
|
||||
LikeNames.fromJson(Map<String, dynamic> json) {
|
||||
id = json['id'];
|
||||
name = json['name'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||
data['id'] = this.id;
|
||||
data['name'] = this.name;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
class GambitThemeCommentVoList {
|
||||
int id;
|
||||
String parentName;
|
||||
String content;
|
||||
String createName;
|
||||
String createDate;
|
||||
|
||||
GambitThemeCommentVoList(
|
||||
{this.id,
|
||||
this.parentName,
|
||||
this.content,
|
||||
this.createName,
|
||||
this.createDate});
|
||||
|
||||
GambitThemeCommentVoList.fromJson(Map<String, dynamic> json) {
|
||||
id = json['id'];
|
||||
parentName = json['parentName'];
|
||||
content = json['content'];
|
||||
createName = json['createName'];
|
||||
createDate = json['createDate'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||
data['id'] = this.id;
|
||||
data['parentName'] = this.parentName;
|
||||
data['content'] = this.content;
|
||||
data['createName'] = this.createName;
|
||||
data['createDate'] = this.createDate;
|
||||
return data;
|
||||
}
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
import 'package:akuCommunity/ui/community/community_views/my_community_view.dart';
|
||||
import 'package:akuCommunity/ui/community/community_views/new_community_view.dart';
|
||||
import 'package:akuCommunity/ui/community/community_views/topic/topic_community_view.dart';
|
||||
import 'package:akuCommunity/utils/headers.dart';
|
||||
import 'package:akuCommunity/widget/bee_scaffold.dart';
|
||||
import 'package:akuCommunity/widget/buttons/column_action_button.dart';
|
||||
import 'package:akuCommunity/widget/tab_bar/bee_tab_bar.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class CommunityPage extends StatefulWidget {
|
||||
CommunityPage({Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_CommunityPageState createState() => _CommunityPageState();
|
||||
}
|
||||
|
||||
class _CommunityPageState extends State<CommunityPage>
|
||||
with TickerProviderStateMixin, AutomaticKeepAliveClientMixin {
|
||||
TabController _tabController;
|
||||
List<String> _tabs = ['最新', '话题', '我的'];
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_tabController = TabController(
|
||||
vsync: this,
|
||||
length: _tabs.length,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
super.build(context);
|
||||
return BeeScaffold(
|
||||
title: '社区',
|
||||
actions: [
|
||||
ColumnActionButton(
|
||||
onPressed: () {},
|
||||
title: '消息',
|
||||
path: R.ASSETS_ICONS_ALARM_PNG,
|
||||
),
|
||||
],
|
||||
appBarBottom: PreferredSize(
|
||||
preferredSize: Size.fromHeight(48),
|
||||
child: Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: BeeTabBar(
|
||||
controller: _tabController,
|
||||
tabs: _tabs,
|
||||
scrollable: true,
|
||||
),
|
||||
),
|
||||
),
|
||||
body: TabBarView(
|
||||
children: [
|
||||
NewCommunityView(),
|
||||
TopicCommunityView(),
|
||||
MyCommunityView(),
|
||||
],
|
||||
controller: _tabController,
|
||||
),
|
||||
bodyColor: Colors.white,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
bool get wantKeepAlive => true;
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class MyCommunityView extends StatefulWidget {
|
||||
MyCommunityView({Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_MyCommunityViewState createState() => _MyCommunityViewState();
|
||||
}
|
||||
|
||||
class _MyCommunityViewState extends State<MyCommunityView>
|
||||
with AutomaticKeepAliveClientMixin {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
super.build(context);
|
||||
return Container();
|
||||
}
|
||||
|
||||
@override
|
||||
bool get wantKeepAlive => true;
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class NewCommunityView extends StatefulWidget {
|
||||
NewCommunityView({Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_NewCommunityViewState createState() => _NewCommunityViewState();
|
||||
}
|
||||
|
||||
class _NewCommunityViewState extends State<NewCommunityView>
|
||||
with AutomaticKeepAliveClientMixin {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
super.build(context);
|
||||
return Container();
|
||||
}
|
||||
|
||||
@override
|
||||
bool get wantKeepAlive => true;
|
||||
}
|
@ -0,0 +1,125 @@
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:akuCommunity/ui/community/community_views/topic/topic_detail_page.dart';
|
||||
import 'package:akuCommunity/utils/headers.dart';
|
||||
import 'package:akuCommunity/constants/api.dart';
|
||||
import 'package:akuCommunity/model/community/community_topic_model.dart';
|
||||
import 'package:akuCommunity/pages/things_page/widget/bee_list_view.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_easyrefresh/easy_refresh.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
class TopicCommunityView extends StatefulWidget {
|
||||
TopicCommunityView({Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_TopicCommunityViewState createState() => _TopicCommunityViewState();
|
||||
}
|
||||
|
||||
class _TopicCommunityViewState extends State<TopicCommunityView>
|
||||
with AutomaticKeepAliveClientMixin {
|
||||
EasyRefreshController _refreshController = EasyRefreshController();
|
||||
|
||||
_buildItem(CommunityTopicModel model) {
|
||||
var firstImg = '';
|
||||
if (model?.imgUrls?.isNotEmpty ?? false) {
|
||||
firstImg = model?.imgUrls?.first?.url ?? '';
|
||||
}
|
||||
return MaterialButton(
|
||||
padding: EdgeInsets.symmetric(horizontal: 53.w, vertical: 20.w),
|
||||
onPressed: () {
|
||||
Get.to(TopicDetailPage(id: model.id));
|
||||
},
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
clipBehavior: Clip.antiAlias,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(8.w),
|
||||
color: Colors.black12,
|
||||
),
|
||||
child: Stack(
|
||||
children: [
|
||||
FadeInImage.assetNetwork(
|
||||
placeholder: R.ASSETS_IMAGES_LOGO_PNG,
|
||||
image: API.image(firstImg),
|
||||
height: 160.w,
|
||||
width: 250.w,
|
||||
),
|
||||
Positioned(
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.vertical(
|
||||
bottom: Radius.circular(8.w),
|
||||
),
|
||||
child: BackdropFilter(
|
||||
filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5),
|
||||
//TODO 等待后端接口补充话题摘要
|
||||
// model.summary
|
||||
child: ('#${''}')
|
||||
.text
|
||||
.center
|
||||
.size(28.sp)
|
||||
.white
|
||||
.make()
|
||||
.material(color: Colors.black26),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
12.wb,
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
(model?.gambitTitle ?? '')
|
||||
.text
|
||||
.maxLines(2)
|
||||
.size(28.sp)
|
||||
.bold
|
||||
.overflow(TextOverflow.ellipsis)
|
||||
.make(),
|
||||
(model?.content ?? '')
|
||||
.text
|
||||
.maxLines(1)
|
||||
.size(22.sp)
|
||||
.overflow(TextOverflow.ellipsis)
|
||||
.make(),
|
||||
12.hb,
|
||||
],
|
||||
).expand(),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
super.build(context);
|
||||
return BeeListView(
|
||||
path: API.community.topicList,
|
||||
controller: _refreshController,
|
||||
convert: (model) {
|
||||
return model.tableList
|
||||
.map((e) => CommunityTopicModel.fromJson(e))
|
||||
.toList();
|
||||
},
|
||||
builder: (items) {
|
||||
return ListView.separated(
|
||||
itemBuilder: (context, index) {
|
||||
return _buildItem(items[index]);
|
||||
},
|
||||
separatorBuilder: (_, __) => 20.hb,
|
||||
itemCount: items.length,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
bool get wantKeepAlive => true;
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
import 'package:akuCommunity/ui/community/community_views/topic/topic_scrollable_text.dart';
|
||||
import 'package:akuCommunity/utils/headers.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class TopicDetailPage extends StatefulWidget {
|
||||
final int id;
|
||||
TopicDetailPage({Key key, @required this.id}) : super(key: key);
|
||||
|
||||
@override
|
||||
_TopicDetailPageState createState() => _TopicDetailPageState();
|
||||
}
|
||||
|
||||
class _TopicDetailPageState extends State<TopicDetailPage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: CustomScrollView(
|
||||
slivers: [
|
||||
SliverAppBar(
|
||||
expandedHeight: 500.w,
|
||||
backgroundColor: Colors.transparent,
|
||||
elevation: 0,
|
||||
pinned: true,
|
||||
flexibleSpace: FlexibleSpaceBar(
|
||||
title: TopicScrollableText(title: '#TEST'),
|
||||
titlePadding: EdgeInsets.zero,
|
||||
collapseMode: CollapseMode.pin,
|
||||
background: Container(color: Colors.red),
|
||||
),
|
||||
),
|
||||
SliverToBoxAdapter(
|
||||
child: 40000.hb,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
import 'package:akuCommunity/utils/headers.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class TopicScrollableText extends StatefulWidget {
|
||||
final String title;
|
||||
TopicScrollableText({Key key, @required this.title}) : super(key: key);
|
||||
|
||||
@override
|
||||
_TopicScrollableTextState createState() => _TopicScrollableTextState();
|
||||
}
|
||||
|
||||
class _TopicScrollableTextState extends State<TopicScrollableText> {
|
||||
ScrollPosition _scrollPosition;
|
||||
|
||||
_positionListener() {
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_scrollPosition?.removeListener(_positionListener);
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
super.didChangeDependencies();
|
||||
_scrollPosition = Scrollable.of(context)?.position;
|
||||
_scrollPosition?.addListener(_positionListener);
|
||||
}
|
||||
|
||||
double get offset {
|
||||
if (_scrollPosition.pixels >= 500.w) return 1;
|
||||
if (_scrollPosition.pixels < 500.w && _scrollPosition.pixels >= 0) {
|
||||
return _scrollPosition.pixels / 500.w;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(bottom: 202.w - offset * 160.w),
|
||||
child: Text(widget.title),
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in new issue