ListView, содержащий GridViews и ListViews в флаттере - PullRequest
0 голосов
/ 30 октября 2019

Я искал способ достижения этого дизайна, но я не уверен, каков наилучший способ сделать это, я хотел бы знать, как расположить эти списки, используя listview и gridview (который можно изменить напросмотр списка при нажатии на иконку), спасибо

enter image description here

Ответы [ 2 ]

1 голос
/ 30 октября 2019

вы можете использовать щепки, чтобы включить все сетки и списки в одно представление прокрутки.

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget{
  @override
  State<StatefulWidget> createState() {

    return _MyAppState();
  }

}


class _MyAppState extends State<MyApp> {
 bool isGrid = true;
  @override
  Widget build(BuildContext context) {
    return MaterialApp(

      home: Scaffold(
        appBar: AppBar(title: Text('demo'),),
        body: Padding(

          child: CustomScrollView(

            slivers: <Widget>[

              SliverToBoxAdapter(
                child: Container(
                  height: 100.0,
                  child: ListView.builder(
                    scrollDirection: Axis.horizontal,
                    itemCount: 10,
                    itemBuilder: (context, index) {
                      return Container(
                        width: 100.0,
                        child: Card(
                          child: Text('data'),
                        ),
                      );
                    },
                  ),
                ),
              ),
              SliverToBoxAdapter(
         child: Row(
           children: <Widget>[
             Text('choose view method'),
             Row(
               children: <Widget>[
                 IconButton(icon: Icon(Icons.list), onPressed: (){
                   setState(() {
                       isGrid = false;
                   });
                 }, ),

                 IconButton(icon: Icon(Icons.grid_on), onPressed: (){
                   setState(() {
                     isGrid = true;
                   });
                 }, ),

               ],
             )
           ],
         ),
              ),
              ProductsWidget(
                isGrid: isGrid,
              ),

            ],
          ), padding: EdgeInsets.all(20),
        ),
      ),
    );
  }
}

class ProductsWidget extends StatelessWidget {
  final bool isGrid;

  const ProductsWidget({Key key, this.isGrid = true}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return isGrid ? SliverGrid(
      gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
        maxCrossAxisExtent: 200.0,
        mainAxisSpacing: 10.0,
        crossAxisSpacing: 10.0,
        childAspectRatio: 4.0,
      ),
      delegate: SliverChildBuilderDelegate(
            (BuildContext context, int index) {
          return  Container(
            width: 100.0,
            child: Card(
              child: Text('data'),
            ),
          );
        },
        childCount: 50,
      ),
    ) :  SliverList(
        delegate: SliverChildListDelegate(
          [
            Card(child: Text('data'),),
            Card(child: Text('data'),),
            Card(child: Text('data'),),
            Card(child: Text('data'),),
          ],
        ), ) ;


  }
}

enter image description here

1 голос
/ 30 октября 2019

Я думаю, что просто выбрав сетку для нижнего списка и изменив значение делегата childAspectRatio (поскольку элементы сетки явно не имеют явной высоты) и crossAxisCount сделает это.

import 'package:flutter/material.dart';

class Tires extends StatefulWidget {
  @override
  _TiresState createState() => _TiresState();
}

class _TiresState extends State<Tires> {
  var _crossAxisCount = 1;
  var _childAspectRatio = 2.0;

  @override
  Widget build(BuildContext context) {
    final mediaQuery = MediaQuery.of(context);
    final titleStyle = TextStyle(fontWeight: FontWeight.bold);

    return ListView(
      children: <Widget>[
        Padding(
          padding: EdgeInsets.symmetric(horizontal: 16.0),
          child: Text('Hot offer', style: titleStyle),
        ),
        SizedBox(height: 8),
        Container(
          height: mediaQuery.size.height / 4,
          child: ListView.separated(
            shrinkWrap: true,
            padding: EdgeInsets.symmetric(horizontal: 16.0),
            scrollDirection: Axis.horizontal,
            itemCount: 10,
            separatorBuilder: (_, __) => SizedBox(width: 10),
            itemBuilder: (_, __) => SizedBox(
              width: mediaQuery.size.width / 3,
              child: Card(),
            ),
          ),
        ),
        SizedBox(height: 8),
        Padding(
          padding: EdgeInsets.symmetric(horizontal: 16.0),
          child: Row(
            children: <Widget>[
              Text('Hot offer', style: titleStyle),
              Spacer(),
              IconButton(
                icon: Icon(Icons.list),
                onPressed: () => setState(() {
                  _crossAxisCount = _crossAxisCount = 1;
                  _childAspectRatio = _childAspectRatio = 2.0;
                }),
              ),
              IconButton(
                icon: Icon(Icons.grid_on),
                onPressed: () => setState(() {
                  _crossAxisCount = _crossAxisCount = 2;
                  _childAspectRatio = _childAspectRatio = 1.0;
                }),
              ),
            ],
          ),
        ),
        SizedBox(height: 8),
        GridView.builder(
          primary: false,
          shrinkWrap: true,
          padding: EdgeInsets.symmetric(horizontal: 16.0),
          gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
            childAspectRatio: _childAspectRatio,
            crossAxisSpacing: 16,
            mainAxisSpacing: 16,
            crossAxisCount: _crossAxisCount,
          ),
          itemCount: 15,
          itemBuilder: (_, __) => Card(),
        )
      ],
    );
  }
}

An Image of the tires app

...