skip to Main Content

I want the user to be able to scroll manually, but also automatically scroll to the bottom when the text changes and when text is out of bound.

This is my calculator app. As you can see, I didn’t solve my problem.

enter image description here


class _CalculatorDisplayWidgetState extends State<_CalculatorDisplayWidget> {
  final ScrollController controller = ScrollController();

  @override
  void initState() {
    super.initState();
    controller.addListener(listener);
  }

  void listener() {
    if (controller.offset < controller.position.maxScrollExtent) {
      controller.jumpTo(
        controller.position.maxScrollExtent,
      );
    }
  }

  @override
  void dispose() {
    super.dispose();
    controller.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Expanded(
      child: Container(
        width: MediaQuery.of(context).size.width,
        color: Colors.yellow,
        padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 10),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.end,
          children: [
            Expanded(
              child: SingleChildScrollView(/// TODO
                controller: controller,
                child: Text(
                  widget.state.expression,
                  style: textStyle.copyWith(
                    fontSize: 40,
                  ),
                  textAlign: TextAlign.right,
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

in this code, i wrote controller and listener, but it is not what i want.

if there are some solutions, please help me 🙂 Thanks.

2

Answers


  1. Chosen as BEST ANSWER

    I solved my problem by didUpdateWidget. here is my code.

    class _CalculatorDisplayWidgetState extends State<_CalculatorDisplayWidget> {
      final ScrollController _controller = ScrollController();
    
      void listener() {
        _controller.jumpTo(
          _controller.position.maxScrollExtent,
        );
      }
    
      @override
      void didUpdateWidget(covariant _CalculatorDisplayWidget oldWidget) {
        super.didUpdateWidget(oldWidget);
        WidgetsBinding.instance.addPostFrameCallback((_) {
          // Execute the listener after the frame is rendered
          listener();
        });
      }
    
      @override
      void dispose() {
        super.dispose();
        _controller.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return Expanded(
          child: Container(
            width: MediaQuery.of(context).size.width,
            color: Colors.yellow,
            padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 10),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.end,
              children: [
                Expanded(
                  child: SingleChildScrollView(
                    controller: _controller,
                    child: Text(
                      widget.state.expression,
                      style: textStyle.copyWith(
                        fontSize: 40,
                      ),
                      textAlign: TextAlign.right,
                    ),
                  ),
                ),
                ......
    
    

  2. just change Expanded to container inside the SingleChildScrollView

    class _CalculatorDisplayWidgetState extends State<_CalculatorDisplayWidget> {
      final ScrollController controller = ScrollController();
    
      @override
      void initState() {
        super.initState();
        controller.addListener(listener);
      }
    
      void listener() {
        if (controller.offset < controller.position.maxScrollExtent) {
          controller.jumpTo(
            controller.position.maxScrollExtent,
          );
        }
      }
    
      @override
      void dispose() {
        super.dispose();
        controller.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return Expanded(
          child: Container(
            width: MediaQuery.of(context).size.width,
            color: Colors.yellow,
            padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 10),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.end,
              children: [
                SingleChildScrollView( 
                  controller: controller,
                  child: Container(
                    height:150,// add your convenient 
                    child: Text(
                      widget.state.expression,
                      style: textStyle.copyWith(
                        fontSize: 40,
                      ),
                      textAlign: TextAlign.right,
                    ),
                  ),
                ),
              ],
            ),
          ),
        );
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search