0

Is it possible to have a specific item in a gridview.builder that is bigger than the others and is overlapping them like in the image down below in Flutter?

I tried adding the child aspect ratio but its not specific for a child and i cant access the index to make a function call with it. If i try to change the width and height of the container manually it gives me a "RenderFlex overflowed" error

I also tried replacing the specific child by doing

child: selectedIndex != index ? Dice(index: index) : Dice2(index: index)

but thats not working eiger because of the child aspect ratio i guess. But even after removing the ratio i still cant change the width or height manually.

This is my code:

import 'dart:collection';

import 'package:bordered_text/bordered_text.dart';
import 'package:flutter/material.dart';
import 'package:lottie/lottie.dart';
import 'package:randomdice2/declarations/constants.dart';
import 'package:randomdice2/functions/functions.dart';

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

  @override
  State<GreenScreen> createState() => _GreenScreenState();
}

class _GreenScreenState extends State<GreenScreen> {
  bool showingOriginalWidget = true;
  int selectedIndex = -1;

  @override
  Widget build(BuildContext context) {
    var size = MediaQuery.of(context).size;
    final double itemHeight = (size.height - kToolbarHeight - 24) / 2.5;
    final double itemWidth = size.width / 2;
    return Stack(
      fit: StackFit.expand,
      children: [
        Lottie.asset("assets/lottie/background.json", fit: BoxFit.cover),
        Column(
          children: [
            ElevatedButton(onPressed: () {}, child: const Text("Press me")),
            Expanded(
              child: Padding(
                padding:
                    const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
                child: GridView.builder(
                  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                    crossAxisCount: 4,
                    mainAxisSpacing: 10,
                    crossAxisSpacing: 10,
                    childAspectRatio: (itemWidth / itemHeight),
                  ),
                  itemCount: dices.length,
                  itemBuilder: (BuildContext context, int index) {
                    return GestureDetector(
                      onTap: () {
                        setState(() {
                          if (selectedIndex == index) {
                            selectedIndex = -1;
                          } else {
                            selectedIndex = index;
                          }
                        });
                      },
                      child: Container(
                        height: 120, // cant set this, neither width
                        decoration: BoxDecoration(
                          color: getColor2(index),
                          border: Border.all(color: Colors.transparent),
                          borderRadius:
                              const BorderRadius.all(Radius.circular(4)),
                          boxShadow: const [
                            BoxShadow(
                              color: Colors.black,
                              blurRadius: 2.0,
                              spreadRadius: 0.0,
                              offset: Offset(0, 1),
                            )
                          ],
                        ),
                        child: Column(
                          children: [
                            Container(
                              height: 80,
                              width: 80,
                              color: getColor(index),
                              child: Image.asset(
                                'assets/dice/174x192/${dices.keys.elementAt(index)}',
                                scale: 3,
                              ),
                            ),
                            Padding(
                              padding: const EdgeInsets.all(3.0),
                              child: BorderedText(
                                strokeWidth: 3,
                                child: const Text(
                                  "Class 10",
                                  style: TextStyle(color: Colors.white),
                                ),
                              ),
                            ),
                            const Padding(
                              padding: EdgeInsets.all(3.0),
                              child: ClipRRect(
                                borderRadius: BorderRadius.all(
                                  Radius.circular(4),
                                ),
                                child: LinearProgressIndicator(
                                  value: 0.5,
                                  color: Color(0xff55bef3),
                                  backgroundColor: Color(0xff2b2b2b),
                                  minHeight: 15,
                                ),
                              ),
                            )
                          ],
                        ),
                      ),
                    );
                  },
                ),
              ),
            ),
            ElevatedButton(
                onPressed: () {
                  setState(() {
                    selectedIndex = -1;
                    dices = LinkedHashMap.fromEntries(
                        dices.entries.toList().reversed);
                  });
                },
                child: const Text("Press me")),
          ],
        ),
      ],
    );
  }
}

How i want it - Example

2 Answers2

0

Inside the item builder make the child's container dimensions differ according to the property that specified which item to zoom: something like this:

itemBuilder: (context, index) {

    return Container(
     height: items[index].pro == "special" ? 120:50 ,
     width: items[index].pro == "special" ? 70:30 ,

    );
  },
Reham Alraee
  • 139
  • 8
0

This is the demo code, you can apply to your code and try:

      OverlayEntry overlayEntry;

      Rect getWidget(GlobalKey key){
        final renderObject = key.currentContext?.findRenderObject();
        final translation = renderObject?.getTransformTo(null).getTranslation();
        if (translation != null && renderObject?.paintBounds != null) {
          final offset = Offset(translation.x, translation.y);
          return renderObject.paintBounds.shift(offset);
        } else {
          return null;
        }
      }

// overylay a scaled current widget
            child: GridView.builder(
              gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 3,
                childAspectRatio: 2/3,
              ),
              itemCount: 30,
              itemBuilder: (context, index) {
                final containerKey = GlobalKey();
                final LayerLink _layerLink = LayerLink();

                return GestureDetector(
                  onTap: () {
                    overlayEntry?.remove();
                    
                    Rect _obj = getWidget(containerKey);

                    overlayEntry = OverlayEntry(
                      builder: (context) {
                        return Positioned(
                          top: _obj.top,
                          left: _obj.left,
                          child: CompositedTransformFollower(
                            link: _layerLink,
                            showWhenUnlinked: false,
                            child: Transform.scale(
                              scale: 1.2,
                              child: Container(
                                width: _obj.width,
                                height: _obj.height,
                                color: Colors.blue,
                                child: Center(
                                  child: Icon(Icons.settings),
                                ),
                              ),
                            ),
                          ),
                        );
                      },
                    );
                    Overlay.of(context).insert(overlayEntry);
                  },
                  child: CompositedTransformTarget(
                    link: _layerLink,
                    child: Container(
                      key: containerKey,
                      color: Colors.red,
                      child: Center(
                        child: Icon(Icons.settings),
                      ),
                    ),
                  ),
                );
              },
            ),
Jim
  • 6,928
  • 1
  • 7
  • 18