mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-06-18 16:30:11 +08:00
63
lib/common/widgets/flutter/time_picker.dart
Normal file
63
lib/common/widgets/flutter/time_picker.dart
Normal file
@@ -0,0 +1,63 @@
|
||||
// Copyright 2014 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
Future<TimeOfDay?> showTimePicker({
|
||||
required BuildContext context,
|
||||
required TimeOfDay initialTime,
|
||||
TransitionBuilder? builder,
|
||||
bool barrierDismissible = true,
|
||||
Color? barrierColor,
|
||||
String? barrierLabel,
|
||||
bool useRootNavigator = true,
|
||||
TimePickerEntryMode initialEntryMode = TimePickerEntryMode.dial,
|
||||
String? cancelText,
|
||||
String? confirmText,
|
||||
String? helpText,
|
||||
String? errorInvalidText,
|
||||
String? hourLabelText,
|
||||
String? minuteLabelText,
|
||||
RouteSettings? routeSettings,
|
||||
EntryModeChangeCallback? onEntryModeChanged,
|
||||
Offset? anchorPoint,
|
||||
Orientation? orientation,
|
||||
Icon? switchToInputEntryModeIcon,
|
||||
Icon? switchToTimerEntryModeIcon,
|
||||
bool emptyInitialInput = false,
|
||||
BoxConstraints? constraints,
|
||||
}) {
|
||||
assert(debugCheckHasMaterialLocalizations(context));
|
||||
|
||||
final Widget dialog = DialogTheme(
|
||||
data: const DialogThemeData(constraints: BoxConstraints(minWidth: 280.0)),
|
||||
child: TimePickerDialog(
|
||||
initialTime: initialTime,
|
||||
initialEntryMode: initialEntryMode,
|
||||
cancelText: cancelText,
|
||||
confirmText: confirmText,
|
||||
helpText: helpText,
|
||||
errorInvalidText: errorInvalidText,
|
||||
hourLabelText: hourLabelText,
|
||||
minuteLabelText: minuteLabelText,
|
||||
orientation: orientation,
|
||||
onEntryModeChanged: onEntryModeChanged,
|
||||
switchToInputEntryModeIcon: switchToInputEntryModeIcon,
|
||||
switchToTimerEntryModeIcon: switchToTimerEntryModeIcon,
|
||||
emptyInitialInput: emptyInitialInput,
|
||||
),
|
||||
);
|
||||
return showDialog<TimeOfDay>(
|
||||
context: context,
|
||||
barrierDismissible: barrierDismissible,
|
||||
barrierColor: barrierColor,
|
||||
barrierLabel: barrierLabel,
|
||||
useRootNavigator: useRootNavigator,
|
||||
builder: (BuildContext context) {
|
||||
return builder == null ? dialog : builder(context, dialog);
|
||||
},
|
||||
routeSettings: routeSettings,
|
||||
anchorPoint: anchorPoint,
|
||||
);
|
||||
}
|
||||
@@ -327,7 +327,12 @@ class _CustomGridViewDelegate extends MultiChildLayoutDelegate {
|
||||
|
||||
@override
|
||||
void performLayout(Size size) {
|
||||
final constraints = BoxConstraints.expand(width: width, height: height);
|
||||
final constraints = BoxConstraints(
|
||||
minWidth: width,
|
||||
maxWidth: width,
|
||||
minHeight: height,
|
||||
maxHeight: height,
|
||||
);
|
||||
for (int i = 0; i < itemCount; i++) {
|
||||
layoutChild(i, constraints);
|
||||
positionChild(
|
||||
|
||||
@@ -124,9 +124,11 @@ class _InteractiveviewerGalleryState extends State<InteractiveviewerGallery>
|
||||
..removeListener(listener)
|
||||
..dispose();
|
||||
_transformationController.dispose();
|
||||
for (final item in widget.sources) {
|
||||
if (item.sourceType == SourceType.networkImage) {
|
||||
CachedNetworkImageProvider(_getActualUrl(item.url)).evict();
|
||||
if (widget.quality != _quality) {
|
||||
for (final item in widget.sources) {
|
||||
if (item.sourceType == SourceType.networkImage) {
|
||||
CachedNetworkImageProvider(_getActualUrl(item.url)).evict();
|
||||
}
|
||||
}
|
||||
}
|
||||
super.dispose();
|
||||
|
||||
@@ -98,7 +98,7 @@ class ActionPanel extends StatelessWidget {
|
||||
},
|
||||
child: Text(
|
||||
like.count != null ? NumUtils.numFormat(like.count) : '点赞',
|
||||
key: ValueKey<String>(like.count?.toString() ?? '点赞'),
|
||||
key: ValueKey<int?>(like.count),
|
||||
style: TextStyle(color: like.status! ? primary : outline),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -8,6 +8,7 @@ import 'package:PiliPlus/common/widgets/flutter/draggable_sheet/draggable_scroll
|
||||
as dyn_sheet;
|
||||
import 'package:PiliPlus/common/widgets/flutter/text_field/controller.dart';
|
||||
import 'package:PiliPlus/common/widgets/flutter/text_field/text_field.dart';
|
||||
import 'package:PiliPlus/common/widgets/flutter/time_picker.dart';
|
||||
import 'package:PiliPlus/common/widgets/pair.dart';
|
||||
import 'package:PiliPlus/http/dynamics.dart';
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
@@ -31,7 +32,8 @@ import 'package:PiliPlus/utils/extension/context_ext.dart';
|
||||
import 'package:PiliPlus/utils/extension/iterable_ext.dart';
|
||||
import 'package:PiliPlus/utils/grid.dart';
|
||||
import 'package:PiliPlus/utils/request_utils.dart';
|
||||
import 'package:flutter/material.dart' hide DraggableScrollableSheet;
|
||||
import 'package:flutter/material.dart'
|
||||
hide DraggableScrollableSheet, showTimePicker;
|
||||
import 'package:flutter/services.dart' show LengthLimitingTextInputFormatter;
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
import 'package:get/get.dart';
|
||||
@@ -280,46 +282,45 @@ class _CreateDynPanelState extends CommonRichTextPubPageState<CreateDynPanel> {
|
||||
|
||||
Widget _buildImageList(ThemeData theme) => SizedBox(
|
||||
height: 100,
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: Obx(
|
||||
() => Row(
|
||||
spacing: 10,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
...List.generate(
|
||||
imageList.length,
|
||||
(index) => buildImage(index, 100),
|
||||
),
|
||||
if (imageList.length != limit)
|
||||
Builder(
|
||||
builder: (context) {
|
||||
const borderRadius = StyleString.mdRadius;
|
||||
return Material(
|
||||
borderRadius: borderRadius,
|
||||
child: InkWell(
|
||||
borderRadius: borderRadius,
|
||||
onTap: () => onPickImage(() {
|
||||
if (imageList.isNotEmpty && !enablePublish.value) {
|
||||
enablePublish.value = true;
|
||||
}
|
||||
}),
|
||||
child: Ink(
|
||||
width: 100,
|
||||
height: 100,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: borderRadius,
|
||||
color: theme.colorScheme.secondaryContainer,
|
||||
),
|
||||
child: const Center(child: Icon(Icons.add, size: 35)),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
child: Obx(
|
||||
() => CustomScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
slivers: [
|
||||
const SliverToBoxAdapter(child: SizedBox(width: 16)),
|
||||
if (imageList.isNotEmpty)
|
||||
SliverPadding(
|
||||
padding: const .only(right: 10),
|
||||
sliver: SliverList.separated(
|
||||
itemCount: imageList.length,
|
||||
itemBuilder: (context, index) => buildImage(index, 100),
|
||||
separatorBuilder: (_, _) => const SizedBox(width: 10),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (imageList.length != limit)
|
||||
SliverToBoxAdapter(
|
||||
child: Material(
|
||||
borderRadius: StyleString.mdRadius,
|
||||
child: InkWell(
|
||||
borderRadius: StyleString.mdRadius,
|
||||
onTap: () => onPickImage(() {
|
||||
if (imageList.isNotEmpty && !enablePublish.value) {
|
||||
enablePublish.value = true;
|
||||
}
|
||||
}),
|
||||
child: Ink(
|
||||
width: 100,
|
||||
height: 100,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: StyleString.mdRadius,
|
||||
color: theme.colorScheme.secondaryContainer,
|
||||
),
|
||||
child: const Center(child: Icon(Icons.add, size: 35)),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SliverToBoxAdapter(child: SizedBox(width: 16)),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -629,18 +630,18 @@ class _CreateDynPanelState extends CommonRichTextPubPageState<CreateDynPanel> {
|
||||
}
|
||||
|
||||
final color = theme.colorScheme.onSurfaceVariant;
|
||||
late final gridDelegate = SliverGridDelegateWithExtentAndRatio(
|
||||
maxCrossAxisExtent: 65,
|
||||
mainAxisSpacing: 12,
|
||||
crossAxisSpacing: 12,
|
||||
mainAxisExtent: 25,
|
||||
);
|
||||
|
||||
return SizedBox(
|
||||
height: height,
|
||||
child: GridView(
|
||||
physics: const ClampingScrollPhysics(),
|
||||
padding: const EdgeInsets.only(left: 12, bottom: 12, right: 12),
|
||||
gridDelegate: gridDelegate,
|
||||
gridDelegate: SliverGridDelegateWithExtentAndRatio(
|
||||
maxCrossAxisExtent: 65,
|
||||
mainAxisSpacing: 12,
|
||||
crossAxisSpacing: 12,
|
||||
mainAxisExtent: 25,
|
||||
),
|
||||
children: [
|
||||
item(
|
||||
onTap: _onReserve,
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import 'package:PiliPlus/common/widgets/flutter/time_picker.dart';
|
||||
import 'package:PiliPlus/pages/dynamics_create_reserve/controller.dart';
|
||||
import 'package:PiliPlus/utils/date_utils.dart';
|
||||
import 'package:PiliPlus/utils/utils.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/material.dart' hide showTimePicker;
|
||||
import 'package:flutter/services.dart'
|
||||
show TextInputFormatter, LengthLimitingTextInputFormatter;
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'dart:io' show File;
|
||||
|
||||
import 'package:PiliPlus/common/widgets/button/icon_button.dart';
|
||||
import 'package:PiliPlus/common/widgets/flutter/time_picker.dart';
|
||||
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
|
||||
import 'package:PiliPlus/models/dynamics/vote_model.dart';
|
||||
import 'package:PiliPlus/pages/dynamics_create_vote/controller.dart';
|
||||
@@ -9,7 +10,7 @@ import 'package:PiliPlus/utils/extension/file_ext.dart';
|
||||
import 'package:PiliPlus/utils/platform_utils.dart';
|
||||
import 'package:PiliPlus/utils/utils.dart';
|
||||
import 'package:easy_debounce/easy_throttle.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/material.dart' hide showTimePicker;
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
@@ -69,7 +69,7 @@ class DynamicDetailController extends CommonDynController {
|
||||
action: action,
|
||||
);
|
||||
if (res.isSuccess) {
|
||||
await Future.delayed(const Duration(milliseconds: 500), () {
|
||||
Future.delayed(const Duration(milliseconds: 500), () {
|
||||
if (!isClosed) {
|
||||
onReload();
|
||||
}
|
||||
|
||||
@@ -68,6 +68,7 @@ class _EmotePanelState extends State<EmotePanel>
|
||||
final size = flag ? 40.0 : 60.0;
|
||||
final isTextEmote = e.type == 4;
|
||||
return GridView.builder(
|
||||
physics: const ClampingScrollPhysics(),
|
||||
padding: const EdgeInsets.only(
|
||||
left: 12,
|
||||
right: 12,
|
||||
|
||||
@@ -174,9 +174,11 @@ class _CreateFavPageState extends State<CreateFavPage> {
|
||||
final leadingStyle = const TextStyle(fontSize: 14);
|
||||
|
||||
Widget _buildBody(ThemeData theme) => SingleChildScrollView(
|
||||
padding: .only(bottom: MediaQuery.viewPaddingOf(context).bottom + 25),
|
||||
child: Column(
|
||||
spacing: 12,
|
||||
children: [
|
||||
if (_attr == null || !FavUtils.isDefaultFav(_attr!)) ...[
|
||||
if (_attr == null || !FavUtils.isDefaultFav(_attr!))
|
||||
Builder(
|
||||
builder: (context) {
|
||||
return ListTile(
|
||||
@@ -260,8 +262,6 @@ class _CreateFavPageState extends State<CreateFavPage> {
|
||||
);
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
],
|
||||
ListTile(
|
||||
tileColor: theme.colorScheme.onInverseSurface,
|
||||
title: Row(
|
||||
@@ -318,8 +318,7 @@ class _CreateFavPageState extends State<CreateFavPage> {
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
if (_attr == null || !FavUtils.isDefaultFav(_attr!)) ...[
|
||||
if (_attr == null || !FavUtils.isDefaultFav(_attr!))
|
||||
ListTile(
|
||||
tileColor: theme.colorScheme.onInverseSurface,
|
||||
title: Row(
|
||||
@@ -362,8 +361,6 @@ class _CreateFavPageState extends State<CreateFavPage> {
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
],
|
||||
Builder(
|
||||
builder: (context) {
|
||||
void onTap() {
|
||||
@@ -389,7 +386,6 @@ class _CreateFavPageState extends State<CreateFavPage> {
|
||||
);
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
@@ -75,6 +75,7 @@ class _LiveEmotePanelState extends State<LiveEmotePanel>
|
||||
final width = widthFac * 38;
|
||||
final height = heightFac * 38;
|
||||
return GridView.builder(
|
||||
physics: const ClampingScrollPhysics(),
|
||||
padding: const EdgeInsets.only(
|
||||
left: 12,
|
||||
right: 12,
|
||||
|
||||
@@ -66,13 +66,17 @@ class MemberDynamicsController
|
||||
: DynamicsHttp.setTop(dynamicId: dynamicId));
|
||||
if (res.isSuccess) {
|
||||
List<DynamicItemModel> list = loadingState.value.data!;
|
||||
list[0].modules.moduleTag = null;
|
||||
list[0].modules
|
||||
..moduleTag = null
|
||||
..moduleAuthor?.isTop = false;
|
||||
if (isTop) {
|
||||
loadingState.refresh();
|
||||
SmartDialog.showToast('取消置顶成功');
|
||||
} else {
|
||||
final item = list.firstWhere((item) => item.idStr == dynamicId);
|
||||
item.modules.moduleTag = ModuleTag(text: '置顶');
|
||||
item.modules
|
||||
..moduleTag = ModuleTag(text: '置顶')
|
||||
..moduleAuthor?.isTop = true;
|
||||
list
|
||||
..remove(item)
|
||||
..insert(0, item);
|
||||
|
||||
@@ -20,13 +20,14 @@ class _ExtraSettingState extends State<ExtraSetting> {
|
||||
return Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
appBar: showAppBar ? AppBar(title: const Text('其它设置')) : null,
|
||||
body: ListView(
|
||||
body: ListView.builder(
|
||||
padding: EdgeInsets.only(
|
||||
left: showAppBar ? padding.left : 0,
|
||||
right: showAppBar ? padding.right : 0,
|
||||
bottom: padding.bottom + 100,
|
||||
),
|
||||
children: settings.map((item) => item.widget).toList(),
|
||||
itemCount: settings.length,
|
||||
itemBuilder: (context, index) => settings[index].widget,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -20,13 +20,14 @@ class _PlaySettingState extends State<PlaySetting> {
|
||||
return Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
appBar: showAppBar ? AppBar(title: const Text('播放器设置')) : null,
|
||||
body: ListView(
|
||||
body: ListView.builder(
|
||||
padding: EdgeInsets.only(
|
||||
left: showAppBar ? padding.left : 0,
|
||||
right: showAppBar ? padding.right : 0,
|
||||
bottom: padding.bottom + 100,
|
||||
),
|
||||
children: settings.map((item) => item.widget).toList(),
|
||||
itemCount: settings.length,
|
||||
itemBuilder: (context, index) => settings[index].widget,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -20,13 +20,14 @@ class _StyleSettingState extends State<StyleSetting> {
|
||||
return Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
appBar: showAppBar ? AppBar(title: const Text('外观设置')) : null,
|
||||
body: ListView(
|
||||
body: ListView.builder(
|
||||
padding: EdgeInsets.only(
|
||||
left: showAppBar ? padding.left : 0,
|
||||
right: showAppBar ? padding.right : 0,
|
||||
bottom: padding.bottom + 100,
|
||||
),
|
||||
children: settings.map((item) => item.widget).toList(),
|
||||
itemCount: settings.length,
|
||||
itemBuilder: (context, index) => settings[index].widget,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -20,13 +20,14 @@ class _VideoSettingState extends State<VideoSetting> {
|
||||
return Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
appBar: showAppBar ? AppBar(title: const Text('音视频设置')) : null,
|
||||
body: ListView(
|
||||
body: ListView.builder(
|
||||
padding: EdgeInsets.only(
|
||||
left: showAppBar ? padding.left : 0,
|
||||
right: showAppBar ? padding.right : 0,
|
||||
bottom: padding.bottom + 100,
|
||||
),
|
||||
children: settings.map((item) => item.widget).toList(),
|
||||
itemCount: settings.length,
|
||||
itemBuilder: (context, index) => settings[index].widget,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -247,7 +247,7 @@ class _CdnSelectDialogState extends State<CdnSelectDialog> {
|
||||
valueListenable: item,
|
||||
builder: (context, value, _) {
|
||||
return Text(
|
||||
item.value ?? '---',
|
||||
value ?? '---',
|
||||
style: const TextStyle(fontSize: 13),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
|
||||
@@ -66,7 +66,7 @@ class _SettingsSearchPageState
|
||||
onPressed: () {
|
||||
if (_textEditingController.text.isNotEmpty) {
|
||||
_textEditingController.clear();
|
||||
_list.value = <SettingsModel>[];
|
||||
_list.clear();
|
||||
} else {
|
||||
Get.back();
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ class _PayCoinsPageState extends State<PayCoinsPage>
|
||||
|
||||
Timer? _timer;
|
||||
late final RxInt _thunderIndex = (-1).obs;
|
||||
late final List<String> _thunderImages = const [
|
||||
static const List<String> _thunderImages = [
|
||||
'assets/images/paycoins/ic_thunder_1.png',
|
||||
'assets/images/paycoins/ic_thunder_2.png',
|
||||
'assets/images/paycoins/ic_thunder_3.png',
|
||||
|
||||
@@ -115,17 +115,12 @@ class _ReplyPageState extends CommonRichTextPubPageState<ReplyPage> {
|
||||
if (imageList.isNotEmpty) {
|
||||
return SizedBox(
|
||||
height: 85,
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
padding: const EdgeInsets.fromLTRB(15, 0, 15, 10),
|
||||
child: Row(
|
||||
spacing: 10,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: List.generate(
|
||||
imageList.length,
|
||||
(index) => buildImage(index, 75),
|
||||
),
|
||||
),
|
||||
child: ListView.separated(
|
||||
scrollDirection: .horizontal,
|
||||
padding: const .fromLTRB(15, 0, 15, 10),
|
||||
itemCount: imageList.length,
|
||||
itemBuilder: (_, index) => buildImage(index, 75),
|
||||
separatorBuilder: (_, _) => const SizedBox(width: 10),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
@@ -314,6 +309,7 @@ class _ReplyPageState extends CommonRichTextPubPageState<ReplyPage> {
|
||||
return SizedBox(
|
||||
height: height,
|
||||
child: GridView(
|
||||
physics: const ClampingScrollPhysics(),
|
||||
padding: const EdgeInsets.only(left: 12, bottom: 12, right: 12),
|
||||
gridDelegate: gridDelegate,
|
||||
children: [
|
||||
|
||||
@@ -179,62 +179,62 @@ class _SendDanmakuPanelState extends CommonTextPubPageState<SendDanmakuPanel> {
|
||||
),
|
||||
),
|
||||
),
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(height: 12),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'弹幕字号',
|
||||
style: TextStyle(
|
||||
fontSize: 15,
|
||||
color: themeData.colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
_buildFontSizeItem(18, '小'),
|
||||
const SizedBox(width: 5),
|
||||
_buildFontSizeItem(25, '标准'),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'弹幕样式',
|
||||
style: TextStyle(
|
||||
fontSize: 15,
|
||||
color: themeData.colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
_buildPositionItem(1, '滚动'),
|
||||
const SizedBox(width: 5),
|
||||
_buildPositionItem(5, '顶部'),
|
||||
const SizedBox(width: 5),
|
||||
_buildPositionItem(4, '底部'),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'弹幕颜色',
|
||||
style: TextStyle(
|
||||
fontSize: 15,
|
||||
color: themeData.colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
_buildColorPanel,
|
||||
],
|
||||
),
|
||||
SizedBox(height: 12 + MediaQuery.viewPaddingOf(context).bottom),
|
||||
],
|
||||
child: ListView(
|
||||
physics: const ClampingScrollPhysics(),
|
||||
padding: .only(
|
||||
top: 12,
|
||||
bottom: 12 + MediaQuery.viewPaddingOf(context).bottom,
|
||||
),
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'弹幕字号',
|
||||
style: TextStyle(
|
||||
fontSize: 15,
|
||||
color: themeData.colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
_buildFontSizeItem(18, '小'),
|
||||
const SizedBox(width: 5),
|
||||
_buildFontSizeItem(25, '标准'),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
'弹幕样式',
|
||||
style: TextStyle(
|
||||
fontSize: 15,
|
||||
color: themeData.colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
_buildPositionItem(1, '滚动'),
|
||||
const SizedBox(width: 5),
|
||||
_buildPositionItem(5, '顶部'),
|
||||
const SizedBox(width: 5),
|
||||
_buildPositionItem(4, '底部'),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'弹幕颜色',
|
||||
style: TextStyle(
|
||||
fontSize: 15,
|
||||
color: themeData.colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
_buildColorPanel,
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user