通过鼠标滚轮在 HtmlElementView 上方滚动 => 不起作用 (Flutter Web)
Scrolling above HtmlElementView by mouse wheel => doesn't work (Flutter Web)
嗨 Flutter 粉丝
我正在为我的 flutter 网站开发自定义图像小部件,以使我的网站像本地网站一样
我的问题
我的自定义图像小部件可以使用了,您也可以使用它,但是我的滚动有问题
- 当鼠标悬停在我网站的任何位置时(期望自定义图像小部件)然后通过鼠标滚轮滚动 => 它滚动正常
- 当悬停在自定义图像小部件上并通过鼠标滚轮滚动时 => 无法滚动
自定义图像小工具 (AdaptiveImage)
一个使用 HtmlElementView
显示图像的小部件,它使用语义和 SEO 渲染包
import 'package:flutter/material.dart';
import 'package:seo_renderer/seo_renderer.dart';
import '../utils/platform_detector.dart';
import 'package:universal_html/html.dart' as html;
import 'dart:ui' as ui;
// ignore: must_be_immutable
class AdaptiveImage extends StatefulWidget {
final String srcImage;
final String altImage;
final double width;
final double height;
final String hint;
final String label;
final String value;
final Widget? nativeImage;
final String imageName;
const AdaptiveImage({
required key,
required this.srcImage,
required this.altImage,
required this.width,
required this.height,
required this.imageName,
this.nativeImage,
this.label = '',
this.hint = '',
this.value = '',
}) : super(key: key);
@override
State<StatefulWidget> createState() => _AdaptiveImageState();
}
class _AdaptiveImageState extends State<AdaptiveImage> {
@override
initState() {
html.IFrameElement _element = html.IFrameElement()
..width = '${widget.width}px'
..height = '${widget.height}px'
..style.width = "${widget.width}px"
..style.height = "${widget.height}px"
..style.border = 'none'
..style.padding = '0px'
..style.margin = '0px'
..srcdoc = """
<!DOCTYPE html>
<html>
<body scroll="no" style="overflow: hidden">
<img src='${widget.srcImage}' alt='${widget.altImage}' width="${widget.width - 15}px" height="${widget.height - 15}px"/>
</body>
</html>
""";
// ignore: undefined_prefixed_name
ui.platformViewRegistry
.registerViewFactory(widget.imageName, (int viewId) => _element);
super.initState();
}
@override
Widget build(BuildContext context) {
return PlatformDetector().isWeb()
? SizedBox(
width: widget.width,
height: widget.height,
child: ImageRenderer(
src: widget.srcImage,
alt: widget.altImage,
child: Semantics(
onTap: () {},
readOnly: true,
image: true,
value: widget.value,
label: widget.label,
hint: widget.hint,
child: HtmlElementView(
key: widget.key,
viewType: widget.imageName,
onPlatformViewCreated: (value) => debugPrint('text_$value'),
)),
),
)
: Semantics(
onTap: () {},
readOnly: true,
image: true,
value: widget.value,
label: widget.label,
hint: widget.hint,
child: widget.nativeImage);
}
}
首页
我的用于显示包含自定义图像小部件的小部件的页面(AdaptiveImage)
请搜索如下文本:<<<<<<<<<<<-------------------- ----------这是我的问题
import 'dart:math';
import 'package:design_ui/utils/app_color.dart';
import 'package:design_ui/utils/resources_path.dart';
import 'package:design_ui/utils/router/routers.dart';
import 'package:design_ui/view_model/home_view_model.dart';
import 'package:design_ui/widgets/adaptive_image.dart';
import 'package:design_ui/widgets/adaptive_link.dart';
import 'package:design_ui/widgets/adaptive_text.dart';
import 'package:flutter/material.dart';
import 'package:flutter_improved_scrolling/flutter_improved_scrolling.dart';
import 'package:seo_renderer/renderers/text_renderer/text_renderer_style.dart';
import 'package:seo_renderer/seo_renderer.dart';
import 'package:url_launcher/link.dart';
import '../utils/constants.dart';
import '../utils/localization/app_localizations.dart';
import '../utils/platform_detector.dart';
import '../widgets/clippers.dart';
class HomePage extends StatelessWidget {
HomePage({Key? key}) : super(key: key) {
viewModel = HomeViewModel(); //Injection
}
late HomeViewModel viewModel;
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: SizedBox(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child:
//Web for mobile (Android & IOS)
PlatformDetector().isWeb() &&
(Theme.of(context).platform == TargetPlatform.iOS ||
Theme.of(context).platform == TargetPlatform.android)
? _singleScrollChild(context)
:
//Web for Desktops (Windows-MacOS-Linux)
_desktopWebScroller(context),
),
),
);
}
_desktopWebScroller(BuildContext context) {
return ImprovedScrolling(
scrollController: viewModel.scrollController,
mmbScrollConfig: const MMBScrollConfig(
customScrollCursor: DefaultCustomScrollCursor(),
),
keyboardScrollConfig: KeyboardScrollConfig(
homeScrollDurationBuilder: (currentScrollOffset, minScrollOffset) {
return const Duration(milliseconds: 100);
},
endScrollDurationBuilder: (currentScrollOffset, maxScrollOffset) {
return const Duration(milliseconds: 2000);
},
),
customMouseWheelScrollConfig: const CustomMouseWheelScrollConfig(
scrollAmountMultiplier: 2.0,
),
onScroll: (scrollOffset) {
//print(Scroll offset: $scrollOffset',),
},
onMMBScrollStateChanged: (scrolling) {
//print('Is scrolling: $scrolling',)
},
onMMBScrollCursorPositionUpdate: (localCursorOffset, scrollActivity) {
//print('Cursor position: $localCursorOffset\n''Scroll activity: $scrollActivity',)
},
enableMMBScrolling: true,
enableKeyboardScrolling: true,
enableCustomMouseWheelScrolling: true,
child: ScrollConfiguration(
behavior: const CustomScrollBehaviour(),
child: _singleScrollChild(context),
));
}
_singleScrollChild(BuildContext context) {
return SingleChildScrollView(
controller: viewModel.scrollController,
physics:
//Web to Android or IOS OS
PlatformDetector().isWeb() &&
(Theme.of(context).platform == TargetPlatform.windows ||
Theme.of(context).platform == TargetPlatform.linux ||
Theme.of(context).platform == TargetPlatform.macOS ||
Theme.of(context).platform == TargetPlatform.fuchsia)
? const NeverScrollableScrollPhysics()
:
//Web to Windows or MacOs or Linux
const BouncingScrollPhysics(),
scrollDirection: Axis.vertical,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
//////////////////////// * Header * ////////////////////////
HomeHeader(viewModel),
//////////////////////// * Modern Products * ////////////////////////
HomeModernProducts(viewModel),
],
),
);
}
/* HomeHeader Class */
// ignore: must_be_immutable
class HomeHeader extends StatelessWidget {
HomeHeader(this.viewModel, {Key? key}) : super(key: key);
HomeViewModel viewModel;
@override
Widget build(BuildContext context) {
return SizedBox(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: ClipPath(
clipper: HomeHeaderClipper(),
child: Stack(
children: [
//////////////////////// * Background Image * ////////////////////////
ImageRenderer(
alt: 'Products header image',
src: 'assets${ResourcesPath.headerImage}',
child: Image.asset(
ResourcesPath.headerImage,
fit: BoxFit.cover,
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
),
),
// AdaptiveImage(
// width: MediaQuery.of(context).size.width,
// height: MediaQuery.of(context).size.height,
// altImage: 'products header image',
// srcImage: ResourcesPath.headerImage,
// hint: 'products header image',
// label: 'products header image',
// value: 'products header image',
// ),
//////////////////////// * Shadow Black * ////////////////////////
Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
color: Colors.black.withOpacity(0.8),
),
//////////////////////// * Titles * ////////////////////////
Center(
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
//////////////////////// * Title * ////////////////////////
AdaptiveText(
text: AppLocalizations.of(context)!
.translate('home_header_title'),
headerText: 'Products',
headerType: TextRendererStyle.header1,
style: Theme.of(context).textTheme.headline1!.copyWith(
color: Colors.white,
shadows: const [
Shadow(color: Colors.blue, blurRadius: 12)
]),
textAlign: TextAlign.center,
hint: 'Products',
label: 'Products',
value: 'Products',
),
const SizedBox(
height: 20,
),
//////////////////////// * Subtitle * ////////////////////////
Padding(
padding: const EdgeInsets.all(16.0),
child: AdaptiveText(
text: AppLocalizations.of(context)!
.translate('home_header_subtitle'),
headerText:
"Explore the latest modern products in the world",
headerType: TextRendererStyle.header2,
style: Theme.of(context).textTheme.headline2!.copyWith(
color: Colors.white, fontWeight: FontWeight.w200),
textAlign: TextAlign.center,
hint: "Explore the latest modern products in the world",
label: "Explore the latest modern products in the world",
value: "Explore the latest modern products in the world",
),
),
const SizedBox(
height: 35,
),
//////////////////////// * Button Login * ////////////////////////
AdaptiveLink(
link: Routers.loginName,
linkText: 'Login Page',
target: LinkTarget.self,
hint: 'Login Page',
label: 'Login Page',
value: 'Login Page',
widget: ElevatedButton(
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.all(25),
primary: Theme.of(context).primaryColor,
shadowColor: Theme.of(context).primaryColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)),
elevation: 16,
),
child: Text(
AppLocalizations.of(context)!
.translate('home_header_button_login'),
style: Theme.of(context)
.textTheme
.headline6!
.copyWith(color: Colors.white),
textAlign: TextAlign.center,
),
onPressed: () {
viewModel.goLogin(context);
},
),
)
],
))
],
),
));
}
}
/* ModernProducts Class */
// ignore: must_be_immutable
class HomeModernProducts extends StatelessWidget {
HomeModernProducts(this.viewModel, {Key? key}) : super(key: key);
HomeViewModel viewModel;
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 42, vertical: 30),
child: Row(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
//////////////////////// * Text * ////////////////////////
Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
AdaptiveText(
text: AppLocalizations.of(context)!
.translate('home_modern_products_title'),
headerText: "Modern Products",
headerType: TextRendererStyle.header3,
style: Theme.of(context)
.textTheme
.headline3!
.copyWith(fontWeight: FontWeight.w400),
textAlign: TextAlign.start,
hint: "Modern Products",
label: "Modern Products",
value: "Modern Products",
),
const SizedBox(
height: 12,
),
SizedBox(
width: MediaQuery.of(context).size.width - 800,
child: AdaptiveText(
text: AppLocalizations.of(context)!
.translate('home_modern_products_subtitle'),
headerText:
"We offer a lot of products which every one want has it, we care about your ideas and opinion and release latest version of our products",
headerType: TextRendererStyle.header6,
style: Theme.of(context)
.textTheme
.headline6!
.copyWith(fontWeight: FontWeight.w200),
textAlign: TextAlign.start,
maxLines: 4,
hint:
"We offer a lot of products which every one want has it, we care about your ideas and opinion and release latest version of our products",
label:
"We offer a lot of products which every one want has it, we care about your ideas and opinion and release latest version of our products",
value:
"We offer a lot of products which every one want has it, we care about your ideas and opinion and release latest version of our products",
),
),
],
),
//////////////////////// * Image * ////////////////////////
AdaptiveImage( <<<<<<<<<<<---------------------------------HERE MY PROBLEM
key: UniqueKey(),
width: 660,
height: 660,
altImage: 'modern products image',
srcImage: ResourcesPath.modernProductsImage,
imageName: 'image${Random().nextInt(100000)}',
hint: 'modern products image',
label: 'modern products image',
value: 'modern products image',
),
],
),
);
}
}
我想要的
请大家解决鼠标悬停在 AdaptiveImage 上时滚动的问题 (HtmlViewElement)
我做了什么和失败了
1- 用 SingleChildScrollView 包装我的 AdaptiveImage 并为其使用相同的控制器,代码:
SingleChildScrollView(
controller: viewModel.scrollController, //Using same scroller
child: AdaptiveImage(
key: UniqueKey(),
width: 660,
height: 660,
altImage: 'modern products image',
srcImage: ResourcesPath.modernProductsImage,
imageName: 'image${Random().nextInt(100000)}',
hint: 'modern products image',
label: 'modern products image',
value: 'modern products image',
),
),
结果:
Doesn't work
2- 用 SingleChildScrollView 包装我的 AdaptiveImage 并且不使用控制器,代码:
SingleChildScrollView(
child: AdaptiveImage(
key: UniqueKey(),
width: 660,
height: 660,
altImage: 'modern products image',
srcImage: ResourcesPath.modernProductsImage,
imageName: 'image${Random().nextInt(100000)}',
hint: 'modern products image',
label: 'modern products image',
value: 'modern products image',
),
),
结果:
Doesn't work
屏幕
您可以查看一些图片以获得更多解释
照片1
开始正常滚动
照片2
文本上方的左侧可以很好地滚动,但右侧不能在图像 (AdaptiveImage) 上方滚动,因为 HtmlViewElement,我想要一种在其上方滚动的方法
终于
非常感谢您耐心阅读所有这些内容并喜欢您对我的支持
是的,伙计们,我找到了
我正在研究我的问题的解决方案,我重写了 AdaptiveImage class,它 works
很好。
import 'package:flutter/material.dart';
import 'package:seo_renderer/seo_renderer.dart';
import '../utils/platform_detector.dart';
import 'package:universal_html/html.dart' as html;
import 'dart:ui' as ui;
// ignore: must_be_immutable
class AdaptiveImage extends StatefulWidget {
final String srcImage;
final String altImage;
final double width;
final double height;
final String hint;
final String label;
final String value;
final Widget? nativeImage;
final String imageName;
const AdaptiveImage({
required key,
required this.srcImage,
required this.altImage,
required this.width,
required this.height,
required this.imageName,
this.nativeImage,
this.label = '',
this.hint = '',
this.value = '',
}) : super(key: key);
@override
State<StatefulWidget> createState() => _AdaptiveImageState();
}
class _AdaptiveImageState extends State<AdaptiveImage> {
@override
initState() {
html.ImageElement _element = html.ImageElement(src: widget.srcImage)
..style.width = "${widget.width}px"
..style.height = "${widget.height}px"
..alt = widget.altImage
..style.padding = '0px'
..style.margin = '0px';
// ignore: undefined_prefixed_name
ui.platformViewRegistry
.registerViewFactory(widget.imageName, (int viewId) => _element);
super.initState();
}
@override
Widget build(BuildContext context) {
return PlatformDetector().isWeb()
? SizedBox(
width: widget.width,
height: widget.height,
child: ImageRenderer(
src: widget.srcImage,
alt: widget.altImage,
child: Semantics(
onTap: () {},
readOnly: true,
image: true,
value: widget.value,
label: widget.label,
hint: widget.hint,
child: IgnorePointer(
child: HtmlElementView(
key: widget.key,
viewType: widget.imageName,
),
)),
),
)
: Semantics(
onTap: () {},
readOnly: true,
image: true,
value: widget.value,
label: widget.label,
hint: widget.hint,
child: widget.nativeImage);
}
}
嗨 Flutter 粉丝
我正在为我的 flutter 网站开发自定义图像小部件,以使我的网站像本地网站一样
我的问题
我的自定义图像小部件可以使用了,您也可以使用它,但是我的滚动有问题
- 当鼠标悬停在我网站的任何位置时(期望自定义图像小部件)然后通过鼠标滚轮滚动 => 它滚动正常
- 当悬停在自定义图像小部件上并通过鼠标滚轮滚动时 => 无法滚动
自定义图像小工具 (AdaptiveImage)
一个使用 HtmlElementView
显示图像的小部件,它使用语义和 SEO 渲染包
import 'package:flutter/material.dart';
import 'package:seo_renderer/seo_renderer.dart';
import '../utils/platform_detector.dart';
import 'package:universal_html/html.dart' as html;
import 'dart:ui' as ui;
// ignore: must_be_immutable
class AdaptiveImage extends StatefulWidget {
final String srcImage;
final String altImage;
final double width;
final double height;
final String hint;
final String label;
final String value;
final Widget? nativeImage;
final String imageName;
const AdaptiveImage({
required key,
required this.srcImage,
required this.altImage,
required this.width,
required this.height,
required this.imageName,
this.nativeImage,
this.label = '',
this.hint = '',
this.value = '',
}) : super(key: key);
@override
State<StatefulWidget> createState() => _AdaptiveImageState();
}
class _AdaptiveImageState extends State<AdaptiveImage> {
@override
initState() {
html.IFrameElement _element = html.IFrameElement()
..width = '${widget.width}px'
..height = '${widget.height}px'
..style.width = "${widget.width}px"
..style.height = "${widget.height}px"
..style.border = 'none'
..style.padding = '0px'
..style.margin = '0px'
..srcdoc = """
<!DOCTYPE html>
<html>
<body scroll="no" style="overflow: hidden">
<img src='${widget.srcImage}' alt='${widget.altImage}' width="${widget.width - 15}px" height="${widget.height - 15}px"/>
</body>
</html>
""";
// ignore: undefined_prefixed_name
ui.platformViewRegistry
.registerViewFactory(widget.imageName, (int viewId) => _element);
super.initState();
}
@override
Widget build(BuildContext context) {
return PlatformDetector().isWeb()
? SizedBox(
width: widget.width,
height: widget.height,
child: ImageRenderer(
src: widget.srcImage,
alt: widget.altImage,
child: Semantics(
onTap: () {},
readOnly: true,
image: true,
value: widget.value,
label: widget.label,
hint: widget.hint,
child: HtmlElementView(
key: widget.key,
viewType: widget.imageName,
onPlatformViewCreated: (value) => debugPrint('text_$value'),
)),
),
)
: Semantics(
onTap: () {},
readOnly: true,
image: true,
value: widget.value,
label: widget.label,
hint: widget.hint,
child: widget.nativeImage);
}
}
首页
我的用于显示包含自定义图像小部件的小部件的页面(AdaptiveImage)
请搜索如下文本:<<<<<<<<<<<-------------------- ----------这是我的问题
import 'dart:math';
import 'package:design_ui/utils/app_color.dart';
import 'package:design_ui/utils/resources_path.dart';
import 'package:design_ui/utils/router/routers.dart';
import 'package:design_ui/view_model/home_view_model.dart';
import 'package:design_ui/widgets/adaptive_image.dart';
import 'package:design_ui/widgets/adaptive_link.dart';
import 'package:design_ui/widgets/adaptive_text.dart';
import 'package:flutter/material.dart';
import 'package:flutter_improved_scrolling/flutter_improved_scrolling.dart';
import 'package:seo_renderer/renderers/text_renderer/text_renderer_style.dart';
import 'package:seo_renderer/seo_renderer.dart';
import 'package:url_launcher/link.dart';
import '../utils/constants.dart';
import '../utils/localization/app_localizations.dart';
import '../utils/platform_detector.dart';
import '../widgets/clippers.dart';
class HomePage extends StatelessWidget {
HomePage({Key? key}) : super(key: key) {
viewModel = HomeViewModel(); //Injection
}
late HomeViewModel viewModel;
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: SizedBox(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child:
//Web for mobile (Android & IOS)
PlatformDetector().isWeb() &&
(Theme.of(context).platform == TargetPlatform.iOS ||
Theme.of(context).platform == TargetPlatform.android)
? _singleScrollChild(context)
:
//Web for Desktops (Windows-MacOS-Linux)
_desktopWebScroller(context),
),
),
);
}
_desktopWebScroller(BuildContext context) {
return ImprovedScrolling(
scrollController: viewModel.scrollController,
mmbScrollConfig: const MMBScrollConfig(
customScrollCursor: DefaultCustomScrollCursor(),
),
keyboardScrollConfig: KeyboardScrollConfig(
homeScrollDurationBuilder: (currentScrollOffset, minScrollOffset) {
return const Duration(milliseconds: 100);
},
endScrollDurationBuilder: (currentScrollOffset, maxScrollOffset) {
return const Duration(milliseconds: 2000);
},
),
customMouseWheelScrollConfig: const CustomMouseWheelScrollConfig(
scrollAmountMultiplier: 2.0,
),
onScroll: (scrollOffset) {
//print(Scroll offset: $scrollOffset',),
},
onMMBScrollStateChanged: (scrolling) {
//print('Is scrolling: $scrolling',)
},
onMMBScrollCursorPositionUpdate: (localCursorOffset, scrollActivity) {
//print('Cursor position: $localCursorOffset\n''Scroll activity: $scrollActivity',)
},
enableMMBScrolling: true,
enableKeyboardScrolling: true,
enableCustomMouseWheelScrolling: true,
child: ScrollConfiguration(
behavior: const CustomScrollBehaviour(),
child: _singleScrollChild(context),
));
}
_singleScrollChild(BuildContext context) {
return SingleChildScrollView(
controller: viewModel.scrollController,
physics:
//Web to Android or IOS OS
PlatformDetector().isWeb() &&
(Theme.of(context).platform == TargetPlatform.windows ||
Theme.of(context).platform == TargetPlatform.linux ||
Theme.of(context).platform == TargetPlatform.macOS ||
Theme.of(context).platform == TargetPlatform.fuchsia)
? const NeverScrollableScrollPhysics()
:
//Web to Windows or MacOs or Linux
const BouncingScrollPhysics(),
scrollDirection: Axis.vertical,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
//////////////////////// * Header * ////////////////////////
HomeHeader(viewModel),
//////////////////////// * Modern Products * ////////////////////////
HomeModernProducts(viewModel),
],
),
);
}
/* HomeHeader Class */
// ignore: must_be_immutable
class HomeHeader extends StatelessWidget {
HomeHeader(this.viewModel, {Key? key}) : super(key: key);
HomeViewModel viewModel;
@override
Widget build(BuildContext context) {
return SizedBox(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: ClipPath(
clipper: HomeHeaderClipper(),
child: Stack(
children: [
//////////////////////// * Background Image * ////////////////////////
ImageRenderer(
alt: 'Products header image',
src: 'assets${ResourcesPath.headerImage}',
child: Image.asset(
ResourcesPath.headerImage,
fit: BoxFit.cover,
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
),
),
// AdaptiveImage(
// width: MediaQuery.of(context).size.width,
// height: MediaQuery.of(context).size.height,
// altImage: 'products header image',
// srcImage: ResourcesPath.headerImage,
// hint: 'products header image',
// label: 'products header image',
// value: 'products header image',
// ),
//////////////////////// * Shadow Black * ////////////////////////
Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
color: Colors.black.withOpacity(0.8),
),
//////////////////////// * Titles * ////////////////////////
Center(
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
//////////////////////// * Title * ////////////////////////
AdaptiveText(
text: AppLocalizations.of(context)!
.translate('home_header_title'),
headerText: 'Products',
headerType: TextRendererStyle.header1,
style: Theme.of(context).textTheme.headline1!.copyWith(
color: Colors.white,
shadows: const [
Shadow(color: Colors.blue, blurRadius: 12)
]),
textAlign: TextAlign.center,
hint: 'Products',
label: 'Products',
value: 'Products',
),
const SizedBox(
height: 20,
),
//////////////////////// * Subtitle * ////////////////////////
Padding(
padding: const EdgeInsets.all(16.0),
child: AdaptiveText(
text: AppLocalizations.of(context)!
.translate('home_header_subtitle'),
headerText:
"Explore the latest modern products in the world",
headerType: TextRendererStyle.header2,
style: Theme.of(context).textTheme.headline2!.copyWith(
color: Colors.white, fontWeight: FontWeight.w200),
textAlign: TextAlign.center,
hint: "Explore the latest modern products in the world",
label: "Explore the latest modern products in the world",
value: "Explore the latest modern products in the world",
),
),
const SizedBox(
height: 35,
),
//////////////////////// * Button Login * ////////////////////////
AdaptiveLink(
link: Routers.loginName,
linkText: 'Login Page',
target: LinkTarget.self,
hint: 'Login Page',
label: 'Login Page',
value: 'Login Page',
widget: ElevatedButton(
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.all(25),
primary: Theme.of(context).primaryColor,
shadowColor: Theme.of(context).primaryColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)),
elevation: 16,
),
child: Text(
AppLocalizations.of(context)!
.translate('home_header_button_login'),
style: Theme.of(context)
.textTheme
.headline6!
.copyWith(color: Colors.white),
textAlign: TextAlign.center,
),
onPressed: () {
viewModel.goLogin(context);
},
),
)
],
))
],
),
));
}
}
/* ModernProducts Class */
// ignore: must_be_immutable
class HomeModernProducts extends StatelessWidget {
HomeModernProducts(this.viewModel, {Key? key}) : super(key: key);
HomeViewModel viewModel;
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 42, vertical: 30),
child: Row(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
//////////////////////// * Text * ////////////////////////
Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
AdaptiveText(
text: AppLocalizations.of(context)!
.translate('home_modern_products_title'),
headerText: "Modern Products",
headerType: TextRendererStyle.header3,
style: Theme.of(context)
.textTheme
.headline3!
.copyWith(fontWeight: FontWeight.w400),
textAlign: TextAlign.start,
hint: "Modern Products",
label: "Modern Products",
value: "Modern Products",
),
const SizedBox(
height: 12,
),
SizedBox(
width: MediaQuery.of(context).size.width - 800,
child: AdaptiveText(
text: AppLocalizations.of(context)!
.translate('home_modern_products_subtitle'),
headerText:
"We offer a lot of products which every one want has it, we care about your ideas and opinion and release latest version of our products",
headerType: TextRendererStyle.header6,
style: Theme.of(context)
.textTheme
.headline6!
.copyWith(fontWeight: FontWeight.w200),
textAlign: TextAlign.start,
maxLines: 4,
hint:
"We offer a lot of products which every one want has it, we care about your ideas and opinion and release latest version of our products",
label:
"We offer a lot of products which every one want has it, we care about your ideas and opinion and release latest version of our products",
value:
"We offer a lot of products which every one want has it, we care about your ideas and opinion and release latest version of our products",
),
),
],
),
//////////////////////// * Image * ////////////////////////
AdaptiveImage( <<<<<<<<<<<---------------------------------HERE MY PROBLEM
key: UniqueKey(),
width: 660,
height: 660,
altImage: 'modern products image',
srcImage: ResourcesPath.modernProductsImage,
imageName: 'image${Random().nextInt(100000)}',
hint: 'modern products image',
label: 'modern products image',
value: 'modern products image',
),
],
),
);
}
}
我想要的
请大家解决鼠标悬停在 AdaptiveImage 上时滚动的问题 (HtmlViewElement)
我做了什么和失败了
1- 用 SingleChildScrollView 包装我的 AdaptiveImage 并为其使用相同的控制器,代码:
SingleChildScrollView(
controller: viewModel.scrollController, //Using same scroller
child: AdaptiveImage(
key: UniqueKey(),
width: 660,
height: 660,
altImage: 'modern products image',
srcImage: ResourcesPath.modernProductsImage,
imageName: 'image${Random().nextInt(100000)}',
hint: 'modern products image',
label: 'modern products image',
value: 'modern products image',
),
),
结果:
Doesn't work
2- 用 SingleChildScrollView 包装我的 AdaptiveImage 并且不使用控制器,代码:
SingleChildScrollView(
child: AdaptiveImage(
key: UniqueKey(),
width: 660,
height: 660,
altImage: 'modern products image',
srcImage: ResourcesPath.modernProductsImage,
imageName: 'image${Random().nextInt(100000)}',
hint: 'modern products image',
label: 'modern products image',
value: 'modern products image',
),
),
结果:
Doesn't work
屏幕
您可以查看一些图片以获得更多解释
照片1
开始正常滚动
照片2
文本上方的左侧可以很好地滚动,但右侧不能在图像 (AdaptiveImage) 上方滚动,因为 HtmlViewElement,我想要一种在其上方滚动的方法
终于
非常感谢您耐心阅读所有这些内容并喜欢您对我的支持
是的,伙计们,我找到了
我正在研究我的问题的解决方案,我重写了 AdaptiveImage class,它 works
很好。
import 'package:flutter/material.dart';
import 'package:seo_renderer/seo_renderer.dart';
import '../utils/platform_detector.dart';
import 'package:universal_html/html.dart' as html;
import 'dart:ui' as ui;
// ignore: must_be_immutable
class AdaptiveImage extends StatefulWidget {
final String srcImage;
final String altImage;
final double width;
final double height;
final String hint;
final String label;
final String value;
final Widget? nativeImage;
final String imageName;
const AdaptiveImage({
required key,
required this.srcImage,
required this.altImage,
required this.width,
required this.height,
required this.imageName,
this.nativeImage,
this.label = '',
this.hint = '',
this.value = '',
}) : super(key: key);
@override
State<StatefulWidget> createState() => _AdaptiveImageState();
}
class _AdaptiveImageState extends State<AdaptiveImage> {
@override
initState() {
html.ImageElement _element = html.ImageElement(src: widget.srcImage)
..style.width = "${widget.width}px"
..style.height = "${widget.height}px"
..alt = widget.altImage
..style.padding = '0px'
..style.margin = '0px';
// ignore: undefined_prefixed_name
ui.platformViewRegistry
.registerViewFactory(widget.imageName, (int viewId) => _element);
super.initState();
}
@override
Widget build(BuildContext context) {
return PlatformDetector().isWeb()
? SizedBox(
width: widget.width,
height: widget.height,
child: ImageRenderer(
src: widget.srcImage,
alt: widget.altImage,
child: Semantics(
onTap: () {},
readOnly: true,
image: true,
value: widget.value,
label: widget.label,
hint: widget.hint,
child: IgnorePointer(
child: HtmlElementView(
key: widget.key,
viewType: widget.imageName,
),
)),
),
)
: Semantics(
onTap: () {},
readOnly: true,
image: true,
value: widget.value,
label: widget.label,
hint: widget.hint,
child: widget.nativeImage);
}
}