Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Classes | Public Member Functions | List of all members
io.flutter.plugin.editing.ListenableEditingState Class Reference
Inheritance diagram for io.flutter.plugin.editing.ListenableEditingState:

Classes

interface  EditingStateWatcher
 

Public Member Functions

 ListenableEditingState ( @Nullable TextInputChannel.TextEditState initialState, @NonNull View view)
 
ArrayList< TextEditingDeltaextractBatchTextEditingDeltas ()
 
void clearBatchDeltas ()
 
void beginBatchEdit ()
 
void endBatchEdit ()
 
void setComposingRange (int composingStart, int composingEnd)
 
void setEditingState (TextInputChannel.TextEditState newState)
 
void addEditingStateListener (EditingStateWatcher listener)
 
void removeEditingStateListener (EditingStateWatcher listener)
 
SpannableStringBuilder replace (int start, int end, CharSequence tb, int tbstart, int tbend)
 
final int getSelectionStart ()
 
final int getSelectionEnd ()
 
final int getComposingStart ()
 
final int getComposingEnd ()
 
void setSpan (Object what, int start, int end, int flags)
 
String toString ()
 

Detailed Description

The current editing state (text, selection range, composing range) the text input plugin holds.

As the name implies, this class also notifies its listeners when the editing state changes. When there're ongoing batch edits, change notifications will be deferred until all batch edits end (i.e. when the outermost batch edit ends). Listeners added during a batch edit will always be notified when all batch edits end, even if there's no real change.

Adding/removing listeners or changing the editing state in a didChangeEditingState callback may cause unexpected behavior.

Definition at line 30 of file ListenableEditingState.java.

Constructor & Destructor Documentation

◆ ListenableEditingState()

io.flutter.plugin.editing.ListenableEditingState.ListenableEditingState ( @Nullable TextInputChannel.TextEditState  initialState,
@NonNull View  view 
)
inline

Definition at line 60 of file ListenableEditingState.java.

61 {
62 super();
63
64 Editable self = this;
65 mDummyConnection =
66 new BaseInputConnection(view, true) {
67 @Override
68 public Editable getEditable() {
69 return self;
70 }
71 };
72
73 if (initialState != null) {
74 setEditingState(initialState);
75 }
76 }
void setEditingState(TextInputChannel.TextEditState newState)

Member Function Documentation

◆ addEditingStateListener()

void io.flutter.plugin.editing.ListenableEditingState.addEditingStateListener ( EditingStateWatcher  listener)
inline

Definition at line 171 of file ListenableEditingState.java.

