1+ /*
2+ * PanguText - A typographic solution for the optimal alignment of CJK characters, English words, and half-width digits.
3+ * Copyright (C) 2019 HighCapable
4+ * https://github.com/BetterAndroid/PanguText
5+ *
6+ * Apache License Version 2.0
7+ *
8+ * Licensed under the Apache License, Version 2.0 (the "License");
9+ * you may not use this file except in compliance with the License.
10+ * You may obtain a copy of the License at
11+ *
12+ * https://www.apache.org/licenses/LICENSE-2.0
13+ *
14+ * Unless required by applicable law or agreed to in writing, software
15+ * distributed under the License is distributed on an "AS IS" BASIS,
16+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17+ * See the License for the specific language governing permissions and
18+ * limitations under the License.
19+ *
20+ * This file is created by fankes on 2025/8/15.
21+ */
22+ package com.highcapable.pangutext.android.core
23+
24+ import android.text.TextWatcher
25+ import android.widget.TextView
26+ import com.highcapable.kavaref.KavaRef.Companion.resolve
27+
28+ /* *
29+ * A delegate for [TextView] to manage its text watchers.
30+ * @param instance the [TextView] instance.
31+ */
32+ internal class TextViewDelegate private constructor(private val instance : TextView ) {
33+
34+ companion object {
35+
36+ private val mListeners by lazy {
37+ TextView ::class .resolve()
38+ .optional(silent = true )
39+ .firstFieldOrNull { name = " mListeners" }
40+ }
41+
42+ /* *
43+ * Create the [TextViewDelegate] for the given [TextView] instance.
44+ * @return [TextViewDelegate]
45+ */
46+ val TextView .delegate get() = TextViewDelegate (this )
47+ }
48+
49+ /* *
50+ * The text watchers of the [TextView].
51+ * @return [ArrayList]<[TextWatcher]>.
52+ */
53+ private val textWatchers
54+ get() = mListeners?.copy()?.of(instance)?.getQuietly<ArrayList <TextWatcher >>()
55+
56+ /* *
57+ * Execute the given action without triggering text watchers.
58+ * @param action the action to execute without triggering text watchers.
59+ */
60+ inline fun withoutTextWatchers (action : () -> Unit ) {
61+ val currentWatchers = mutableListOf<TextWatcher >()
62+ textWatchers?.also {
63+ currentWatchers.addAll(it)
64+ // Avoid triggering events again during processing.
65+ it.clear()
66+ }
67+
68+ // Run action.
69+ action()
70+ // Re-add to continue listening to text changes.
71+ textWatchers?.addAll(currentWatchers)
72+
73+ currentWatchers.clear()
74+ }
75+ }
0 commit comments