Search code examples
fluttertextfieldcursor-positiontextselectiontexteditingcontroller

Cursor defaults to start of Textfield when typing, using TextEditingController + onChanged - Flutter


I'm developing an app that will have some single line Textfields that are essentially used to store notes in each, so I am using shared_preferences dependency to set/get these values, but using this with a TextEditingController and onChanged parameter I find the cursor moves to the start of the Textfield when typing.

I've researched this and can see a lot of suggestions to use a Listener (as below) for the TextSelection to set cursor permanently at the end of the Textfield, but I was hoping to allow the user to move the cursor anywhere in that box to type where they like.

text1.addListener(() {
      final text = text1.text;
      text1.value = text1.value.copyWith(
        text: text,
        selection:
            TextSelection(baseOffset: text.length, extentOffset: text.length),
        composing: TextRange.empty,
      );
    });

Here is an example below that replicates the issue I'm experiencing, if anyone has any suggestions? I could use a Save button, but I was hoping to just allow the user to amend text and move the cursor where they need, and the onChanged parameter could then save any changes to shared_preferences;

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Textfield Test'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  
  TextEditingController text1 = TextEditingController();
  SharedPreferences sharedPreferences;

  @override
  void initState() {
    super.initState();
    getText();
  }
 

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            TextField(
                controller: text1,
                onChanged: _setText,
              ),
          ],
        ),
      ),
    );
  }

  _setText(String value) async {
    sharedPreferences = await SharedPreferences.getInstance();
    setState(() {
      sharedPreferences.setString("text1", text1.text);
      getText();
    });
  }

  getText() async {
    sharedPreferences = await SharedPreferences.getInstance();
    setState(() {
        text1.text = sharedPreferences.getString("text1");
    });
  }

}

Solution

  • Just to let anyone know reading this post, i found where i was going wrong.

    On the _setText function id defined, i just needed to remove the line 'getText();', and now it doesn't move the cursor around when typing, and works fine.