Home > Net >  How to have a ListView without scrolling the parent column view in flutter?
How to have a ListView without scrolling the parent column view in flutter?

Time:09-10

Please look at this image Home Page

Now when I scroll the ListView it becomes like this - Home Page

Now I know the reason why this is happening, it is because I used ListView as a parent to this entire view and added ListView.builder() and other widgets as its child.

What I want is to scroll the ListView.builder() without scrolling the entire page.

For this I first tried to use Column as parent but that ended up giving the overflow pixels error. And then I set the physics: const NeverScrollableScrollPhysics() inside the parent ListView but after that it made my ListView.builder() to show all of its list items.

Here is my Code for Home Screen

Widget build(BuildContext context) {
return Scaffold(
  body: Column(
    children: [
      Expanded(
        child: ListView(
          padding: const EdgeInsets.only(top: 45, bottom: 24),
          children: [
            header(),
            const SizedBox(height: 36),
            const BalanceCard(),
            const SizedBox(height: 36),
            Recent()
          ],
        ),
      ),
      Align(
        alignment: Alignment.bottomCenter,
        child: bottomNavigationBar(),
      ),
    ],
  ),
); }

Recent List Code

class RecentItems extends StatefulWidget {
final List<Transaction> transactions;

RecentItems({required this.transactions});

@override
State<RecentItems> createState() => _RecentItemsState();
}
class _RecentItemsState extends State<RecentItems> {
@override
Widget build(BuildContext context) {
  return SizedBox(
    height: 450,
    child: Expanded(child: ListView.builder(
           itemBuilder: (context, index) {
      final item = widget.transactions[index].toString();
      return Dismissible(
        direction: DismissDirection.endToStart,
        key: UniqueKey(),
        onDismissed: (direction) {
          setState(() {
            widget.transactions.removeAt(index);
          });

          // Then show a snackbar.
          ScaffoldMessenger.of(context)
              .showSnackBar(const SnackBar(content: Text('Transaction Deleted')));
        },
        background: Container(
          color: Colors.red,
          alignment: AlignmentDirectional.centerEnd,
          child: const Padding(
            padding: EdgeInsets.fromLTRB(0.0, 0.0, 15.0, 0.0),
            child: Icon(
              EvaIcons.trash2,
              color: Colors.white,
            ),
          ),
        ),

        child: Card(
          elevation: 5,
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(20.0),
          ),
          child: ListTile(
            leading: CircleAvatar(
              radius: 30,
              foregroundImage: widget.transactions[index].Image,
              backgroundColor: primaryColor,
            ),
            title: Text(
              widget.transactions[index].title,
              style: const TextStyle(color: secondaryColor),
            ),
            subtitle: Text(
              DateFormat.yMMMd().format(widget.transactions[index].date),
            ),
            trailing: Text(
              '\$${widget.transactions[index].amount}',
              style: const TextStyle(color: secondaryColor),
            ),
          ),
        ),
      );
    },
    itemCount: widget.transactions.length,
  ),)
);
}
}

Recent Widget -

@override
Widget build(BuildContext context) {
return Padding(
  padding: const EdgeInsets.symmetric(horizontal: 24),
  child: Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: [
      const Text(
        'Recent Transactions',
        style: TextStyle(
            fontSize: 15,
            fontWeight: FontWeight.bold,
            color: secondaryColor),
      ),
      const SizedBox(height: 5),
      RecentItems(transactions: _userTransactions),
    ],
  ),
)

CodePudding user response:

The entire screen scrolls because Recent() is included in the same ListView as header() and balanceCard().

Try something like this:

Scaffold(
        body: Column(
          children: [
            Expanded(
              child: ListView(
                padding: const EdgeInsets.only(top: 45, bottom: 24),
                children: [
                  header(),
                  const SizedBox(height: 36),
                  const BalanceCard(),
                  const SizedBox(height: 36),
                ],
              ),
            ),
            // Recent items removed from ListView
            Recent(),
            Align(
              alignment: Alignment.bottomCenter,
              child: bottomNavigationBar(),
            ),
          ],
        ),
      )

I hope this helps.

CodePudding user response:

By simplifying your code, this is an example of a layout where you have a single Column in the Scaffold. The Column contains some sized, unsized and aligned children.

One child, Recent is a ListView, without explicit height, but wrapped into an Expanded widget. This way it will occupy all the remaining area left by the other children, and it will be scrollable.

(You will run into trouble with this if the children without Recent occupy all the available area.)

Please have a look at this code, you can copy-paste it into a DartPad fiddle:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: MyWidget(),
        ),
      ),
    );
  }
}

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) => Scaffold(
        body: Column(
          children: [
            const Text('header()'),
            const SizedBox(height: 36),
            const Text('BalanceCard()'),
            const SizedBox(height: 36),
            Expanded(child: Recent()),
            const Align(
              alignment: Alignment.bottomCenter,
              child: Text('bottomNavigationBar()'),
            ),
          ],
        ),
      );
}

class Recent extends StatelessWidget {
  @override
  Widget build(BuildContext context) => ListView.builder(
      itemCount: 100, itemBuilder: (context, index) => Text('Item $index'));
}

  • Related