Skip to content

Commit 8d9f04e

Browse files
author
vinda
authored
Merge pull request #2 from SHINING-TECH/dev
Dev Merge to Main
2 parents 49d92bb + 808cdda commit 8d9f04e

File tree

12 files changed

+274
-35
lines changed

12 files changed

+274
-35
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ to manage and update the screen content in real-time.
5555
### 📰 Info Screens
5656

5757
<p align="center">
58-
<img src="assets/show/digitalinfo.png" width="500" alt="Info Screen" />
58+
<img src="assets/show/sales.gif" width="500" alt="Info Screen" />
5959
</p>
6060

6161
---

assets/show/sales.gif

1.61 MB
Loading

assets/web20250605.zip

-4.9 MB
Binary file not shown.

assets/web20250622.zip

5.6 MB
Binary file not shown.

lib/config/app_config.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class AppConfig {
1111
AppConfig._internal();
1212

1313
// 配置变量
14-
late String webVersion = "web20250605";
14+
late String webVersion = "web20250622";
1515

1616
//当前播放的播放计划id
1717
late int nowPlayingPublishId = 0;

lib/displayitem/text/TextItemData.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ class TextItemData {
1515
final String textWeight;
1616
final String textStyle;
1717
final String textUnderline;
18+
final String textAnimalType;
1819

1920
TextItemData({
2021
// 初始化注释中的字段
@@ -28,6 +29,7 @@ class TextItemData {
2829
required this.textWeight,
2930
required this.textStyle,
3031
required this.textUnderline,
32+
required this.textAnimalType,
3133
});
3234

3335
// 从 JSON 数据创建 TextItemData 实例
@@ -44,6 +46,7 @@ class TextItemData {
4446
textWeight: json['textWeight']?? '',
4547
textStyle: json['textStyle']?? '',
4648
textUnderline: json['textUnderline']?? '',
49+
textAnimalType: json['textAnimalType']?? '',
4750
);
4851
}
4952
}

lib/displayitem/text/display_item_text.dart renamed to lib/displayitem/text/TextWidgetBuilder.dart

Lines changed: 108 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,25 @@
1-
// ... existing code ...
2-
31
import 'package:flutter/cupertino.dart';
42
import 'package:flutter/material.dart';
53

64
import '../../database/database.dart';
75
import '../../database/database_manager.dart';
86
import 'TextItemData.dart';
97
import 'dart:convert';
8+
import '../BaseDisplayWidget.dart';
9+
import 'package:animated_text_kit/animated_text_kit.dart'; // 导入 animated_text_kit 库
10+
1011

1112
/**
1213
* 文字区域显示组件
1314
*/
14-
class TextWidgetBuilder {
15-
static Future<Widget> buildTextWidget(
16-
int programId, Map<String, dynamic> item) async {
15+
class TextWidgetBuilder extends BaseDisplayWidget {
16+
@override
17+
Future<Widget> buildWidget(int programId, Map<String, dynamic> item) async {
1718
final DatabaseManager _dbManager = DatabaseManager();
1819
String itemID = item['id'];
1920
print("构建文字区域显示组件 模板区域id: ${itemID}");
2021
try {
21-
//根据programID和模板区域id查询节目中这个模板区域的配置
22+
// 根据programID和模板区域id查询节目中这个模板区域的配置
2223
ProgramItem? programItemData = await _dbManager
2324
.getProgramItemByProgramIdAndItemId(programId, itemID);
2425
print("查询到的节目中这个模板区域的配置:${programItemData?.toJson()}");
@@ -44,6 +45,10 @@ class TextWidgetBuilder {
4445
),
4546
);
4647
}
48+
// final double devicePixelRatio = MediaQuery.of(context).devicePixelRatio;
49+
// final double flutterFontSize = webFontSize / devicePixelRatio;
50+
print("文字大小:${textItemData.textFontSize} 动画效果:${textItemData.textAnimalType} 字体:${textItemData.textFontFamily}");
51+
4752

4853
// 解析颜色
4954
Color parseColor(String colorStr) {
@@ -110,7 +115,7 @@ class TextWidgetBuilder {
110115
}
111116
}
112117

113-
//居中设置
118+
// 居中设置
114119
// Function to parse text alignment
115120
TextAlign parseTextAlign(String align) {
116121
switch (align.toLowerCase()) {
@@ -125,30 +130,108 @@ class TextWidgetBuilder {
125130
}
126131
}
127132

133+
final textStyle = TextStyle(
134+
color: parseColor(textItemData.textColor),
135+
fontSize: double.tryParse((textItemData.textFontSize).toString()) ?? 20,
136+
fontFamily: textItemData.textFontFamily,
137+
fontWeight: parseFontWeight(textItemData.textWeight),
138+
fontStyle: parseFontStyle(textItemData.textStyle),
139+
decoration: parseUnderline(textItemData.textUnderline),
140+
);
141+
142+
List<AnimatedText> getAnimatedTexts(String animalType,String textContent,String textAlign) {
143+
switch (animalType) {
144+
case 'none':
145+
print("无动画效果");
146+
return [
147+
// 无动画效果,直接使用普通 Text
148+
TyperAnimatedText(
149+
textContent,
150+
speed: const Duration(milliseconds: 0),
151+
textAlign: parseTextAlign(textAlign),
152+
),
153+
];
154+
case 'Fade':
155+
print("淡入淡出效果");
156+
return [
157+
FadeAnimatedText(
158+
textContent,
159+
duration: const Duration(seconds: 2),
160+
textAlign: parseTextAlign(textAlign),
161+
),
162+
];
163+
case 'Typer':
164+
print("打字效果");
165+
return [
166+
TyperAnimatedText(
167+
textContent,
168+
speed: const Duration(milliseconds: 100),
169+
textAlign: parseTextAlign(textAlign),
170+
),
171+
];
172+
case 'Scale':
173+
print("缩放效果");
174+
return [
175+
ScaleAnimatedText(
176+
textContent,
177+
textAlign: parseTextAlign(textAlign),
178+
duration: const Duration(milliseconds: 2000),
179+
scalingFactor: 0.5,
180+
),
181+
];
182+
case 'Flick':
183+
print("闪烁效果");
184+
return [
185+
FlickerAnimatedText(
186+
textContent,
187+
textStyle: textStyle,
188+
textAlign: parseTextAlign(textAlign),
189+
),
190+
];
191+
case 'Colorize':
192+
print("颜色变化效果");
193+
return [
194+
ColorizeAnimatedText(
195+
textContent,
196+
colors: [
197+
Colors.purple,
198+
Colors.blue,
199+
Colors.yellow,
200+
Colors.red,
201+
],
202+
textStyle: textStyle,
203+
textAlign: parseTextAlign(textAlign),
204+
),
205+
];
206+
default:
207+
return [
208+
// 无动画效果,直接使用普通 Text
209+
TyperAnimatedText(
210+
textContent,
211+
speed: const Duration(milliseconds: 0),
212+
textAlign: parseTextAlign(textAlign),
213+
),
214+
];
215+
}
216+
}
217+
128218
return Container(
129219
color: parseColor(textItemData.textBGColor),
130220
child: Align(
131-
alignment: Alignment.center,
132221
child: SizedBox(
133222
width: double.infinity,
134-
child: Text(
135-
textItemData.textContent,
136-
style: TextStyle(
137-
color: parseColor(textItemData.textColor),
138-
fontSize: double.tryParse(textItemData.textFontSize.toString()) ?? 20,
139-
fontFamily: textItemData.textFontFamily,
140-
fontWeight: parseFontWeight(textItemData.textWeight),
141-
fontStyle: parseFontStyle(textItemData.textStyle),
142-
decoration: parseUnderline(textItemData.textUnderline),
223+
child: DefaultTextStyle(
224+
style: textStyle,
225+
child: AnimatedTextKit(
226+
repeatForever: true,
227+
animatedTexts: getAnimatedTexts(textItemData.textAnimalType,textItemData.textContent,textItemData.align),
143228
),
144-
textAlign: parseTextAlign(textItemData.align),
145229
),
146230
),
147231
),
148232
);
149-
150233
} catch (e) {
151-
print("Error in buildTextWidget: $e");
234+
print("Error in buildWidget: $e");
152235
return Container(
153236
color: Colors.black,
154237
alignment: Alignment.center,
@@ -159,4 +242,8 @@ class TextWidgetBuilder {
159242
);
160243
}
161244
}
162-
}
245+
@override
246+
void dispose() {
247+
print("Text Area Release");
248+
}
249+
}

lib/pages/display_page.dart

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import '../displayitem/BaseDisplayWidget.dart';
1111
import '../displayitem/clock/ClockWidgetBuilder.dart';
1212
import '../displayitem/img/ImageWidgetBuilder.dart';
1313
import '../displayitem/scrolltext/display_item_scroll_text.dart';
14-
import '../displayitem/text/display_item_text.dart';
14+
import '../displayitem/text/TextWidgetBuilder.dart';
1515
import '../displayitem/timeTxt/TimeTextWidgetBuilder.dart';
1616
import '../event/event_bus.dart';
1717
import '../event/refresh_display_event.dart';
@@ -162,7 +162,10 @@ class DisplayPageState extends StateEx<DisplayPage> {
162162
final videoWidget = await videoBuilder.buildWidget(programId,item);
163163
return videoWidget;
164164
case "txt":
165-
return await TextWidgetBuilder.buildTextWidget(programId,item);
165+
final textBuilder = TextWidgetBuilder();
166+
displayWidgets.add(textBuilder); // 添加到列表
167+
final textWidget = await textBuilder.buildWidget(programId,item);
168+
return textWidget;
166169
case "scroll":
167170
return await ScrollTextWidgetBuilder.buildScrollTextWidget(programId,item);
168171
case "clock":
@@ -286,6 +289,7 @@ class TemplateScreen extends StatelessWidget {
286289
.of(context)
287290
.size
288291
.height;
292+
289293
print("screenWidth: $screenWidth designWidth: $designWidth");
290294
print("screenHeight: $screenHeight designHeight: $designHeight");
291295

lib/pages/home_page.dart

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import 'dart:convert';
22

33
import 'package:flutter/material.dart';
44
import 'package:snap_vison_client/config/app_config.dart';
5+
import 'package:snap_vison_client/pages/setting_v2.dart';
56
import 'package:snap_vison_client/server/ServerManage.dart';
67
import 'package:r_get_ip/r_get_ip.dart';
78
import 'package:snap_vison_client/util/FileUtil.dart';
@@ -30,6 +31,16 @@ class _HomePageState extends State<HomePage> {
3031
final DatabaseManager _dbManager = DatabaseManager();
3132
final ServerManage _serverManage = ServerManage();
3233
String? ipv4Address;
34+
//TV焦点
35+
final FocusNode _settingsButtonFocusNode = FocusNode();
36+
bool _isButtonFocused = false;
37+
38+
@override
39+
void dispose() {
40+
// 释放焦点节点
41+
_settingsButtonFocusNode.dispose();
42+
super.dispose();
43+
}
3344

3445
@override
3546
void initState() {
@@ -90,15 +101,30 @@ class _HomePageState extends State<HomePage> {
90101
Positioned(
91102
left: 16,
92103
top: 16,
93-
child: ElevatedButton.icon(
94-
onPressed: () {
95-
Navigator.push(
96-
context,
97-
MaterialPageRoute(builder: (context) => const SettingsPage()),
98-
);
104+
child: FocusableActionDetector(
105+
focusNode: _settingsButtonFocusNode,
106+
onShowFocusHighlight: (isFocused) {
107+
setState(() {
108+
// 可根据 isFocused 状态更新 UI,如改变按钮颜色
109+
_isButtonFocused = isFocused;
110+
});
99111
},
100-
icon: const Icon(Icons.settings),
101-
label: Text(L10n.getString(context, 'settings')),
112+
child: ElevatedButton.icon(
113+
style: ElevatedButton.styleFrom(
114+
// 根据焦点状态添加外边框
115+
side: _isButtonFocused
116+
? BorderSide(color: Colors.lightBlue, width: 2)
117+
: BorderSide.none,
118+
),
119+
onPressed: () {
120+
Navigator.push(
121+
context,
122+
MaterialPageRoute(builder: (context) => const SettingsPage()),
123+
);
124+
},
125+
icon: const Icon(Icons.settings),
126+
label: Text(L10n.getString(context, 'settings')),
127+
),
102128
),
103129
),
104130
],

0 commit comments

Comments
 (0)