3

i am trying to show the catalog list in two row within horizontal GridView or ListView
instead of single row the list data comes from server The horizontal ListView working fine with one row How can I achieve this as the GIF bellow ?

bellow image what i have

bellow gif what i need

enter image description here [the ListView as needed1

below full code The horizontal ListView which is working fine with one row and i need to convert it to GridView so it can show two row and horizontal scrollable

_catList() {
return Container(
  height: 150,
  child: ListView.builder(
    itemCount: catList.length < 10 ? catList.length : 10,
    scrollDirection: Axis.horizontal,
    shrinkWrap: true,
    physics: AlwaysScrollableScrollPhysics(),
    itemBuilder: (context, index) {
      return Padding(
        padding: const EdgeInsetsDirectional.only(end: 10),
        child: GestureDetector(
          onTap: () async {
            if (catList[index].subList == null ||
                catList[index].subList.length == 0) {
              await Navigator.push(
                  context,
                  MaterialPageRoute(
                    builder: (context) => ProductList(
                        name: catList[index].name,
                        id: catList[index].id,
                        tag: false,
                        updateHome: widget.updateHome),
                  ));
              if (mounted) setState(() {});
            } else {
              await Navigator.push(
                  context,
                  MaterialPageRoute(
                    builder: (context) => SubCat(
                        title: catList[index].name,
                        subList: catList[index].subList,
                        updateHome: widget.updateHome),
                  ));
              if (mounted) setState(() {});
            }
          },
          child: Column(
            mainAxisAlignment: MainAxisAlignment.start,
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
              Padding(
                padding: const EdgeInsetsDirectional.only(bottom: 5.0),
                child: new ClipRRect(
                  borderRadius: BorderRadius.circular(25.0),
                  child: new FadeInImage(
                    fadeInDuration: Duration(milliseconds: 50),
                    image: NetworkImage(
                      catList[index].image,
                    ),
                    height: 100.0,
                    width: 100.0,
                    fit: BoxFit.cover,
                    imageErrorBuilder: (context, error, stackTrace) =>
                        erroWidget(100),

                    //  errorWidget: (context, url, e) => placeHolder(50),
                    placeholder: placeHolder(100),
                  ),
                ),
              ),
              Container(
                child: Text(
                  catList[index].name,
                  style: Theme.of(context).textTheme.caption.copyWith(
                      color: colors.fontColor,
                      fontWeight: FontWeight.w600,
                      fontSize: 15),
                  overflow: TextOverflow.ellipsis,
                  textAlign: TextAlign.center,
                ),
                width: 100,
              ),
            ],
          ),
        ),
      );
    },
  ),
);

}

3 Answers 3

4

You can use grid view to archive this thing. Here is a snippet of the configuration.

GridView.count(
                  shrinkWrap: true,
                  crossAxisCount: 2,
                  physics: const ClampingScrollPhysics(),
                  scrollDirection: Axis.horizontal,
                  crossAxisSpacing: 10,
                  mainAxisSpacing: 20,
                  children: ...)

Here crossAxisCount: 2,scrollDirection: Axis.horizontal is what you need.

Sign up to request clarification or add additional context in comments.

5 Comments

this working if i use " scrollDirection: Axis.vertical," but with " scrollDirection: Axis.horizontal," show blank page
finally it working the issue was the "height: 250," not include within GridView.count()
Good but this would be one of the better approaches since mention 250 height maybe vary depends on device dp.
you mean the fixed height is not recommended , if yes what is better
Get size from MediaQuery or use GridView
1

You can either use ListView.builder with itemCount: catList.length/2 and return a Column with two items (index and index+1)

or use GridView.count:

Container(
  height: 150,
  child: GridView.count(
    shrinkWrap: true,
    scrollDirection: Axis.horizontal,
    crossAxisCount: 2,
    children: catList.isEmpty ? [Container()] : catList.map((cat) {
      return Padding(
        padding: const EdgeInsetsDirectional.only(end: 10),
         child: GestureDetector(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.start,
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
              Padding(
                padding: const EdgeInsetsDirectional.only(bottom: 5.0),
                child: new ClipRRect(
                  borderRadius: BorderRadius.circular(25.0),
                  child: new FadeInImage(
                    fadeInDuration: Duration(milliseconds: 50),
                    image: NetworkImage(
                      cat.image,
                    ),
                    height: 100.0,
                    width: 100.0,
                    fit: BoxFit.cover,
                    imageErrorBuilder: (context, error, stackTrace) =>
                        erroWidget(100),
                    placeholder: placeHolder(100),
                  ),
                ),
              ),
              Container(
                child: Text(
                  cat.name,
                  style: Theme.of(context).textTheme.caption.copyWith(
                      color: colors.fontColor,
                      fontWeight: FontWeight.w600,
                      fontSize: 15),
                  overflow: TextOverflow.ellipsis,
                  textAlign: TextAlign.center,
                ),
                width: 100,
              ),
            ],
          ),
        ),
      );
    }).toList(),
  ),
);

9 Comments

it show error Colum's children must not contain any null values , but a null value was found at index 3
can u post the catList values? Also, are you using GridView or ListView (with a 2 rows column)?
i have edit the post with full current code
can I see how did you try to implement it with GridView instead of ListView?
itemCount: catList.length/2 and return a Column with two items (index and index+1) will give duplicated items (1,2,2,3,3,4,4,5,5,6,6,error) so i tried GridView.count as your above code but its show error " Colum's children must not contain any null values , but a null value was found at index 3 "
|
0

i liked @pedro pimont approach.

Now i can render multiple row in horizontal list view with minimal code. This is working example.

int itemCount = 12;
int divison = 2;
SizedBox(
              height: MediaQuery.of(context).size.height * .35,
              child: ListView.separated(
                separatorBuilder: (_, __) => const SizedBox(width: 20),
                scrollDirection: Axis.horizontal,
                itemCount: itemCount ~/ divison,
                itemBuilder: (context, index) {
                  return Column(
                    children: [
                      productItem((itemCount ~/ divison) * 0 + index),
                      productItem((itemCount ~/ divison) * 1 + index),
                    ],
                  );
                },
              ),
            )

Widget productItem(int index) => Card(
        color: Colors.grey[50],
        elevation: 1,
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(5.0),
        ),
        child: Column(
          children: [
            SizedBox(
              height: 80,
              child: Card(
                elevation: 0,
                margin: EdgeInsets.zero,
                semanticContainer: true,
                color: secondaryLight,
                clipBehavior: Clip.antiAliasWithSaveLayer,
                shape: const RoundedRectangleBorder(
                  borderRadius: BorderRadius.only(
                      topLeft: Radius.circular(5),
                      topRight: Radius.circular(5)),
                ),
                child: CachedNetworkImage(
                  imageUrl: 'https://picsum.photos/250?image=9',
                  fit: BoxFit.cover,
                ),
              ),
            ),
            Text("${index + 1}"),
          ],
        ),
      );

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.