|
@@ -2,19 +2,29 @@ import 'package:flutter/material.dart';
|
|
|
import 'package:flutter_easyrefresh/easy_refresh.dart';
|
|
|
import 'package:provider/provider.dart';
|
|
|
import 'package:sport/bean/post.dart';
|
|
|
+import 'package:sport/bean/post_user.dart';
|
|
|
+import 'package:sport/bean/user_friend.dart';
|
|
|
+import 'package:sport/bean/user_info.dart';
|
|
|
import 'package:sport/pages/social/post_widget.dart';
|
|
|
+import 'package:sport/pages/social/user_detail_page.dart';
|
|
|
import 'package:sport/provider/lib/provider_widget.dart' as p;
|
|
|
import 'package:sport/provider/lib/provider_widget_selector.dart';
|
|
|
+import 'package:sport/provider/lib/simple_model.dart';
|
|
|
+import 'package:sport/provider/lib/view_state_lifecycle.dart';
|
|
|
import 'package:sport/provider/search_model.dart';
|
|
|
import 'package:sport/provider/social_detail_model.dart';
|
|
|
import 'package:sport/router/navigator_util.dart';
|
|
|
+import 'package:sport/services/api/inject_api.dart';
|
|
|
import 'package:sport/services/api/resp.dart';
|
|
|
import 'package:sport/services/userid.dart';
|
|
|
+import 'package:sport/utils/toast.dart';
|
|
|
import 'package:sport/widgets/appbar.dart';
|
|
|
+import 'package:sport/widgets/dialog/request_dialog.dart';
|
|
|
import 'package:sport/widgets/error.dart';
|
|
|
import 'package:sport/widgets/image.dart';
|
|
|
import 'package:sport/widgets/loading.dart';
|
|
|
import 'package:sport/widgets/misc.dart';
|
|
|
+import 'package:sport/widgets/persistent_header.dart';
|
|
|
import 'package:sport/widgets/space.dart';
|
|
|
|
|
|
class SearchPage extends StatefulWidget {
|
|
@@ -22,13 +32,17 @@ class SearchPage extends StatefulWidget {
|
|
|
State<StatefulWidget> createState() => _PageState();
|
|
|
}
|
|
|
|
|
|
-class _PageState extends State<SearchPage> with UserId {
|
|
|
+class _PageState extends State<SearchPage> with UserId, InjectApi {
|
|
|
TextEditingController _controller;
|
|
|
FocusNode _focusNode;
|
|
|
|
|
|
SearchModel _model;
|
|
|
SocialDetailModel _searchModel;
|
|
|
|
|
|
+ final double tabHeader = 50;
|
|
|
+
|
|
|
+ SimpleModel simpleModel;
|
|
|
+
|
|
|
@override
|
|
|
void initState() {
|
|
|
super.initState();
|
|
@@ -38,14 +52,20 @@ class _PageState extends State<SearchPage> with UserId {
|
|
|
..getHistory()
|
|
|
..getHot();
|
|
|
_searchModel = SocialDetailModel("0", 100);
|
|
|
+ simpleModel = new SimpleModel((page) async {
|
|
|
+ var list = (await api.userSearch(kw: _model.searchValue, page: page))
|
|
|
+ .pageResult
|
|
|
+ .results;
|
|
|
+ return list;
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
@override
|
|
|
void dispose() {
|
|
|
+ super.dispose();
|
|
|
_focusNode?.dispose();
|
|
|
_controller?.dispose();
|
|
|
_searchModel?.dispose();
|
|
|
- super.dispose();
|
|
|
}
|
|
|
|
|
|
_submitValue(String value) {
|
|
@@ -70,8 +90,8 @@ class _PageState extends State<SearchPage> with UserId {
|
|
|
body = _buildDefaultWidget();
|
|
|
break;
|
|
|
case SearchBody.suggestions:
|
|
|
- body = buildSuggestions(context);
|
|
|
- break;
|
|
|
+// body = buildSuggestions(context);
|
|
|
+// break;
|
|
|
case SearchBody.results:
|
|
|
body = buildResults(context);
|
|
|
break;
|
|
@@ -97,7 +117,6 @@ class _PageState extends State<SearchPage> with UserId {
|
|
|
width: 12,
|
|
|
),
|
|
|
Image.asset("lib/assets/img/searchbar_icon_search.png"),
|
|
|
-
|
|
|
Expanded(
|
|
|
child: Selector<SearchModel, String>(
|
|
|
selector: (_, model) => model.searchValue,
|
|
@@ -106,13 +125,14 @@ class _PageState extends State<SearchPage> with UserId {
|
|
|
maxLines: 1,
|
|
|
focusNode: _focusNode,
|
|
|
decoration: InputDecoration(
|
|
|
- hintText: '请输入搜索内容',
|
|
|
- contentPadding: EdgeInsets.symmetric(vertical: 11.0, horizontal: 16.0),
|
|
|
- border: InputBorder.none,
|
|
|
- hintStyle: TextStyle(color: Color(0xff999999))
|
|
|
- ),
|
|
|
+ hintText: '请输入搜索内容',
|
|
|
+ contentPadding: EdgeInsets.symmetric(
|
|
|
+ vertical: 11.0, horizontal: 16.0),
|
|
|
+ border: InputBorder.none,
|
|
|
+ hintStyle: TextStyle(color: Color(0xff999999))),
|
|
|
onChanged: (value) {
|
|
|
- Provider.of<SearchModel>(context, listen: false).updateSearchValue(value);
|
|
|
+ Provider.of<SearchModel>(context, listen: false)
|
|
|
+ .updateSearchValue(value);
|
|
|
},
|
|
|
onSubmitted: (value) {
|
|
|
_submitValue(value);
|
|
@@ -122,15 +142,20 @@ class _PageState extends State<SearchPage> with UserId {
|
|
|
),
|
|
|
)),
|
|
|
Visibility(
|
|
|
- visible: context.select<SearchModel, String>((value) => value.searchValue).isNotEmpty,
|
|
|
+ visible: context
|
|
|
+ .select<SearchModel, String>(
|
|
|
+ (value) => value.searchValue)
|
|
|
+ .isNotEmpty,
|
|
|
child: GestureDetector(
|
|
|
onTap: () {
|
|
|
- Provider.of<SearchModel>(context, listen: false).updateSearchValue("");
|
|
|
+ Provider.of<SearchModel>(context, listen: false)
|
|
|
+ .updateSearchValue("");
|
|
|
_controller.clear();
|
|
|
},
|
|
|
child: Padding(
|
|
|
padding: const EdgeInsets.all(8.0),
|
|
|
- child: Image.asset("lib/assets/img/searchbar_btn_no.png"),
|
|
|
+ child: Image.asset(
|
|
|
+ "lib/assets/img/searchbar_btn_no.png"),
|
|
|
),
|
|
|
))
|
|
|
],
|
|
@@ -164,7 +189,11 @@ class _PageState extends State<SearchPage> with UserId {
|
|
|
return Column(
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
children: <Widget>[
|
|
|
- Text("热门帖子", style: Theme.of(context).textTheme.headline3.copyWith(fontSize: 18)),
|
|
|
+ Text("热门帖子",
|
|
|
+ style: Theme.of(context)
|
|
|
+ .textTheme
|
|
|
+ .headline3
|
|
|
+ .copyWith(fontSize: 18)),
|
|
|
Padding(
|
|
|
padding: const EdgeInsets.symmetric(vertical: 6.0),
|
|
|
child: Wrap(
|
|
@@ -177,12 +206,15 @@ class _PageState extends State<SearchPage> with UserId {
|
|
|
// _model.queryValue(e);
|
|
|
},
|
|
|
child: Chip(
|
|
|
- labelPadding: const EdgeInsets.fromLTRB(16.0, 0, 16.0, 0),
|
|
|
+ labelPadding: const EdgeInsets.fromLTRB(
|
|
|
+ 16.0, 0, 16.0, 0),
|
|
|
label: Text("$e"),
|
|
|
- labelStyle: TextStyle(color: Color(0xff666666)),
|
|
|
+ labelStyle:
|
|
|
+ TextStyle(color: Color(0xff666666)),
|
|
|
backgroundColor: Colors.white,
|
|
|
shape: StadiumBorder(
|
|
|
- side: BorderSide(color: Color(0xffDCDCDC), width: 0.5),
|
|
|
+ side: BorderSide(
|
|
|
+ color: Color(0xffDCDCDC), width: 0.5),
|
|
|
),
|
|
|
));
|
|
|
}).toList()),
|
|
@@ -208,14 +240,19 @@ class _PageState extends State<SearchPage> with UserId {
|
|
|
Row(
|
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
|
children: <Widget>[
|
|
|
- Text("历史搜索", style: Theme.of(context).textTheme.headline3.copyWith(fontSize: 18)),
|
|
|
+ Text("历史搜索",
|
|
|
+ style: Theme.of(context)
|
|
|
+ .textTheme
|
|
|
+ .headline3
|
|
|
+ .copyWith(fontSize: 18)),
|
|
|
InkWell(
|
|
|
onTap: () {
|
|
|
_model.clearHistory();
|
|
|
},
|
|
|
child: Padding(
|
|
|
padding: const EdgeInsets.all(8.0),
|
|
|
- child: Image.asset("lib/assets/img/list_icon_del.png"),
|
|
|
+ child: Image.asset(
|
|
|
+ "lib/assets/img/list_icon_del.png"),
|
|
|
),
|
|
|
)
|
|
|
],
|
|
@@ -233,12 +270,15 @@ class _PageState extends State<SearchPage> with UserId {
|
|
|
// _model.queryValue(e);
|
|
|
},
|
|
|
child: Chip(
|
|
|
- labelPadding: const EdgeInsets.fromLTRB(16.0, 0, 16.0, 0),
|
|
|
+ labelPadding: const EdgeInsets.fromLTRB(
|
|
|
+ 16.0, 0, 16.0, 0),
|
|
|
label: Text("$e"),
|
|
|
- labelStyle: TextStyle(color: Color(0xff666666)),
|
|
|
+ labelStyle:
|
|
|
+ TextStyle(color: Color(0xff666666)),
|
|
|
backgroundColor: Colors.white,
|
|
|
shape: StadiumBorder(
|
|
|
- side: BorderSide(color: Color(0xffDCDCDC), width: 0.5),
|
|
|
+ side: BorderSide(
|
|
|
+ color: Color(0xffDCDCDC), width: 0.5),
|
|
|
),
|
|
|
));
|
|
|
}).toList(),
|
|
@@ -259,91 +299,301 @@ class _PageState extends State<SearchPage> with UserId {
|
|
|
Widget buildSuggestions(BuildContext context) {
|
|
|
return FutureBuilder(
|
|
|
future: _model.api.getPostList(kw: _model.searchValue),
|
|
|
- builder: (context, AsyncSnapshot<RespPage<Post>> snapshot) => snapshot.connectionState == ConnectionState.done
|
|
|
- ? snapshot.data.code == 0
|
|
|
- ? snapshot.data.pageResult.results.isEmpty
|
|
|
- ? Center(
|
|
|
- child: RequestErrorWidget(
|
|
|
- null,
|
|
|
- msg: "暂时找不到您想搜索的东西喔",
|
|
|
- ))
|
|
|
- : ListView.separated(
|
|
|
- itemBuilder: (context, index) {
|
|
|
- var item = snapshot.data.pageResult.results[index];
|
|
|
- return ListTile(
|
|
|
- title: Text(
|
|
|
- item.content,
|
|
|
- maxLines: 1,
|
|
|
- overflow: TextOverflow.ellipsis,
|
|
|
- ),
|
|
|
- onTap: () {
|
|
|
+ builder: (context, AsyncSnapshot<RespPage<Post>> snapshot) =>
|
|
|
+ snapshot.connectionState == ConnectionState.done
|
|
|
+ ? snapshot.data.code == 0
|
|
|
+ ? snapshot.data.pageResult.results.isEmpty
|
|
|
+ ? Center(
|
|
|
+ child: RequestErrorWidget(
|
|
|
+ null,
|
|
|
+ msg: "暂时找不到您想搜索的东西喔",
|
|
|
+ ))
|
|
|
+ : ListView.separated(
|
|
|
+ itemBuilder: (context, index) {
|
|
|
+ var item = snapshot.data.pageResult.results[index];
|
|
|
+ return ListTile(
|
|
|
+ title: Text(
|
|
|
+ item.content,
|
|
|
+ maxLines: 1,
|
|
|
+ overflow: TextOverflow.ellipsis,
|
|
|
+ ),
|
|
|
+ onTap: () {
|
|
|
// query = '老孟 $index';
|
|
|
- String value = item.content;
|
|
|
- _submitValue(value);
|
|
|
+ String value = item.content;
|
|
|
+ _submitValue(value);
|
|
|
|
|
|
- // NavigatorUtil.goSocialPostDetail(context, item);
|
|
|
+ // NavigatorUtil.goSocialPostDetail(context, item);
|
|
|
+ },
|
|
|
+ trailing: arrowRight(),
|
|
|
+ );
|
|
|
},
|
|
|
- trailing: arrowRight(),
|
|
|
- );
|
|
|
- },
|
|
|
- separatorBuilder: (context, index) {
|
|
|
- return Divider(
|
|
|
- height: 1,
|
|
|
- indent: 12,
|
|
|
- endIndent: 12,
|
|
|
- );
|
|
|
- },
|
|
|
- itemCount: snapshot.data.pageResult.results.length,
|
|
|
- )
|
|
|
- : Container()
|
|
|
- : Container(),
|
|
|
+ separatorBuilder: (context, index) {
|
|
|
+ return Divider(
|
|
|
+ height: 1,
|
|
|
+ indent: 12,
|
|
|
+ endIndent: 12,
|
|
|
+ );
|
|
|
+ },
|
|
|
+ itemCount: snapshot.data.pageResult.results.length,
|
|
|
+ )
|
|
|
+ : Container()
|
|
|
+ : Container(),
|
|
|
);
|
|
|
}
|
|
|
|
|
|
Widget buildResults(BuildContext context) {
|
|
|
- return p.ProviderWidget<SocialDetailModel>(
|
|
|
- model: _searchModel,
|
|
|
- autoDispose: false,
|
|
|
- builder: (_, model, __) {
|
|
|
- return EasyRefresh.custom(
|
|
|
- controller: model.refreshController,
|
|
|
- enableControlFinishRefresh: true,
|
|
|
- enableControlFinishLoad: true,
|
|
|
- onLoad: model.isIdle ? () => model.loadMore() : null,
|
|
|
- header: buildClassicalHeader(),
|
|
|
- footer: buildClassicalFooter(),
|
|
|
- slivers: <Widget>[
|
|
|
- if (model.isBusy)
|
|
|
- SliverToBoxAdapter(
|
|
|
- child: RequestLoadingWidget(),
|
|
|
- ),
|
|
|
- if (model.isEmpty)
|
|
|
- SliverToBoxAdapter(
|
|
|
- child: RequestErrorWidget(
|
|
|
- null,
|
|
|
- msg: "暂时找不到您想搜索的东西喔",
|
|
|
- assets: RequestErrorWidget.ASSETS_NO_MOTION,
|
|
|
+ return DefaultTabController(
|
|
|
+ length: 2,
|
|
|
+ child: Column(
|
|
|
+ children: <Widget>[
|
|
|
+ Container(
|
|
|
+ color: Colors.white,
|
|
|
+ height: tabHeader,
|
|
|
+ padding: EdgeInsets.symmetric(vertical: 8.0),
|
|
|
+ child: TabBar(
|
|
|
+ isScrollable: true,
|
|
|
+ indicatorPadding: EdgeInsets.symmetric(horizontal: 6),
|
|
|
+ indicatorWeight: 3,
|
|
|
+ tabs: <Widget>[
|
|
|
+ Tab(text: "帖子"),
|
|
|
+ Tab(text: "用户"),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ alignment: Alignment.centerLeft,
|
|
|
+ ),
|
|
|
+ Expanded(
|
|
|
+ child: TabBarView(
|
|
|
+ children: <Widget>[
|
|
|
+ p.ProviderWidget<SocialDetailModel>(
|
|
|
+ model: _searchModel,
|
|
|
+ autoDispose: false, // 自动 dispose
|
|
|
+ builder: (_, model, __) {
|
|
|
+ return EasyRefresh.custom(
|
|
|
+ controller: model.refreshController,
|
|
|
+ enableControlFinishRefresh: true,
|
|
|
+ enableControlFinishLoad: true,
|
|
|
+ onLoad: model.isIdle ? () => model.loadMore() : null,
|
|
|
+ header: buildClassicalHeader(),
|
|
|
+ footer: buildClassicalFooter(),
|
|
|
+ slivers: <Widget>[
|
|
|
+ if (model.isBusy)
|
|
|
+ SliverToBoxAdapter(
|
|
|
+ child: RequestLoadingWidget(),
|
|
|
+ ),
|
|
|
+ if (model.isEmpty)
|
|
|
+ SliverToBoxAdapter(
|
|
|
+ child: RequestErrorWidget(
|
|
|
+ null,
|
|
|
+ msg: "暂时找不到您想搜索的东西喔",
|
|
|
+ assets: RequestErrorWidget.ASSETS_NO_MOTION,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ SliverList(
|
|
|
+ delegate: SliverChildBuilderDelegate(
|
|
|
+ (context, index) {
|
|
|
+ Post post = model.list[index];
|
|
|
+ return PostWidget(
|
|
|
+ post,
|
|
|
+ _searchModel,
|
|
|
+ selfId == post.userId,
|
|
|
+ keyword: _controller.text,
|
|
|
+ highlight: true,
|
|
|
+ );
|
|
|
+ },
|
|
|
+ childCount: model.list.length,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ );
|
|
|
+ },
|
|
|
),
|
|
|
- ),
|
|
|
- if (model.isIdle)
|
|
|
- SliverList(
|
|
|
- delegate: SliverChildBuilderDelegate(
|
|
|
- (context, index) {
|
|
|
- Post post = model.list[index];
|
|
|
- return PostWidget(
|
|
|
- post,
|
|
|
- _searchModel,
|
|
|
- selfId == post.userId,
|
|
|
- keyword: _controller.text,
|
|
|
- highlight: true,
|
|
|
+ p.ProviderWidget<SimpleModel>(
|
|
|
+ model: simpleModel,
|
|
|
+ onModelReady: (model) => model.initData(),
|
|
|
+ autoDispose: false,
|
|
|
+ builder: (_, model, __) {
|
|
|
+ return EasyRefresh.custom(
|
|
|
+ firstRefresh: true,
|
|
|
+ controller: model.refreshController,
|
|
|
+ enableControlFinishRefresh: true,
|
|
|
+ enableControlFinishLoad: true,
|
|
|
+ onLoad: model.isIdle ? () => model.initData() : null,
|
|
|
+ header: buildClassicalHeader(),
|
|
|
+ footer: buildClassicalFooter(),
|
|
|
+ slivers: <Widget>[
|
|
|
+ if (model.isBusy)
|
|
|
+ SliverToBoxAdapter(
|
|
|
+ child: RequestLoadingWidget(),
|
|
|
+ ),
|
|
|
+ if (model.isEmpty || model.isError)
|
|
|
+ SliverToBoxAdapter(
|
|
|
+ child: RequestErrorWidget(
|
|
|
+ null,
|
|
|
+ msg: _model.searchValue == ""
|
|
|
+ ? "请输入搜索的关键字1"
|
|
|
+ : "暂无相关用户~",
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ if (model.isIdle)
|
|
|
+ SliverList(
|
|
|
+ delegate: SliverChildBuilderDelegate(
|
|
|
+ (context, index) {
|
|
|
+ return _buildItem(model.list[index]);
|
|
|
+ },
|
|
|
+ childCount: model.list.length,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
);
|
|
|
},
|
|
|
- childCount: model.list.length,
|
|
|
),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ )
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ Widget _buildItem(UserInfo user) {
|
|
|
+ Widget child = Row(
|
|
|
+ children: <Widget>[
|
|
|
+ CircleAvatar(
|
|
|
+ backgroundImage: userAvatarProvider(user?.avatar),
|
|
|
+ radius: 22,
|
|
|
+ ),
|
|
|
+ SizedBox(
|
|
|
+ width: 8,
|
|
|
+ ),
|
|
|
+ Expanded(
|
|
|
+ child: Column(
|
|
|
+ crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
+ children: <Widget>[
|
|
|
+ Text(
|
|
|
+ "${user?.name}",
|
|
|
+ style: Theme.of(context).textTheme.headline3,
|
|
|
),
|
|
|
- ],
|
|
|
- );
|
|
|
- },
|
|
|
+ SizedBox(
|
|
|
+ height: 4,
|
|
|
+ ),
|
|
|
+ Text(
|
|
|
+ "ID: ${user?.id}",
|
|
|
+ style: Theme.of(context).textTheme.bodyText2,
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ user.isFriend()
|
|
|
+ ? Container(
|
|
|
+ width: 64,
|
|
|
+ height: 30,
|
|
|
+ margin: EdgeInsets.only(left: 8.0),
|
|
|
+ alignment: Alignment.center,
|
|
|
+ child: Text(
|
|
|
+ "已关注",
|
|
|
+ strutStyle: fixedLine,
|
|
|
+ style: Theme.of(context)
|
|
|
+ .textTheme
|
|
|
+ .bodyText2
|
|
|
+ .copyWith(color: Theme.of(context).accentColor),
|
|
|
+ ),
|
|
|
+ )
|
|
|
+ : GestureDetector(
|
|
|
+ child: Container(
|
|
|
+ width: 64,
|
|
|
+ height: 30,
|
|
|
+ margin: EdgeInsets.only(left: 8.0),
|
|
|
+ alignment: Alignment.center,
|
|
|
+ child: Text(
|
|
|
+ "关注",
|
|
|
+ strutStyle: fixedLine,
|
|
|
+ style: Theme.of(context)
|
|
|
+ .textTheme
|
|
|
+ .bodyText2
|
|
|
+ .copyWith(color: Theme.of(context).accentColor),
|
|
|
+ ),
|
|
|
+ decoration: BoxDecoration(
|
|
|
+ borderRadius: BorderRadius.circular(20),
|
|
|
+ border: Border.all(
|
|
|
+ color: Theme.of(context).accentColor,
|
|
|
+ width: .5,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ onTap: () async {
|
|
|
+ if (user.isFriend()) return;
|
|
|
+ await request(context, () async {
|
|
|
+ var resp = await simpleModel.api
|
|
|
+ .userFollow(uid: user?.id)
|
|
|
+ .catchError((onError) {});
|
|
|
+ if (resp?.code == 0) {
|
|
|
+ ToastUtil.show("关注成功");
|
|
|
+ setState(() {
|
|
|
+ user.followStatus = "followed";
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ )
|
|
|
+ ],
|
|
|
+ );
|
|
|
+ return Column(
|
|
|
+ children: <Widget>[
|
|
|
+ Padding(
|
|
|
+ padding: const EdgeInsets.all(12.0),
|
|
|
+ child: InkWell(
|
|
|
+ onTap: () async {
|
|
|
+ List<UserFriend> friends = simpleModel.list
|
|
|
+ .map((e) => UserFriend(
|
|
|
+ uid: user.id,
|
|
|
+ socialInfo: user,
|
|
|
+ isFriends: user.isFriend() ? "1" : "0"))
|
|
|
+ .toList();
|
|
|
+ await NavigatorUtil.goPage(
|
|
|
+ context,
|
|
|
+ (context) => UserDetailPage(
|
|
|
+ PostUser(
|
|
|
+ id: "${user?.id}",
|
|
|
+ name: user?.name,
|
|
|
+ avatar: user?.avatar),
|
|
|
+ userFriends: friends));
|
|
|
+ user.followStatus = friends
|
|
|
+ .firstWhere((element) => element.uid == user.id)
|
|
|
+ ?.isFriends ==
|
|
|
+ "1"
|
|
|
+ ? "followed"
|
|
|
+ : "none";
|
|
|
+ setState(() {});
|
|
|
+ },
|
|
|
+ child: child),
|
|
|
+ ),
|
|
|
+ Divider(
|
|
|
+ height: 1,
|
|
|
+ )
|
|
|
+ ],
|
|
|
);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+class StickyTabBarDelegate extends SliverPersistentHeaderDelegate {
|
|
|
+ final TabBar child;
|
|
|
+
|
|
|
+ StickyTabBarDelegate({@required this.child});
|
|
|
+
|
|
|
+ @override
|
|
|
+ Widget build(
|
|
|
+ BuildContext context, double shrinkOffset, bool overlapsContent) {
|
|
|
+ return this.child;
|
|
|
+ }
|
|
|
+
|
|
|
+ @override
|
|
|
+ double get maxExtent => this.child.preferredSize.height;
|
|
|
+
|
|
|
+ @override
|
|
|
+ double get minExtent => this.child.preferredSize.height;
|
|
|
+
|
|
|
+ @override
|
|
|
+ bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+}
|