171 {
172 if (mChangeNotificationDepth > 0) {
173 Log.e(TAG, "adding a listener " + listener.toString() + " in a listener callback");
174 }
175 // It is possible for a listener to get added during a batch edit. When that happens we always
176 // notify the new listeners.
177 // This does not check if the listener is already in the list of existing listeners.
178 if (mBatchEditNestDepth > 0) {
179 Log.w(TAG, "a listener was added to EditingState while a batch edit was in progress");
180 mPendingListeners.add(listener);
181 } else {
182 mListeners.add(listener);
183 }
184 }
void Log(const char *format,...) SK_PRINTF_LIKE(1

◆ beginBatchEdit()

void io.flutter.plugin.editing.ListenableEditingState.beginBatchEdit ( )
inline

Starts a new batch edit during which change notifications will be put on hold until all batch edits end.

Batch edits nest.

Definition at line 93 of file ListenableEditingState.java.

93 {
94 mBatchEditNestDepth++;
95 if (mChangeNotificationDepth > 0) {
96 Log.e(TAG, "editing state should not be changed in a listener callback");
97 }
98 if (mBatchEditNestDepth == 1 && !mListeners.isEmpty()) {
99 mTextWhenBeginBatchEdit = toString();
100 mSelectionStartWhenBeginBatchEdit = getSelectionStart();
101 mSelectionEndWhenBeginBatchEdit = getSelectionEnd();
102 mComposingStartWhenBeginBatchEdit = getComposingStart();
103 mComposingEndWhenBeginBatchEdit = getComposingEnd();
104 }
105 }

◆ clearBatchDeltas()

void io.flutter.plugin.editing.ListenableEditingState.clearBatchDeltas ( )
inline

Definition at line 85 of file ListenableEditingState.java.

85 {
86 mBatchTextEditingDeltas.clear();
87 }

◆ endBatchEdit()

void io.flutter.plugin.editing.ListenableEditingState.endBatchEdit ( )
inline

Ends the current batch edit and flush pending change notifications if the current batch edit is not nested (i.e. it is the last ongoing batch edit).

Definition at line 109 of file ListenableEditingState.java.

109 {
110 if (mBatchEditNestDepth == 0) {
111 Log.e(TAG, "endBatchEdit called without a matching beginBatchEdit");
112 return;
113 }
114 if (mBatchEditNestDepth == 1) {
115 for (final EditingStateWatcher listener : mPendingListeners) {
116 notifyListener(listener, true, true, true);
117 }
118
119 if (!mListeners.isEmpty()) {
120 Log.v(TAG, "didFinishBatchEdit with " + String.valueOf(mListeners.size()) + " listener(s)");
121 final boolean textChanged = !toString().equals(mTextWhenBeginBatchEdit);
122 final boolean selectionChanged =
123 mSelectionStartWhenBeginBatchEdit != getSelectionStart()
124 || mSelectionEndWhenBeginBatchEdit != getSelectionEnd();
125 final boolean composingRegionChanged =
126 mComposingStartWhenBeginBatchEdit != getComposingStart()
127 || mComposingEndWhenBeginBatchEdit != getComposingEnd();
128
129 notifyListenersIfNeeded(textChanged, selectionChanged, composingRegionChanged);
130 }
131 }
132
133 mListeners.addAll(mPendingListeners);
134 mPendingListeners.clear();
135 mBatchEditNestDepth--;
136 }

◆ extractBatchTextEditingDeltas()

ArrayList< TextEditingDelta > io.flutter.plugin.editing.ListenableEditingState.extractBatchTextEditingDeltas ( )
inline

Definition at line 78 of file ListenableEditingState.java.

78 {
79 ArrayList<TextEditingDelta> currentBatchDeltas =
80 new ArrayList<TextEditingDelta>(mBatchTextEditingDeltas);
81 mBatchTextEditingDeltas.clear();
82 return currentBatchDeltas;
83 }

◆ getComposingEnd()

final int io.flutter.plugin.editing.ListenableEditingState.getComposingEnd ( )
inline

Definition at line 274 of file ListenableEditingState.java.

274 {
275 return BaseInputConnection.getComposingSpanEnd(this);
276 }

◆ getComposingStart()

final int io.flutter.plugin.editing.ListenableEditingState.getComposingStart ( )
inline

Definition at line 270 of file ListenableEditingState.java.

270 {
271 return BaseInputConnection.getComposingSpanStart(this);
272 }

◆ getSelectionEnd()

final int io.flutter.plugin.editing.ListenableEditingState.getSelectionEnd ( )
inline

Definition at line 266 of file ListenableEditingState.java.

266 {
267 return Selection.getSelectionEnd(this);
268 }

◆ getSelectionStart()

final int io.flutter.plugin.editing.ListenableEditingState.getSelectionStart ( )
inline

Definition at line 262 of file ListenableEditingState.java.

262 {
263 return Selection.getSelectionStart(this);
264 }

◆ removeEditingStateListener()

void io.flutter.plugin.editing.ListenableEditingState.removeEditingStateListener ( EditingStateWatcher  listener)
inline

Definition at line 186 of file ListenableEditingState.java.

186 {
187 if (mChangeNotificationDepth > 0) {
188 Log.e(TAG, "removing a listener " + listener.toString() + " in a listener callback");
189 }
190 mListeners.remove(listener);
191 if (mBatchEditNestDepth > 0) {
192 mPendingListeners.remove(listener);
193 }
194 }

◆ replace()

SpannableStringBuilder io.flutter.plugin.editing.ListenableEditingState.replace ( int  start,
int  end,
CharSequence  tb,
int  tbstart,
int  tbend 
)
inline

Definition at line 197 of file ListenableEditingState.java.

198 {
199
200 if (mChangeNotificationDepth > 0) {
201 Log.e(TAG, "editing state should not be changed in a listener callback");
202 }
203
204 final CharSequence oldText = toString();
205
206 boolean textChanged = end - start != tbend - tbstart;
207 for (int i = 0; i < end - start && !textChanged; i++) {
208 textChanged |= charAt(start + i) != tb.charAt(tbstart + i);
209 }
210 if (textChanged) {
211 mToStringCache = null;
212 }
213
214 final int selectionStart = getSelectionStart();
215 final int selectionEnd = getSelectionEnd();
216 final int composingStart = getComposingStart();
217 final int composingEnd = getComposingEnd();
218
219 final SpannableStringBuilder editable = super.replace(start, end, tb, tbstart, tbend);
220 mBatchTextEditingDeltas.add(
221 new TextEditingDelta(
222 oldText,
223 start,
224 end,
225 tb,
229 getComposingEnd()));
230
231 if (mBatchEditNestDepth > 0) {
232 return editable;
233 }
234
235 final boolean selectionChanged =
236 getSelectionStart() != selectionStart || getSelectionEnd() != selectionEnd;
237 final boolean composingRegionChanged =
238 getComposingStart() != composingStart || getComposingEnd() != composingEnd;
239 notifyListenersIfNeeded(textChanged, selectionChanged, composingRegionChanged);
240 return editable;
241 }
glong glong end

◆ setComposingRange()

void io.flutter.plugin.editing.ListenableEditingState.setComposingRange ( int  composingStart,
int  composingEnd 
)
inline

Update the composing region of the current editing state.

If the range is invalid or empty, the current composing region will be removed.

Definition at line 141 of file ListenableEditingState.java.

141 {
142 if (composingStart < 0 || composingStart >= composingEnd) {
143 BaseInputConnection.removeComposingSpans(this);
144 } else {
145 mDummyConnection.setComposingRegion(composingStart, composingEnd);
146 }
147 }

◆ setEditingState()

void io.flutter.plugin.editing.ListenableEditingState.setEditingState ( TextInputChannel.TextEditState  newState)
inline

Called when the framework sends updates to the text input plugin.

This method will also update the composing region if it has changed.

Definition at line 152 of file ListenableEditingState.java.

152 {
154 replace(0, length(), newState.text);
155
156 if (newState.hasSelection()) {
157 Selection.setSelection(this, newState.selectionStart, newState.selectionEnd);
158 } else {
159 Selection.removeSelection(this);
160 }
161
162 setComposingRange(newState.composingStart, newState.composingEnd);
163
164 // Updates from the framework should not have a delta created for it as they have already been
165 // applied on the framework side.
167
168 endBatchEdit();
169 }
SpannableStringBuilder replace(int start, int end, CharSequence tb, int tbstart, int tbend)
void setComposingRange(int composingStart, int composingEnd)
size_t length

◆ setSpan()

void io.flutter.plugin.editing.ListenableEditingState.setSpan ( Object  what,
int  start,
int  end,
int  flags 
)
inline

Definition at line 279 of file ListenableEditingState.java.

279 {
280 super.setSpan(what, start, end, flags);
281 // Setting a span does not involve mutating the text value in the editing state. Here we create
282 // a non text update delta with any updated selection and composing regions.
283 mBatchTextEditingDeltas.add(
284 new TextEditingDelta(
285 toString(),
289 getComposingEnd()));
290 }
FlutterSemanticsFlag flags

◆ toString()

String io.flutter.plugin.editing.ListenableEditingState.toString ( )
inline

Definition at line 293 of file ListenableEditingState.java.

293 {
294 return mToStringCache != null ? mToStringCache : (mToStringCache = super.toString());
295 }

The documentation for this class was generated from the following file: