Skip to content

[CP-Stable] Fix deleting text in EditableText with CJK keyboard while in CupertinoPageRoute throws exception #153949

@Renzo-Olivares

Description

@Renzo-Olivares

Issue Link

#153003

Target

stable

Cherry pick PR Link

#153946

Changelog Description

Fix a crash when deleting text in an EditableText inside CupertinoPageRoute, with a CJK keyboard on Android.

Impacted Users

Users of Flutter TextField using CJK keyboard and CupertinoPageRoute

Impact Description

This triggers a crash when an Android user, using a CJK keyboard, tries to delete text in a TextField with scrollable text, that is inside of a CupertinoPageRoute.

Workaround

No workaround.

Risk

low

Test Coverage

yes

Validation Steps

Run the example below on an Android device with a CJK keyboard (tested on Gboard), tap the Push CupertinoPageRoute button, scroll to the end of the TextField and select a word (either through a long press or double tap), then delete that word. The app should not throw an exception when this happens.

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

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Test TextField in CupertinoRoute'),
        ),
        body: const Padding(
          padding: EdgeInsets.all(16.0),
          child: MyHome(),
        ),
      ),
    );
  }
}

class MyHome extends StatefulWidget {
  const MyHome({super.key});

  @override
  State<MyHome> createState() => _MyHomeState();
}

class _MyHomeState extends State<MyHome> {
  @override
  void dispose() {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(mainAxisAlignment: MainAxisAlignment.start, children: <Widget>[
        TextButton(
          onPressed: () async {
            await Navigator.of(context).push(
              CupertinoPageRoute<void>(
                  settings: const RouteSettings(name: '/TestCupertinoRoute'),
                  builder: (BuildContext innerContext) => const MyTextTest(),
              ),
            );
          },
          child: const Text('Push CupertinoPageRoute'),
        ),
      ]),
    );
  }
}

class MyTextTest extends StatefulWidget {
  const MyTextTest({super.key});

  @override
  State<MyTextTest> createState() => _MyTextTestState();
}

class _MyTextTestState extends State<MyTextTest> {
  final TextEditingController _controller = TextEditingController(text: 'Some long text that should scroll. ' * 20);

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

  @override
  Widget build(BuildContext context) {
    return Material(
      child: Center(
        child: TextField(
          controller: _controller,
        ),
      ),
    );
  }
}

Metadata

Metadata

Assignees

Labels

cp: reviewCherry-picks in the review queue

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions