flutterdartshimmer

Can I create Shimmer container with other containers in it?


I am using shimmer package for creating a loading page. This is how it looks:

Shimmer I created

I want to create the shimmer boxes like this:

Shimmer I want to create

My code:

class _Shimmer extends StatelessWidget {
  const _Shimmer();

  @override
  Widget build(BuildContext context) {
    return Shimmer.fromColors(
      baseColor: Colors.grey.shade300,
      highlightColor: Colors.grey.shade100,
      enabled: true,
      child: SingleChildScrollView(
        physics: const NeverScrollableScrollPhysics(),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          mainAxisSize: MainAxisSize.max,
          children: [
            const SizedBox(height: 40),
            ...List.generate(
              10,
              (index) => const Column(
                children: [
                  _CardPlaceHolder(),
                  SizedBox(height: 16),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class _CardPlaceHolder extends StatelessWidget {
  const _CardPlaceHolder({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        Container(
          width: double.infinity,
          height: 86,
          decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(18.0),
            color: Colors.white,
          ),
        ),
      ],
    );
  }
}

When I add another container as the main container's child, it doesn't shown. Is there a way to create this with the package or should I create a new shimmer widget?


Solution

  • Picked this from the Shimmer package's example folder and modified it a little. You can replace your _CardPlaceHolder code with this

    class ContentPlaceholder extends StatelessWidget {
      // final ContentLineType lineType;
    
      const ContentPlaceholder({
        Key? key,
        // required this.lineType,
      }) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Padding(
          padding: const EdgeInsets.symmetric(horizontal: 16.0),
          child: Container(
            width: double.infinity,
            height: 86,
            decoration: BoxDecoration(
              borderRadius: BorderRadius.circular(18.0),
              color: Colors.white.withOpacity(.4),
            ),
            padding: const EdgeInsets.symmetric(vertical: 6.0),
            child: Padding(
              padding: const EdgeInsets.symmetric(horizontal: 16.0),
              child: Row(
                mainAxisSize: MainAxisSize.max,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  Container(
                    width: 96.0,
                    height: 72.0,
                    decoration: BoxDecoration(
                      borderRadius: BorderRadius.circular(18.0),
                      color: Colors.white,
                    ),
                  ),
                  const SizedBox(width: 12.0),
                  Expanded(
                    child: Column(
                      mainAxisSize: MainAxisSize.min,
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Container(
                          width: 100.0,
                          height: 10.0,
                          decoration: BoxDecoration(
                            borderRadius: BorderRadius.circular(18.0),
                            color: Colors.white,
                          ),
                          margin: const EdgeInsets.only(bottom: 8.0),
                        ),
                        Container(
                          width: double.infinity,
                          height: 10.0,
                          decoration: BoxDecoration(
                            borderRadius: BorderRadius.circular(18.0),
                            color: Colors.white,
                          ),
                          margin: const EdgeInsets.only(bottom: 8.0),
                        ),
                        // if (lineType == ContentLineType.threeLines)
                        Container(
                          width: double.infinity,
                          height: 10.0,
                          decoration: BoxDecoration(
                            borderRadius: BorderRadius.circular(18.0),
                            color: Colors.white,
                          ),
                          margin: const EdgeInsets.only(bottom: 8.0),
                        ),
                      ],
                    ),
                  )
                ],
              ),
            ),
          ),
        );
      }
    }