skip to Main Content

I have created a simple demo to explain what i want..

I have a Listview builder which shows names,and a textfield for adding name to names list.

I have used following code for moving listview builder to last item while adding new name with IconButton,

 _scrollController.jumpTo(_scrollController.position.maxScrollExtent);

but how to scroll to last item when Screen loading…I placed above code in InitState() but its not working…

so how to do it without changing order of names..

here is my code


class _HomeScreenState extends State<HomeScreen> {
  TextEditingController txtname = TextEditingController();
  final _scrollController = ScrollController();

  @override
  Widget build(BuildContext context) {
    return SafeArea(
        child: Scaffold(
      body: Column(
        children: [
          Expanded(
              child: ListView.builder(
                  controller: _scrollController,
                  itemCount: names.length,
                  itemBuilder: (context, index) => ListTile(
                        title: Text(names[index].toString()),
                      ))),
          Container(
            child: TextField(
              controller: txtname,
              decoration: InputDecoration(
                  suffix: IconButton(
                    icon: Icon(Icons.send),
                    onPressed: () {
                      setState(() {
                        names.add(txtname.text);
                        _scrollController.jumpTo(
                            _scrollController.position.maxScrollExtent);
                        txtname.clear();
                      });
                    },
                  ),
                  hintText: 'Enter Name'),
            ),
          )
        ],
      ),
    ));
  }
}

2

Answers


  1. You can wrap the Listview with a SingleChildScrollView and set the reading direction to reverse:

    SingleChildScrollView(
            reverse: true,
            child: ListView.builder(
                      controller: _scrollController,
                      itemCount: names.length,
                      itemBuilder: (context, index) => ListTile(
                            title: Text(names[index].toString()),
      ))
    )
    
    Login or Signup to reply.
  2. This worked for me,

    So basically This function WidgetsBinding.instance.addPostFrameCallback((_) {... ensures that a callback after the frame has been painted. and using Timer waits for the ListView.builder to be completed first. You can also add FocusScope.of(context).unfocus(); to dismiss the keyboard

    const HomeScreen({super.key});
    
    @override
    State<HomeScreen> createState() => _HomeScreenState();
    }
    
    class _HomeScreenState extends State<HomeScreen> {
    TextEditingController txtname = TextEditingController();
    final _scrollController = ScrollController();
    @override
    void initState() {
      print("sasssssss");
      super.initState();
    
      WidgetsBinding.instance.addPostFrameCallback((_) {
        Future.delayed(Duration(milliseconds: 50), () {
          _scrollController.jumpTo(_scrollController.position.maxScrollExtent);
        });
      });
      print("sasssssss");
    }
    
    List names = List.generate(17, (index) => 'generated $index');
    
    @override
    Widget build(BuildContext context) {
      return SafeArea(
          child: Scaffold(
        // backgroundColor: Colors.red[100],
        body: Column(
          children: [
            Expanded(
                child: ListView.builder(
                    controller: _scrollController,
                    itemCount: names.length,
                    itemBuilder: (context, index) => ListTile(
                          title: Text(names[index].toString()),
                        ))),
            Container(
              padding: EdgeInsets.all(12.0),
              child: TextField(
                controller: txtname,
                decoration: InputDecoration(
                  suffix: IconButton(
                    icon: const Icon(Icons.send),
                    onPressed: () {
                      setState(() {
                        names.add("${txtname.text} Scrolled");
                        Future.delayed(Duration(milliseconds: 50), () {
                          _scrollController
                              .jumpTo(_scrollController.position.maxScrollExtent);
                        });
    
                        txtname.clear();
                      });
                    },
                  ),
                  hintText: 'Enter Name',
                ),
              ),
            )
          ],
        ),
      ));
    }
    }```
    
    
    
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search