ClipRect Code Sample (2)

一个带自动下滑的菜单,共有3个layer, 在往下滑动的时候,中间图层会慢慢融化掉。


import 'package:flutter/material.dart';

void main(List<String> args) {

  runApp(const MaterialApp(

    home: HomePage(),

  ));

}

class HomePage extends StatefulWidget {

  const HomePage({super.key});

  @override

  State<HomePage> createState() => _HomePageState();

}

class _HomePageState extends State<HomePage> {

  @override

  Widget build(BuildContext context) {

    return const Scaffold(

      body: LayerWidget(),

    );

  }

}

class LayerWidget extends StatefulWidget {

  const LayerWidget({super.key});

  @override

  State<LayerWidget> createState() => _LayerWidgetState();

}

class DropdownMenuClipper extends CustomClipper<Rect> {

  late double startPos;

  DropdownMenuClipper(this.startPos);

  @override

  Rect getClip(Size size) {

    return Rect.fromLTRB(0, startPos, size.width, size.height);

  }

  @override

  bool shouldReclip(covariant CustomClipper<Rect> oldClipper) {

    return this != oldClipper;

  }

}

class _LayerWidgetState extends State<LayerWidget> {

  bool move = false; // 是否已经按下

  double y = 0; // 滑动距离

  bool down = false; // 是否越过中线,如果已经越过中线,则本次滑动认为已经可以自动滑到底部

  void releaseDropAction() {

    move = false;

    if (down) {

      setState(() {

        y = 700;

      });

    } else {

      setState(() {

        y = 0;

      });

    }

  }

  @override

  Widget build(BuildContext context) {

    return Container(

      constraints: const BoxConstraints.tightFor(width: 1280, height: 720),

      child: Stack(

        fit: StackFit.expand,

        children: [

          // background

          Container(

            constraints: const BoxConstraints.expand(),

            child: ListView.builder(

              itemBuilder: (context, index) {

                return Container(

                  alignment: Alignment.centerRight,

                  height: 30,

                  color: Colors.primaries[index % Colors.primaries.length]

                      .withOpacity(0.8),

                  child: Text(

                    "BACKGROUND -- $index -- BACKGROUND",

                    style: const TextStyle(color: Colors.white60),

                  ),

                );

              },

            ),

          ),

          // middle layer

          Container(

            constraints:

                const BoxConstraints.tightFor(width: 1280, height: 720),

            child: ClipRect(

              clipper: DropdownMenuClipper(y),

              child: Opacity(

                opacity: 0.6,

                child: Image.network(

                  "https://ts1.cn.mm.bing.net/th/id/R-C.e51b145d53c430c25c12f6f85bf948a2?rik=InKJPw4ksMoeMw&riu=http%3a%2f%2fwallpaperping.com%2fwp-content%2fuploads%2f2018%2f12%2fBluebirdTotemMeaning.jpg&ehk=NSr%2bPl1FfAgYVt%2fBU4xF%2fsd0p8%2fm6SuScV%2fN59zvKwI%3d&risl=&pid=ImgRaw&r=0",

                  fit: BoxFit.fitWidth,

                ),

              ),

            ),

          ),

          //uplayer

          Positioned(

            top: -700 + y,

            child: GestureDetector(

              onPanDown: (details) => move = true,

              onPanCancel: () => releaseDropAction(),

              onPanEnd: (_) => releaseDropAction(),

              onPanUpdate: (details) {

                setState(() {

                  y = y + details.delta.dy;

                  if (y > 720) {

                    y = 720;

                  }

                  if (y > 720 / 2) {

                    down = true;

                  } else {

                    down = false;

                  }

                });

              },

              child: Container(

                constraints:

                    const BoxConstraints.tightFor(width: 1280, height: 720),

                child: ListView.builder(

                  itemBuilder: (context, index) {

                    return ListTile(

                      title: Center(

                        child: Text("UPPER_LAYER -- $index -- UPPER_LAYER"),

                      ),

                    );

                  },

                  itemCount: 200,

                ),

              ),

            ),

          )

        ],

      ),

    );

  }

}


©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容