首页 > 解决方案 > Flutter:使用 Hover Widget 在触摸输入设备上不起作用

问题描述

我制作了一个包含图像(个人资料图片)的小部件,当您将鼠标悬停在它上面时,您可以选择一个文件用作新的个人资料图片。出于奇怪的原因,某些 PNG 文件无法正常工作。因此,我在显示之前将 PNG 转换为 JPG。它在桌面平台和桌面 Web 上运行良好。使用触摸时,它不起作用,尝试用手势控制包装它也不起作用。所以这给了我们一个在网络上基于触摸的设备上无法使用的小部件。我为 Web 和桌面平台使用不同的页面,因为文件选择器在 Web 上不起作用。

在桌面上:

HoverWidget(
                hoverChild: Container(
                  height: sy(68),
                  width: sy(68),
                  decoration: BoxDecoration(
                    shape: BoxShape.circle,
                    border: Border.all(
                      color: Colors.white,
                      width: 0.1,
                    ),
                  ),
                  child: CircleAvatar(
                    radius: sy(68),
                    backgroundColor: Colors.white,
                    backgroundImage: Img.FileImage(filee),
                    child: ClipRRect(
                      borderRadius:
                          BorderRadius.all(Radius.circular(sy(68))),
                      child: BackdropFilter(
                        filter: ImageFilter.blur(sigmaX: 4, sigmaY: 4),
                        child: Container(
                          alignment: Alignment.center,
                          color: Colors.grey.withOpacity(0.1),
                          child: Center(
                              child: Material(
                            elevation: 5.0,
                            borderRadius: BorderRadius.circular(30.0),
                            color: const Color(0xff1f59b6),
                            child: ElevatedButton(
                              child: Container(
                                  height: sy(16),
                                  width: sy(42),
                                  child: Center(
                                      child: Text(
                                    "Choose Image",
                                    style: TextStyle(
                                        fontSize: sy(6),
                                        fontWeight: FontWeight.bold),
                                  ))),
                              onPressed: () {
                                _selectFile(context);
                              },
                            ),
                          )),
                        ),
                      ),
                    ),
                  ),
                ),
                onHover: (event) {
                  setState(() {
                    hovered = true;
                  });
                },
                child: Container(
                  height: sy(68),
                  width: sy(68),
                  decoration: BoxDecoration(
                    shape: BoxShape.circle,
                    border: Border.all(
                      color: Colors.white,
                      width: 0.1,
                    ),
                  ),
                  child: CircleAvatar(
                    radius: sy(68),
                    backgroundColor: Colors.white,
                    backgroundImage: Img.FileImage(filee),
                  ),
                ),
              ),

在网上:

HoverWidget(
                                    hoverChild: Container(
                                      height: sy(68),
                                      width: sy(68),
                                      decoration: BoxDecoration(
                                        shape: BoxShape.circle,
                                        border: Border.all(
                                          color: Colors.white,
                                          width: 0.1,
                                        ),
                                      ),
                                      child: CircleAvatar(
                                        radius: sy(68),
                                        backgroundColor: Colors.white,
                                        backgroundImage:
                                            Image.network(img).image,
                                        child: ClipRRect(
                                          borderRadius: BorderRadius.all(
                                              Radius.circular(sy(68))),
                                          child: BackdropFilter(
                                            filter: ImageFilter.blur(
                                                sigmaX: 4, sigmaY: 4),
                                            child: Container(
                                              alignment: Alignment.center,
                                              color:
                                                  Colors.grey.withOpacity(0.1),
                                              child: Center(
                                                  child: Material(
                                                elevation: 5.0,
                                                borderRadius:
                                                    BorderRadius.circular(30.0),
                                                color: const Color(0xff1f59b6),
                                                child: ElevatedButton(
                                                  child: Container(
                                                      height: sy(16),
                                                      width: sy(42),
                                                      child: Center(
                                                          child: Text(
                                                        "Choose Image",
                                                        style: TextStyle(
                                                            fontSize: sy(6),
                                                            fontWeight:
                                                                FontWeight
                                                                    .bold),
                                                      ))),
                                                  onPressed: () async {
                                                    var image =
                                                        await ImagePicker()
                                                            .pickImage(
                                                                source:
                                                                    ImageSource
                                                                        .gallery);
                                                    provider.setImage(image);
                                                    img = provider.image.path;
                                                  },
                                                ),
                                              )),
                                            ),
                                          ),
                                        ),
                                      ),
                                    ),
                                    onHover: (event) {
                                      setState(() {
                                        hovered  = true;
                                      });
                                    },
                                    child: Container(
                                      height: sy(68),
                                      width: sy(68),
                                      decoration: BoxDecoration(
                                        shape: BoxShape.circle,
                                        border: Border.all(
                                          color: Colors.white,
                                          width: 0.1,
                                        ),
                                      ),
                                      child: CircleAvatar(
                                        radius: sy(68),
                                        backgroundColor: Colors.white,
                                        backgroundImage:
                                            Image.network(img).image,
                                      ),
                                    ),
                                  ),

标签: flutterdartflutter-layoutflutter-web

解决方案


将 Hover Widget 替换为 Gesture Detector,默认将 hovered 值设置为 false。现在它可以点击。您可以使用https://pub.dev/packages/platform_detect来检测平台和浏览器,以决定何时使用悬停和何时使用点击。遇到了这个问题,分享给大家,希望对大家有帮助!

 GestureDetector(
                                  onTap: () {
                                    setState(() {
                                      hoverd = true;
                                    });
                                    Timer(Duration(seconds: 10), () {
                                      setState(() {
                                        hoverd = false;
                                      });
                                    });
                                  },
                                  child: hoverd == true
                                      ? Container(
                                          height: sy(68),
                                          width: sy(68),
                                          decoration: BoxDecoration(
                                            shape: BoxShape.circle,
                                            border: Border.all(
                                              color: Colors.white,
                                              width: 0.1,
                                            ),
                                          ),
                                          child: CircleAvatar(
                                            radius: sy(68),
                                            backgroundColor: Colors.white,
                                            backgroundImage:
                                                Image.network(img).image,
                                            child: ClipRRect(
                                              borderRadius: BorderRadius.all(
                                                  Radius.circular(sy(68))),
                                              child: BackdropFilter(
                                                filter: ImageFilter.blur(
                                                    sigmaX: 4, sigmaY: 4),
                                                child: Container(
                                                  alignment: Alignment.center,
                                                  color: Colors.grey
                                                      .withOpacity(0.1),
                                                  child: Center(
                                                      child: Material(
                                                    elevation: 5.0,
                                                    borderRadius:
                                                        BorderRadius.circular(
                                                            30.0),
                                                    color:
                                                        const Color(0xff1f59b6),
                                                    child: ElevatedButton(
                                                      child: Container(
                                                          height: sy(16),
                                                          width: sy(42),
                                                          child: Center(
                                                              child: Text(
                                                            "Choose Image",
                                                            style: TextStyle(
                                                                fontSize: sy(6),
                                                                fontWeight:
                                                                    FontWeight
                                                                        .bold),
                                                          ))),
                                                      onPressed: () async {
                                                        var image = await ImagePicker()
                                                            .pickImage(
                                                                source:
                                                                    ImageSource
                                                                        .gallery);
                                                        provider
                                                            .setImage(image);
                                                        img =
                                                            provider.image.path;
                                                        setState(() {
                                                          hoverd = false;
                                                        });
                                                      },
                                                    ),
                                                  )),
                                                ),
                                              ),
                                            ),
                                          ),
                                        )
                                      : Container(
                                          height: sy(68),
                                          width: sy(68),
                                          decoration: BoxDecoration(
                                            shape: BoxShape.circle,
                                            border: Border.all(
                                              color: Colors.white,
                                              width: 0.1,
                                            ),
                                          ),
                                          child: CircleAvatar(
                                            radius: sy(68),
                                            backgroundColor: Colors.white,
                                            backgroundImage:
                                                Image.network(img).image,
                                          ),
                                        ),
                                )

推荐阅读