choose_theme.dart 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469
  1. import 'dart:async';
  2. import 'dart:convert';
  3. import 'package:flutter/material.dart';
  4. import 'package:flutter_svg/svg.dart';
  5. import 'package:get/get.dart';
  6. import 'package:link/model/model.dart';
  7. import 'package:link/utils/global.dart';
  8. import 'package:link/view/component/link_btn.dart';
  9. import '../constants.dart';
  10. import '../utils/api.dart';
  11. import '../utils/http_utils.dart';
  12. import '../utils/size_fit.dart';
  13. import 'component/top_container.dart';
  14. import 'home_content.dart';
  15. class ChooseTheme extends StatefulWidget {
  16. const ChooseTheme({Key? key}) : super(key: key);
  17. @override
  18. State<ChooseTheme> createState() => _ChooseThemeState();
  19. }
  20. class _ChooseThemeState extends State<ChooseTheme> {
  21. int selGroup = 0;
  22. String selId = "";
  23. int column = 6;
  24. List groups = [];
  25. var current;
  26. @override
  27. void initState() {
  28. // TODO: implement initState
  29. getGroup();
  30. super.initState();
  31. }
  32. Future getGroup() async {
  33. if (Global().userBean == null) {
  34. Timer(const Duration(seconds: 1), () {
  35. getGroup();
  36. });
  37. return;
  38. }
  39. var data = await HttpUtils.get(Api.themeStyles);
  40. setState(() {
  41. column = data['column'];
  42. groups = data['themes'];
  43. selId = Global().themeId;
  44. for (int i = 0; i < groups.length; i++) {
  45. List array = groups[i]['categories'];
  46. for (var e in array) {
  47. List themes = e['styles'];
  48. for (var theme in themes) {
  49. if (theme['id'] == selId) {
  50. current = theme['styles'];
  51. selGroup = i;
  52. }
  53. }
  54. }
  55. }
  56. });
  57. }
  58. Future save() async {
  59. var data =
  60. await HttpUtils.post(Api.userThemes, data: {'theme_style_id': selId});
  61. Get.back();
  62. }
  63. @override
  64. void dispose() {
  65. // TODO: implement dispose
  66. super.dispose();
  67. }
  68. preview() {
  69. Get.toNamed('/home_preview', parameters: {"style": jsonEncode(current)});
  70. }
  71. category() {
  72. return SingleChildScrollView(
  73. scrollDirection: Axis.horizontal,
  74. child: Row(
  75. children: [
  76. SizedBox(
  77. width: 20.px,
  78. ),
  79. ...List<Widget>.generate(groups.length, (i) {
  80. return Container(
  81. margin: EdgeInsets.only(right: 12.px),
  82. child: GestureDetector(
  83. onTap: () {
  84. setState(() {
  85. selGroup = i;
  86. });
  87. },
  88. child: Container(
  89. height: 32.px,
  90. alignment: Alignment.center,
  91. padding: EdgeInsets.only(left: 12.px, right: 12.px),
  92. child: Text(
  93. groups[i]['name'],
  94. style: TextStyle(
  95. fontSize: 14.px,
  96. color: selGroup == i
  97. ? kThemeColor
  98. : const Color(0xFF74747A)),
  99. ),
  100. decoration: BoxDecoration(
  101. borderRadius: BorderRadius.circular(16.px),
  102. border: Border.all(
  103. color:
  104. selGroup == i ? kThemeColor : Colors.transparent,
  105. width: 2.px)),
  106. ),
  107. ),
  108. );
  109. }),
  110. ],
  111. ),
  112. );
  113. }
  114. content() {
  115. return SingleChildScrollView(
  116. child: Column(children: [
  117. ...List<Widget>.generate(groups[selGroup]['categories'].length, (i) {
  118. var categoryObj = groups[selGroup]['categories'][i];
  119. return Column(
  120. crossAxisAlignment: CrossAxisAlignment.start,
  121. mainAxisAlignment: MainAxisAlignment.start,
  122. children: [
  123. SizedBox(
  124. height: 20.px,
  125. ),
  126. Row(
  127. children: [
  128. SizedBox(
  129. width: 20.px,
  130. ),
  131. Text(
  132. categoryObj['name'],
  133. style: TextStyle(
  134. color: const Color(0xFF74747A),
  135. fontSize: 12.px,
  136. fontWeight: FontWeight.bold),
  137. ),
  138. SizedBox(
  139. width: 5.px,
  140. ),
  141. Expanded(
  142. child: Container(
  143. height: 1.px,
  144. color: const Color(0xFF2C2C2E),
  145. )),
  146. SizedBox(
  147. width: 20.px,
  148. )
  149. ],
  150. ),
  151. SizedBox(
  152. height: 6.px,
  153. ),
  154. SingleChildScrollView(
  155. scrollDirection: Axis.horizontal,
  156. child: Row(
  157. crossAxisAlignment: CrossAxisAlignment.start,
  158. mainAxisAlignment: MainAxisAlignment.start,
  159. children: [
  160. SizedBox(
  161. width: 18.px,
  162. ),
  163. ...List<Widget>.generate(categoryObj['styles'].length,
  164. (j) {
  165. var objTheme = categoryObj['styles'][j];
  166. return GestureDetector(
  167. onTap: () {
  168. setState(() {
  169. selId = objTheme['id'];
  170. current = objTheme['styles'];
  171. });
  172. },
  173. child: Container(
  174. margin: EdgeInsets.only(
  175. right: categoryObj['styles'].length > 4
  176. ? 12.px
  177. : 22.px),
  178. child: item(
  179. selId == objTheme['id'], objTheme['styles']),
  180. ),
  181. );
  182. }),
  183. ],
  184. ))
  185. ],
  186. );
  187. }),
  188. ]),
  189. );
  190. }
  191. item(bool hasChoose, style) {
  192. double scale = 60 / 375.0;
  193. double height = MediaQuery.of(context).size.height * 60 / 375.0 + 0.2;
  194. return Column(
  195. children: [
  196. Container(
  197. width: 68.px,
  198. height: height + 8.px, //124.px,
  199. alignment: Alignment.center,
  200. decoration: BoxDecoration(
  201. borderRadius: BorderRadius.circular(9.px),
  202. color: const Color(0xFF131314),
  203. border: Border.all(
  204. color: hasChoose ? kThemeColor : Colors.transparent,
  205. width: 2.px)),
  206. child: Container(
  207. width: 60.px,
  208. height: height,
  209. // height: 116.px,
  210. decoration: BoxDecoration(
  211. // color: const Color(0xFFB3B3B3),
  212. borderRadius: BorderRadius.circular(6.px),
  213. ),
  214. child: ClipRRect(
  215. borderRadius: BorderRadius.circular(6.px),
  216. child: HomeContent(
  217. userBean: Global().userBean!,
  218. styles: style,
  219. socials: Global().socials!,
  220. scale: scale,
  221. isPreview: true,
  222. ),
  223. ),
  224. ),
  225. ),
  226. // if (hasChoose)
  227. Container(
  228. width: 20.px,
  229. height: 20.px,
  230. transform: Matrix4.translationValues(0, -10.px, 0),
  231. decoration: hasChoose
  232. ? const BoxDecoration(
  233. image: DecorationImage(
  234. image: AssetImage('assets/images/checked.png')))
  235. : const BoxDecoration(color: Colors.transparent))
  236. ],
  237. );
  238. }
  239. @override
  240. Widget build(BuildContext context) {
  241. SizeFit.initialize(context);
  242. if (groups.isEmpty) {
  243. return Container(
  244. decoration: const BoxDecoration(
  245. gradient: LinearGradient(
  246. begin: Alignment.topCenter,
  247. end: Alignment.bottomCenter,
  248. colors: [Color(0xFF131314), Color(0xFFD5D5E0)])),
  249. );
  250. }
  251. UserBean bean = Global().userBean!;
  252. return Material(
  253. color: kBgColor,
  254. child: TopContainer(
  255. child: Stack(children: [
  256. Positioned(
  257. child: Container(
  258. decoration: const BoxDecoration(
  259. gradient: LinearGradient(
  260. begin: Alignment.topCenter,
  261. end: Alignment.bottomCenter,
  262. colors: [Color(0xFF131314), Color(0xFFD5D5E0)])),
  263. )),
  264. Container(
  265. width: 375.px,
  266. height: 72.px,
  267. padding: EdgeInsets.only(left: 20.px, right: 20.px),
  268. child: Row(
  269. children: [
  270. Expanded(
  271. child: GestureDetector(
  272. onTap: () {
  273. Get.back();
  274. },
  275. child: Text(
  276. '退出编辑',
  277. style: TextStyle(
  278. color: const Color(0x99FFFFFF), fontSize: 14.px),
  279. )),
  280. ),
  281. GestureDetector(
  282. onTap: () {
  283. preview();
  284. },
  285. child: SvgPicture.asset(
  286. 'assets/icons/preview.svg',
  287. color: Colors.white,
  288. ),
  289. )
  290. ],
  291. ),
  292. ),
  293. Column(
  294. children: [
  295. SizedBox(
  296. width: 375.px,
  297. height: 0.px,
  298. ),
  299. Container(
  300. width: MediaQuery.of(context).size.width * 0.2,
  301. height: MediaQuery.of(context).size.height * 0.2,
  302. margin: EdgeInsets.only(top: 25.px, bottom: 25.px),
  303. decoration: BoxDecoration(
  304. borderRadius: BorderRadius.circular(4.px),
  305. boxShadow: [
  306. BoxShadow(
  307. color: const Color(0xB3000000),
  308. blurRadius: 24.px,
  309. offset: Offset(0, 12.px))
  310. ]),
  311. child: ClipRRect(
  312. borderRadius: BorderRadius.circular(4.px),
  313. child: HomeContent(
  314. userBean: Global().userBean!,
  315. styles: current,
  316. socials: Global().socials!,
  317. scale: 0.2,
  318. isPreview: true,
  319. ),
  320. ),
  321. ),
  322. Expanded(
  323. child: ClipRRect(
  324. borderRadius: BorderRadius.only(
  325. topLeft: Radius.circular(24.px),
  326. topRight: Radius.circular(24.px)),
  327. child: Container(
  328. decoration: BoxDecoration(
  329. color: const Color(0xFF131314),
  330. borderRadius: BorderRadius.only(
  331. topLeft: Radius.circular(24.px),
  332. topRight: Radius.circular(24.px))),
  333. child: Stack(children: [
  334. Positioned(
  335. left: 0,
  336. right: 0,
  337. top: 56.px,
  338. bottom: 74.px,
  339. child: content()),
  340. Container(
  341. height: 68.px,
  342. padding: EdgeInsets.only(top: 14.px),
  343. alignment: Alignment.topLeft,
  344. decoration: BoxDecoration(
  345. gradient: const LinearGradient(
  346. begin: Alignment.topCenter,
  347. end: Alignment.bottomCenter,
  348. colors: [
  349. Color(0xFF131314),
  350. Color(0xFF131314),
  351. Color(0x00131314),
  352. ],
  353. stops: [
  354. 0,
  355. 0.82,
  356. 1
  357. ]),
  358. borderRadius: BorderRadius.only(
  359. topLeft: Radius.circular(24.px),
  360. topRight: Radius.circular(24.px))),
  361. child: SizedBox(width: 375.px, child: category()),
  362. ),
  363. Positioned(
  364. left: 0,
  365. top: 0.px,
  366. bottom: 0.px,
  367. width: 20.px,
  368. child: Container(
  369. width: 20.px,
  370. decoration: const BoxDecoration(
  371. gradient: LinearGradient(
  372. begin: Alignment.centerLeft,
  373. end: Alignment.centerRight,
  374. colors: [
  375. Color(0xFF131314),
  376. Color(0x00131314),
  377. ]),
  378. )),
  379. ),
  380. Positioned(
  381. right: 0,
  382. top: 0.px, //68.px,
  383. bottom: 0.px,
  384. width: 20.px,
  385. child: Container(
  386. width: 20.px,
  387. decoration: const BoxDecoration(
  388. gradient: LinearGradient(
  389. begin: Alignment.centerRight,
  390. end: Alignment.centerLeft,
  391. colors: [
  392. Color(0xFF131314),
  393. Color(0x00131314),
  394. ]),
  395. )),
  396. ),
  397. Positioned(
  398. left: 0,
  399. right: 0,
  400. bottom: 0,
  401. height: 110.px,
  402. child: Container(
  403. height: 110.px,
  404. padding: EdgeInsets.only(top: 30.px),
  405. alignment: Alignment.topCenter,
  406. decoration: const BoxDecoration(
  407. gradient: LinearGradient(
  408. begin: Alignment.bottomCenter,
  409. end: Alignment.topCenter,
  410. colors: [
  411. Color(0xFF131314),
  412. Color(0xFF131314),
  413. Color(0x00131314),
  414. ],
  415. stops: [
  416. 0,
  417. 0.81,
  418. 1
  419. ]),
  420. ),
  421. child: Row(
  422. children: [
  423. GestureDetector(
  424. child: Container(
  425. width: 88.px,
  426. child: SvgPicture.asset(
  427. 'assets/icons/filter.svg',
  428. width: 24.px,
  429. height: 24.px,
  430. color: Colors.white,
  431. ),
  432. ),
  433. ),
  434. LinkButton(
  435. title: '保存',
  436. disable: false,
  437. isBlack: false,
  438. btnWidth: 255.px,
  439. btnHeight: 48.px,
  440. callback: () {
  441. save();
  442. }),
  443. ],
  444. ),
  445. ))
  446. ]),
  447. ),
  448. ))
  449. ],
  450. )
  451. ])));
  452. }
  453. }