Milie
Milie

Reputation: 435

How to use ListView and stop element from scrolling?

I have a screen with a ListView that holds an SVG, Stack and TextFields. When the keyboard is opened, I get the usual Overflow error so I'm using a ListView to combat it since I'm using a Column anyway.

I want my SVG image to stay fixed at the top while the rest scrolls underneath it, anyway to give the image a fixed position?

child: Scaffold(
        body: SafeArea(
          child: Container(
              padding: const EdgeInsets.symmetric(horizontal: 32.0),
              width: double.infinity,
              child: ListView(
                children: [
                  const SizedBox(
                    height: 50,
                  ),
                  SvgPicture.asset( //Should stay fixed while rest scroll
                    'assets/example.svg',
                    color: primaryColor,
                    height: 80.0,
                  ),
                  const SizedBox(height: 50),
                  Center(
                    child: Stack(
                      children: [
                        _image != null
                            ? InkWell(
                          onTap: selectImage,
                          child: CircleAvatar(
                            radius: 48,
                            backgroundImage: MemoryImage(_image!),
                          ),
                        )
                            : InkWell(
                          onTap: selectImage,
                          child: const CircleAvatar(
                            radius: 48,
                            backgroundImage: AssetImage('assets/user.png'),
                          ),
                        ),
                        Positioned(
                          bottom: -10,
                          left: 50,
                          child: IconButton(
                            onPressed: selectImage,
                            icon: const Icon(Icons.add_a_photo_outlined),
                          ),
                        ),
                      ],
                    ),
                  ),
                  const SizedBox(height: 50),
                  TextFieldInput(...),
                  TextFieldInput(...),
                  TextFieldInput(...),
                  TextFieldInput(...)...

I've tried taking the SVG out of the Column and changing the ListView into a Column with a SingleChildScrollView parent and I still get Render Overflow. Code follows:

child: Scaffold(
    body: SafeArea(
      child: Column(
        children: [
          SvgPicture.asset(
            'assets/example.svg',
            color: primaryColor,
            height: 80.0,
          ),
          SingleChildScrollView(
            child: Container(
                padding: const EdgeInsets.symmetric(horizontal: 32.0),
                width: double.infinity,
                child: Column(
                  children: [
                    const SizedBox(height: 50),
                    Center(
                      child: Stack(
                        children: [
                          _image != null
                              ? InkWell(
                                  onTap: selectImage,
                                  child: CircleAvatar(
                                    radius: 48,
                                    backgroundImage: MemoryImage(_image!),
                                  ),
                                )
                              : InkWell(
                                  onTap: selectImage,
                                  child: const CircleAvatar(
                                    radius: 48,
                                    backgroundImage:
                                        AssetImage('assets/user.png'),
                                  ),
                                ),
                          Positioned(
                            bottom: -10,
                            left: 50,
                            child: IconButton(
                              onPressed: selectImage,
                              icon: const Icon(Icons.add_a_photo_outlined),
                            ),
                          ),
                        ],
                      ),
                    ),
                    const SizedBox(height: 50),
                    TextFieldInput(..),
                    TextFieldInput(..),
                    TextFieldInput(..)...

What would be the correct approach to this?

Upvotes: 0

Views: 58

Answers (2)

Muhammad Waqas
Muhammad Waqas

Reputation: 207

Column by default has screen height size that is why you get render flow error when screen size increases because you're not making topmost column scrollable.

there are 2 possible solution you can do

  1. Wrap your singleChildScrollView inside Expanded. It will adjust and scroll your all items inside remaining space after image.

  2. Make your topmost column scrollable by wrapping inside SingleChildScrollView. It will solve render flow error issue but your screen whole screen will scroll as well.

Upvotes: 0

eamirho3ein
eamirho3ein

Reputation: 17940

Wrap your SingleChildScrollView in a Expanded widget, like this:

child: Scaffold(
    body: SafeArea(
      child: Column(
        children: [
          SvgPicture.asset(
            'assets/example.svg',
            color: primaryColor,
            height: 80.0,
          ),
          Expanded( //<--- add this
           child: SingleChildScrollView(
            child: Container(
                padding: const EdgeInsets.symmetric(horizontal: 32.0),
                width: double.infinity,
                child: Column(
                  children: [
                    const SizedBox(height: 50),
                    Center(
                      child: Stack(
                        children: [
                          _image != null
                              ? InkWell(
                                  onTap: selectImage,
                                  child: CircleAvatar(
                                    radius: 48,
                                    backgroundImage: MemoryImage(_image!),
                                  ),
                                )
                              : InkWell(
                                  onTap: selectImage,
                                  child: const CircleAvatar(
                                    radius: 48,
                                    backgroundImage:
                                        AssetImage('assets/user.png'),
                                  ),
                                ),
                          Positioned(
                            bottom: -10,
                            left: 50,
                            child: IconButton(
                              onPressed: selectImage,
                              icon: const Icon(Icons.add_a_photo_outlined),
                            ),
                          ),
                        ],
                      ),
                    ),
                    const SizedBox(height: 50),
                    TextFieldInput(..),
                    TextFieldInput(..),
                    TextFieldInput(..)...

Upvotes: 1

Related Questions