flutter 如何使用Gridview.builder的“隐藏滚动视图”

daolsyd0  于 2023-03-31  发布在  Flutter
关注(0)|答案(4)|浏览(166)

我在顶部使用Singlechildscrollview,列作为第一个子级。在Column中我使用DefaultTabController,在Tabview中我使用gridview.builder。Gridview构建器可以有任何不同数量的产品。如何给予它动态高度,因为TabBarView总是需要固定高度
代码部分:

import 'package:flutter/material.dart';

class TestScreen extends StatefulWidget {
  const TestScreen({Key? key}) : super(key: key);

  @override
  State<TestScreen> createState() => _TestScreenState();
}

class _TestScreenState extends State<TestScreen> {
  var indexSelected = 0;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      bottomSheet: Container(
        padding: const EdgeInsets.symmetric(horizontal: 0.0, vertical: 16.0),
        child: ElevatedButton(
          style: ElevatedButton.styleFrom(
              padding:
                  const EdgeInsets.symmetric(horizontal: 25.0, vertical: 16.0),
              primary: Theme.of(context).primaryColor,
              shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(25.0))),
          onPressed: () {},
          child: Row(
              crossAxisAlignment: CrossAxisAlignment.center,
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: <Widget>[
                Row(
                  crossAxisAlignment: CrossAxisAlignment.center,
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Container(
                        padding: const EdgeInsets.symmetric(
                            vertical: 2, horizontal: 8.0),
                        width: 24.0,
                        height: 24.0,
                        decoration: const BoxDecoration(
                          color: Colors.black,
                          shape: BoxShape.circle,
                        ),
                        child: Text('fasdfa',
                            textAlign: TextAlign.center,
                            style: Theme.of(context)
                                .textTheme
                                .button!
                                .copyWith(color: Colors.white))),
                    const SizedBox(width: 8.0),
                    Text('USD 1000',
                        textAlign: TextAlign.center,
                        style: Theme.of(context).textTheme.button)
                  ],
                ),
                Text('NEXT',
                    textAlign: TextAlign.center,
                    style: Theme.of(context).textTheme.button)
              ]),
        ),
      ),
      body: SafeArea(
        child: SingleChildScrollView(
          child: Column(
            children: [
              Padding(
                /** header */
                padding: const EdgeInsets.only(top: 14, bottom: 10),
                child: Container(
                  height: 60,
                  padding: const EdgeInsets.symmetric(
                      horizontal: 15.0, vertical: 0.0),
                  width: MediaQuery.of(context).size.width * 1,
                  color: Colors.blue,
                ),
              ),
              Container(
                color: Colors.white,
                width: MediaQuery.of(context).size.width,
                child: Column(
                  children: [
                    const SizedBox(
                      width: 0,
                      height: 0,
                    ),
                    Padding(
                      padding: const EdgeInsets.only(top: 4.0),
                      child: Column(
                        //_buildContent
                        children: [
                          Stack(
                            children: <Widget>[
                              Column(
                                children: <Widget>[
                                  Container(
                                    width:
                                        MediaQuery.of(context).size.width * 1,
                                    height: 200,
                                    color: Colors.yellow,
                                  ),
                                ],
                              ),
                              Positioned(
                                top: MediaQuery.of(context).size.height * 0.265,
                                right: 20,
                                child: ElevatedButton(
                                  style: ElevatedButton.styleFrom(
                                      shape: const CircleBorder(),
                                      primary: Colors.white),
                                  onPressed: () {},
                                  child: Container(
                                    color: Colors.blue,
                                    width: 10,
                                    height: MediaQuery.of(context).size.height *
                                        0.055,
                                  ),
                                ),
                              )
                            ],
                          ),
                          const Tabss(),
                        ],
                      ),
                    ),
                  ],
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class Tabss extends StatefulWidget {
  const Tabss({Key? key}) : super(key: key);

  @override
  _TabssState createState() => _TabssState();
}

class _TabssState extends State<Tabss> {
  var indexSelected = 0;
  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 25.0, vertical: 0.0),
      color: Colors.red,
      child: DefaultTabController(
        length: 1,
        child: Container(
          color: Colors.white,
          //primary: false,
          child: Column(
            children: [
              TabBar(
                onTap: (a) {
                  setState(() {});
                },
                labelStyle: Theme.of(context)
                    .textTheme
                    .button!
                    .copyWith(fontWeight: FontWeight.normal),
                unselectedLabelStyle: Theme.of(context)
                    .textTheme
                    .subtitle1!
                    .copyWith(fontSize: 14),
                isScrollable: true,
                labelPadding:
                    const EdgeInsets.symmetric(horizontal: 10.0, vertical: 6.0),
                indicatorWeight: 4,
                indicatorColor: Colors.blue,
                indicatorSize: TabBarIndicatorSize.label,
                tabs: List.generate(
                  1,
                  (index) => const Text(
                    'TESTING',
                    style: TextStyle(
                      color: Colors.black,
                    ),
                  ),
                ),
              ),
              Expanded(
                child: TabBarView(
                  children: List.generate(
                    1,
                    (index) {
                      return GridView.builder(
                          shrinkWrap: true,
                          // FOR FOOD AND DECO
                          physics: const NeverScrollableScrollPhysics(),
                          itemCount: 30,
                          gridDelegate:
                              const SliverGridDelegateWithFixedCrossAxisCount(
                                  childAspectRatio: 0.95,
                                  crossAxisSpacing: 15.0,
                                  mainAxisSpacing: 10.0,
                                  mainAxisExtent: 180,
                                  crossAxisCount: 2),
                          itemBuilder: (BuildContext context, int index) {
                            return Container(
                              color: Colors.red,
                              alignment: Alignment.center,
                              child: Text(
                                index.toString(),
                              ),
                            );
                          });
                    },
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
bfhwhh0e

bfhwhh0e1#

嗨,请试试这个-

Expanded(
            child: GridView.builder(
            
            primary: false,
            shrinkWrap: true,
            physics: const NeverScrollableScrollPhysics(),
            itemCount: dataList.length,
            gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                childAspectRatio: 0.95,
                crossAxisSpacing: 15.0,
                mainAxisSpacing: 10.0,
                mainAxisExtent: 200,
                crossAxisCount: 2),
          )
zengzsys

zengzsys2#

如果你想用一个Expanded Package TabBarView以给予其具有固定的高度,因为你已经嵌套了Column s,你应该用一个Expanded Package Column中的所有TabBarView父节点。
通过这种方式,你可以让GridView.builder滚动!所以你不需要SingleChildScrollView!你的代码将是这样的:

import 'package:flutter/material.dart';

class TestScreen extends StatefulWidget {
  const TestScreen({Key? key}) : super(key: key);

  @override
  State<TestScreen> createState() => _TestScreenState();
}

class _TestScreenState extends State<TestScreen> {
  var indexSelected = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      bottomSheet: Container(
        padding: const EdgeInsets.symmetric(horizontal: 0.0, vertical: 16.0),
        child: ElevatedButton(
          style: ElevatedButton.styleFrom(
              padding:
                  const EdgeInsets.symmetric(horizontal: 25.0, vertical: 16.0),
              primary: Theme.of(context).primaryColor,
              shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(25.0))),
          onPressed: () {},
          child: Row(
              crossAxisAlignment: CrossAxisAlignment.center,
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: <Widget>[
                Row(
                  crossAxisAlignment: CrossAxisAlignment.center,
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Container(
                        padding: const EdgeInsets.symmetric(
                            vertical: 2, horizontal: 8.0),
                        width: 24.0,
                        height: 24.0,
                        decoration: const BoxDecoration(
                          color: Colors.black,
                          shape: BoxShape.circle,
                        ),
                        child: Text('fasdfa',
                            textAlign: TextAlign.center,
                            style: Theme.of(context)
                                .textTheme
                                .button!
                                .copyWith(color: Colors.white))),
                    const SizedBox(width: 8.0),
                    Text('USD 1000',
                        textAlign: TextAlign.center,
                        style: Theme.of(context).textTheme.button)
                  ],
                ),
                Text('NEXT',
                    textAlign: TextAlign.center,
                    style: Theme.of(context).textTheme.button)
              ]),
        ),
      ),
      body: SafeArea(
        child: Column(
          children: [
            Padding(
              /** header */
              padding: const EdgeInsets.only(top: 14, bottom: 10),
              child: Container(
                height: 60,
                padding:
                    const EdgeInsets.symmetric(horizontal: 15.0, vertical: 0.0),
                width: MediaQuery.of(context).size.width * 1,
                color: Colors.blue,
              ),
            ),
            Expanded(
              child: Container(
                color: Colors.white,
                width: MediaQuery.of(context).size.width,
                child: Padding(
                  padding: const EdgeInsets.only(top: 4.0),
                  child: Column(
                    //_buildContent
                    children: [
                      Stack(
                        children: <Widget>[
                          Column(
                            children: <Widget>[
                              Container(
                                width: MediaQuery.of(context).size.width * 1,
                                height: 200,
                                color: Colors.yellow,
                              ),
                            ],
                          ),
                          Positioned(
                            top: MediaQuery.of(context).size.height * 0.265,
                            right: 20,
                            child: ElevatedButton(
                              style: ElevatedButton.styleFrom(
                                  shape: const CircleBorder(),
                                  primary: Colors.white),
                              onPressed: () {},
                              child: Container(
                                color: Colors.blue,
                                width: 10,
                                height:
                                    MediaQuery.of(context).size.height * 0.055,
                              ),
                            ),
                          )
                        ],
                      ),
                      const Expanded(child: Tabss()),
                    ],
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class Tabss extends StatefulWidget {
  const Tabss({Key? key}) : super(key: key);

  @override
  _TabssState createState() => _TabssState();
}

class _TabssState extends State<Tabss> {
  var indexSelected = 0;

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 25.0, vertical: 0.0),
      color: Colors.red,
      child: DefaultTabController(
        length: 3,
        child: Container(
          color: Colors.white,
          //primary: false,
          child: Column(
            children: [
              TabBar(
                onTap: (a) {
                  setState(() {});
                },
                labelStyle: Theme.of(context)
                    .textTheme
                    .button!
                    .copyWith(fontWeight: FontWeight.normal),
                unselectedLabelStyle: Theme.of(context)
                    .textTheme
                    .subtitle1!
                    .copyWith(fontSize: 14),
                isScrollable: true,
                labelPadding:
                    const EdgeInsets.symmetric(horizontal: 10.0, vertical: 6.0),
                indicatorWeight: 4,
                indicatorColor: Colors.blue,
                indicatorSize: TabBarIndicatorSize.label,
                tabs: List.generate(
                  3,
                  (index) => const Text(
                    'TESTING',
                    style: TextStyle(
                      color: Colors.black,
                    ),
                  ),
                ),
              ),
              Expanded(
                child: TabBarView(
                  children: List.generate(
                    3,
                    (index) {
                      return GridView.builder(
                        shrinkWrap: true,
                        // FOR FOOD AND DECO
                        itemCount: 30,
                        gridDelegate:
                            const SliverGridDelegateWithFixedCrossAxisCount(
                                childAspectRatio: 0.95,
                                crossAxisSpacing: 15.0,
                                mainAxisSpacing: 10.0,
                                mainAxisExtent: 180,
                                crossAxisCount: 2),
                        itemBuilder: (BuildContext context, int index) {
                          return Container(
                            color: Colors.red,
                            alignment: Alignment.center,
                            child: Text(
                              index.toString(),
                            ),
                          );
                        },
                      );
                    },
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
tzcvj98z

tzcvj98z3#

"你会试试这个"

class TestScreen extends StatefulWidget {
  const TestScreen({Key? key}) : super(key: key);

  @override
  State<TestScreen> createState() => _TestScreenState();
}

class _TestScreenState extends State<TestScreen> {
  var indexSelected = 0;

  @override
Widget build(BuildContext context) {
  return Scaffold(
    bottomSheet: ElevatedButton(
    style: ElevatedButton.styleFrom(
        padding:
        const EdgeInsets.symmetric(horizontal: 25.0, vertical: 16.0),
        primary: Theme.of(context).primaryColor,
        shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(25.0))),
    onPressed: () {},
    child: Row(
        crossAxisAlignment: CrossAxisAlignment.center,
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: <Widget>[
          Row(
            crossAxisAlignment: CrossAxisAlignment.center,
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Container(
                  padding: const EdgeInsets.symmetric(
                      vertical: 2, horizontal: 8.0),
                  width: 24.0,
                  height: 24.0,
                  decoration: const BoxDecoration(
                    color: Colors.black,
                    shape: BoxShape.circle,
                  ),
                  child: Text('fasdfa',
                      textAlign: TextAlign.center,
                      style: Theme.of(context)
                          .textTheme
                          .button!
                          .copyWith(color: Colors.white))),
              const SizedBox(width: 8.0),
              Text('USD 1000',
                  textAlign: TextAlign.center,
                  style: Theme.of(context).textTheme.button)
            ],
          ),
          Text('NEXT',
              textAlign: TextAlign.center,
              style: Theme.of(context).textTheme.button)
        ]),
    ),
    body: SafeArea(
     child: Column(
      children: [
        Padding(
          /** header */
          padding: const EdgeInsets.only(top: 14, bottom: 10),
          child: Container(
            height: 60,
            padding:
            const EdgeInsets.symmetric(horizontal: 15.0, vertical: 0.0),
            width: MediaQuery.of(context).size.width * 1,
            color: Colors.blue,
          ),
        ),
        Expanded(
          child: Container(
            color: Colors.white,
            width: MediaQuery.of(context).size.width,
            child: Padding(
              padding: const EdgeInsets.only(top: 4.0),
              child: Column(
                //_buildContent
                children: [
                  Stack(
                    children: <Widget>[
                      Column(
                        children: <Widget>[
                          Container(
                            width: MediaQuery.of(context).size.width * 1,
                            height: 200,
                            color: Colors.yellow,
                          ),
                        ],
                      ),
                      Positioned(
                        top: MediaQuery.of(context).size.height * 0.265,
                        right: 20,
                        child: ElevatedButton(
                          style: ElevatedButton.styleFrom(
                              shape: const CircleBorder(),
                              primary: Colors.white),
                          onPressed: () {},
                          child: Container(
                            color: Colors.blue,
                            width: 10,
                            height:
                            MediaQuery.of(context).size.height * 0.055,
                          ),
                        ),
                      )
                    ],
                  ),
                  const Expanded(child: Tabss()),
                ],
              ),
            ),
          ),
        ),
      ],
    ),
   ),
  );
 }
}

class Tabss extends StatefulWidget {
  const Tabss({Key? key}) : super(key: key);

  @override
 _TabssState createState() => _TabssState();
}

class _TabssState extends State<Tabss> {
  var indexSelected = 0;

  @override
Widget build(BuildContext context) {
 return DefaultTabController(
  length: 3,
  child: Column(
    children: [
      TabBar(
        onTap: (a) {
          setState(() {});
        },
        labelStyle: Theme.of(context)
            .textTheme
            .button!
            .copyWith(fontWeight: FontWeight.normal),
        unselectedLabelStyle: Theme.of(context)
            .textTheme
            .subtitle1!
            .copyWith(fontSize: 14),
        isScrollable: true,
        labelPadding:
        const EdgeInsets.symmetric(horizontal: 10.0, vertical: 6.0),
        indicatorWeight: 4,
        indicatorColor: Colors.blue,
        indicatorSize: TabBarIndicatorSize.label,
        tabs: List.generate(
          3,
              (index) => const Text(
            'TESTING',
            style: TextStyle(
              color: Colors.black,
            ),
          ),
        ),
      ),
      Flexible(
        flex: 6,
        child: TabBarView(
          children: List.generate(
            3,
                (index) {
              return Padding(
                padding: const EdgeInsets.all(8.0),
                child: GridView.builder(
                  shrinkWrap: true,
                  // FOR FOOD AND DECO
                  itemCount: 30,
                  gridDelegate:
                  const SliverGridDelegateWithFixedCrossAxisCount(
                      childAspectRatio: 0.95,
                      crossAxisSpacing: 15.0,
                      mainAxisSpacing: 10.0,
                      mainAxisExtent: 180,
                      crossAxisCount: 2),
                  itemBuilder: (BuildContext context, int index) {
                    return Container(
                      color: Colors.red,
                      alignment: Alignment.center,
                      child: Text(
                        index.toString(),
                      ),
                    );
                  },
                ),
              );
            },
          ),
        ),
      ),
      const Spacer(),
    ],
   ),
 );
}
}
osh3o9ms

osh3o9ms4#

也许有点晚了,但我现在正在尝试同样的事情,我已经找到了一个解决方案,从这里的一些答案开始。请注意,我已经添加了一些我正在为我的应用程序使用的代码行,但这是我用来使其工作的一些代码。

Expanded(
    child:SingleChildScrollView(
        physics: BouncingScrollPhysics(),
        child: GridView.builder(
            primary: false,
            physics: const NeverScrollableScrollPhysics(),
            shrinkWrap: true,
            gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                childAspectRatio: 1.4,
                crossAxisCount: 2, 
                mainAxisSpacing: 1, 
                crossAxisSpacing: 1,
            )
        )
    )
)

相关问题