Set TextInput selection correctly when attached to window in Android (#46948)

Summary:
On Android, when `ReactEditText` is attached to window, `setTextIsSelectable` moves the caret to the beginning, so we need to restore the selection.

This is similar to what we did in https://github.com/facebook/react-native/pull/17851.

Fixes https://github.com/facebook/react-native/issues/46943

## Changelog:

[ANDROID] [FIXED] - Fix TextInput caret moving to the beginning when attached to window

Pull Request resolved: https://github.com/facebook/react-native/pull/46948

Test Plan:
Code to reproduce in RNTester:

```TSX
import type {RNTesterModuleExample} from '../../types/RNTesterTypes';
import {TextInput} from 'react-native';
import {useEffect, useRef} from 'react';

function Playground() {
  const input = useRef(null);
  useEffect(() => { setTimeout(() => input.current?.focus(), 1000); }, []);
  return <TextInput ref={input} value='1.00' selection={{start: 4, end: 4}} />;
}

export default ({
  title: 'Playground',
  name: 'playground',
  render: (): React.Node => <Playground />,
}: RNTesterModuleExample);
```

Before | After
-- | --
![Screenshot_1728553990](https://github.com/user-attachments/assets/382cf3ec-7437-4b0d-8c15-c8923d677afd) | ![Screenshot_1728553884](https://github.com/user-attachments/assets/9883e966-e9b8-4f8a-bedb-6ee43880d482)

Reviewed By: cortinico

Differential Revision: D64175774

Pulled By: rshest

fbshipit-source-id: ef9fdbecca582c8075bcdfd2d9b810b04d87e3d9
This commit is contained in:
Qichen Zhu
2025-02-06 10:47:26 +00:00
committed by Riccardo Cipolleschi
parent 4475e01570
commit 1656394bae
@@ -1035,12 +1035,18 @@ public class ReactEditText extends AppCompatEditText {
public void onAttachedToWindow() {
super.onAttachedToWindow();
int selectionStart = getSelectionStart();
int selectionEnd = getSelectionEnd();
// Used to ensure that text is selectable inside of removeClippedSubviews
// See https://github.com/facebook/react-native/issues/6805 for original
// fix that was ported to here.
super.setTextIsSelectable(true);
// Restore the selection since `setTextIsSelectable` changed it.
setSelection(selectionStart, selectionEnd);
if (mContainsImages) {
Spanned text = getText();
TextInlineImageSpan[] spans = text.getSpans(0, text.length(), TextInlineImageSpan.class);