如何在Flutter中使一个定位的小部件随内容一起滚动?

huangapple go评论156阅读模式
英文:

How to make a positioned widget scroll along with the content in Flutter?

问题

我在Flutter中有一个页面,包含一张图片和一个返回箭头图像。我正在使用Stack和Positioned小部件将返回箭头图像显示在页面的左上角。然而,当页面上有大量文本并且我向下滚动时,返回箭头图像保持固定在其位置,不会随内容一起滚动。

我想要在用户向下滚动页面时使返回箭头图像随内容一起滚动。在Flutter中,我如何实现这种效果?是否有任何特定的小部件或技术可以使Positioned小部件可滚动?

英文:

I have a page in Flutter that consists of an image and a back arrow image. I'm using a Stack and Positioned widget to display the back arrow image on the top left corner of the page. However, when the page has a large amount of text and I scroll down, the back arrow image remains fixed in its position and doesn't scroll along with the content.

I would like to make the back arrow image scroll along with the content when the user scrolls down the page. How can I achieve this effect in Flutter? Are there any specific widgets or techniques I can use to make the positioned widget scrollable?

答案1

得分: 0

通过修改Stack小部件如下,您可以实现这一目标。

return Scaffold(
  body: Stack(
    children: [
      Container(
        color: const Color(0xFFF7F7F7), // 设置颜色
        child: Column(
          children: [
            Expanded(
              child: SingleChildScrollView(
                child: Stack(
                  children: [
                    // 现有的图片块
                    Image.network(
                      Uri.parse(apiBaseUrl).resolve(house.image).toString(),
                      height: 200,
                      width: double.infinity,
                      fit: BoxFit.fill,
                    ),
                    // 带圆角的详细信息块
                    Container(
                      margin: const EdgeInsets.only(top: 180),
                      padding: const EdgeInsets.all(15),
                      decoration: const BoxDecoration(
                        color: Color(0xFFF7F7F7), // 设置颜色
                        borderRadius: BorderRadius.only(
                          topLeft: Radius.circular(15),
                          topRight: Radius.circular(15),
                        ),
                      ),
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          const SizedBox(
                            height: 20,
                          ),
                          Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: [
                              Text('¥${house.formattedPrice}',
                                  style: const TextStyle(
                                      fontFamily: 'GothamSSm',
                                      fontWeight: FontWeight.w400,
                                      // 将字体权重设置为中等
                                      fontSize: 18,
                                      color: Color(0xCC000000))),
                              const SizedBox(
                                height: 8,
                                width: 60,
                              ),
                              SvgPicture.asset(
                                'assets/icons/ic_bed.svg',
                                width: 18,
                                height: 18,
                                color: const Color(0x66000000),
                              ),
                              Text(house.bedrooms.toString(),
                                  style: const TextStyle(
                                      fontFamily: 'GothamSSm',
                                      fontSize: 10,
                                      color: Color(0x66000000))),
                              const SizedBox(width: 5),
                              // 用于图标之间的间距
                              SvgPicture.asset(
                                'assets/icons/ic_bath.svg',
                                width: 18,
                                height: 18,
                                color: const Color(0x66000000),
                              ),
                              Text(house.bathrooms.toString(),
                                  style: const TextStyle(
                                      fontFamily: 'GothamSSm',
                                      fontSize: 10,
                                      color: Color(0x66000000))),
                              const SizedBox(width: 5),
                              SvgPicture.asset(
                                'assets/icons/ic_layers.svg',
                                width: 18,
                                height: 18,
                                color: const Color(0x66000000),
                              ),
                              Text(house.size.toString(),
                                  style: const TextStyle(
                                      fontFamily: 'GothamSSm',
                                      fontSize: 10,
                                      color: Color(0x66000000))),
                              const SizedBox(width: 5),
                              // 如果有距离,则显示从用户到房子的距离的小部件
                              Visibility(
                                visible: house.distanceFromUser != null,
                                child: Row(
                                  children: [
                                    SvgPicture.asset(
                                      'assets/icons/ic_location.svg',
                                      width: 18,
                                      height: 18,
                                      color: const Color(0x66000000),
                                    ),
                                    const SizedBox(width: 5),
                                    Text(
                                      '${house.distanceFromUser?.toStringAsFixed(0)} km',
                                      style: const TextStyle(
                                        fontFamily: 'GothamSSm',
                                        fontSize: 12,
                                        color: Color(0x66000000),
                                      ),
                                    ),
                                  ],
                                ),
                              ),
                            ],
                          ),
                          const SizedBox(height: 20),
                          const Text(
                            'Description',
                            style: TextStyle(
                              fontSize: 18,
                              fontWeight: FontWeight.w400,
                              fontFamily: 'GothamSSm',
                            ),
                          ),
                          const SizedBox(height: 15),
                          Text(house.description,
                              style: const TextStyle(
                                  fontFamily: 'GothamSSm',
                                  fontWeight: FontWeight.w400,
                                  fontSize: 12,
                                  color: Color(0x66000000))),
                          const SizedBox(height: 8),
                          const Text(
                            'Location',
                            style: TextStyle(
                              fontSize: 18,
                              fontFamily: 'GothamSSm',
                              fontWeight: FontWeight.w400,
                            ),
                          ),
                          Container(
                            height: 200,
                            margin: const EdgeInsets.only(top: 10),
                            // 根据需要调整高度
                            child: GoogleMap(
                              initialCameraPosition: initialCameraPosition,
                              markers: {
                                Marker(
                                  markerId: const MarkerId('houseLocation'),
                                  position:
                                      LatLng(house.latitude, house.longitude),
                                  onTap: onMarkerTap,
                                ),
                              },
                              scrollGesturesEnabled: false,
                              zoomGesturesEnabled: false,
                            ),
                          ),
                        ],
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ],
        ),
      ),
      Positioned(
        top: 35,
        left: 10,
        child: GestureDetector(
          onTap: Navigator.of(context).pop,
          child: SvgPicture.asset(
            'assets/icons/ic_back.svg',
            color: Colors.white,
            width: 30,
            height: 30,
          ),
        ),
      ),
    ],
  ),
);
英文:

by change the Stack widget like below you can achieve that

    return Scaffold(
          body:  Stack(
              children: [
            Container(
            color: const Color(0xFFF7F7F7), // Set the color
            child: Column(
              children: [
                Expanded(
                  child: SingleChildScrollView(
                    child: Stack(
                      children: [
                        // Existing Image Block
                        Image.network(
                          Uri.parse(apiBaseUrl).resolve(house.image).toString(),
                          height: 200,
                          width: double.infinity,
                          fit: BoxFit.fill,
                        ),
        
                        // Details Block with Rounded Corners
                        Container(
                          margin: const EdgeInsets.only(top: 180),
                          padding: const EdgeInsets.all(15),
                          decoration: const BoxDecoration(
                            color: Color(0xFFF7F7F7), // Set the color
                            borderRadius: BorderRadius.only(
                              topLeft: Radius.circular(15),
                              topRight: Radius.circular(15),
                            ),
                          ),
                          child: Column(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: [
                              const SizedBox(
                                height: 20,
                              ),
                              Row(
                                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                                children: [
                                  Text('\$${house.formattedPrice}',
                                      style: const TextStyle(
                                          fontFamily: 'GothamSSm',
                                          fontWeight: FontWeight.w400,
                                          // Set the font weight to medium
                                          fontSize: 18,
                                          color: Color(0xCC000000))),
                                  const SizedBox(
                                    height: 8,
                                    width: 60,
                                  ),
                                  SvgPicture.asset(
                                    'assets/icons/ic_bed.svg',
                                    width: 18,
                                    height: 18,
                                    color: const Color(0x66000000),
                                  ),
                                  Text(house.bedrooms.toString(),
                                      style: const TextStyle(
                                          fontFamily: 'GothamSSm',
                                          fontSize: 10,
                                          color: Color(0x66000000))),
                                  const SizedBox(width: 5),
                                  //width for space betweens icons
                                  SvgPicture.asset(
                                    'assets/icons/ic_bath.svg',
                                    width: 18,
                                    height: 18,
                                    color: const Color(0x66000000),
                                  ),
                                  Text(house.bathrooms.toString(),
                                      style: const TextStyle(
                                          fontFamily: 'GothamSSm',
                                          fontSize: 10,
                                          color: Color(0x66000000))),
                                  const SizedBox(width: 5),
                                  SvgPicture.asset(
                                    'assets/icons/ic_layers.svg',
                                    width: 18,
                                    height: 18,
                                    color: const Color(0x66000000),
                                  ),
                                  Text(house.size.toString(),
                                      style: const TextStyle(
                                          fontFamily: 'GothamSSm',
                                          fontSize: 10,
                                          color: Color(0x66000000))),
                                  const SizedBox(width: 5),
                                  // This widget displays the distance from the user to the house if the distance is available.
                                  Visibility(
                                    visible: house.distanceFromUser != null,
                                    child: Row(
                                      children: [
                                        SvgPicture.asset(
                                          'assets/icons/ic_location.svg',
                                          width: 18,
                                          height: 18,
                                          color: const Color(0x66000000),
                                        ),
                                        const SizedBox(width: 5),
                                        Text(
                                          '${house.distanceFromUser?.toStringAsFixed(0)} km',
                                          style: const TextStyle(
                                            fontFamily: 'GothamSSm',
                                            fontSize: 12,
                                            color: Color(0x66000000),
                                          ),
                                        ),
                                      ],
                                    ),
                                  ),
                                ],
                              ),
                              const SizedBox(height: 20),
                              const Text(
                                'Description',
                                style: TextStyle(
                                  fontSize: 18,
                                  fontWeight: FontWeight.w400,
                                  fontFamily: 'GothamSSm',
                                ),
                              ),
                              const SizedBox(height: 15),
                              Text(house.description,
                                  style: const TextStyle(
                                      fontFamily: 'GothamSSm',
                                      fontWeight: FontWeight.w400,
                                      fontSize: 12,
                                      color: Color(0x66000000))),
                              const SizedBox(height: 8),
                              const Text(
                                'Location',
                                style: TextStyle(
                                  fontSize: 18,
                                  fontFamily: 'GothamSSm',
                                  fontWeight: FontWeight.w400,
                                ),
                              ),
                              Container(
                                height: 200,
                                margin: const EdgeInsets.only(top: 10),
                                // Adjust the height as needed
                                child: GoogleMap(
                                  initialCameraPosition: initialCameraPosition,
                                  markers: {
                                    Marker(
                                      markerId: const MarkerId('houseLocation'),
                                      position:
                                          LatLng(house.latitude, house.longitude),
                                      onTap: onMarkerTap
                                    ),
                                  },
                                  scrollGesturesEnabled: false,
                                  zoomGesturesEnabled: false,
                                ),
                              ),
                            ],
                          ),
                        ),
        
                     
                       
                      ],
                    ),
                  ),
                ),
              ],
            ),
          ),
        ),
 Positioned(
                          top: 35,
                          left: 10,
                          child: GestureDetector(
        
                            onTap: Navigator.of(context).pop,
                            child: SvgPicture.asset(
                              'assets/icons/ic_back.svg',
                              color: Colors.white,
                              width: 30,
                              height: 30,
                            ),
                          ),
                        ),
                  ]);

答案2

得分: 0

你可以通过以下代码来实现它:

Scaffold(
  appBar: AppBar(
    title: Text(widget.title),
  ),
  body: Container(
    color: const Color(0xFFF7F7F7), // 设置颜色
    child: Stack(
      children: [
        Positioned(
          child: SingleChildScrollView(
            child: Column(
              children: [
                // YOUR   MAIN LONG UI CODE WILL BE HERE 
                Image.network(
                  "https://www.imgonline.com.ua/examples/random-pixels-big.png",
                  height: 200,
                  width: double.infinity,
                  fit: BoxFit.fill,
                ),
                Container(
                  height: 100000,
                  color: Colors.red,
                )

                // 返回按钮
              ],
            ),
          ),
        ),
        Positioned(
          top: 35,
          left: 10,
          child: GestureDetector(
            onTap: Navigator.of(context).pop,
            child: Icon(
              Icons.arrow_back_outlined,
              size: 30,
            ),
          ),
        ),
      ],
    ),
  ),
);
英文:

You can achieve it by below code

Scaffold(
  appBar: AppBar(
    title: Text(widget.title),
  ),
  body: Container(
    color: const Color(0xFFF7F7F7), // Set the color
    child: Stack(
      children: [
        Positioned(
          child: SingleChildScrollView(
            child: Column(
              children: [
         // YOUR   MAIN LONG UI CODE WILL BE HERE 
                Image.network(
                  "https://www.imgonline.com.ua/examples/random-pixels-big.png",
                  height: 200,
                  width: double.infinity,
                  fit: BoxFit.fill,
                ),
                Container(
                  height: 100000,
                  color: Colors.red,
                )

                // Back Button
              ],
            ),
          ),
        ),
        Positioned(
          top: 35,
          left: 10,
          child: GestureDetector(
            onTap: Navigator.of(context).pop,
            child: Icon(
              Icons.arrow_back_outlined,
              size: 30,
            ),
          ),
        ),
      ],
    ),
  ),
);

huangapple
  • 本文由 发表于 2023年7月17日 17:35:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/76703157.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定