mirror of
https://github.com/BetterAndroid/PanguText.git
synced 2025-09-01 08:15:21 +08:00
refactor: decoupling mListeners in PanguTextWatcher to TextViewDelegate
This commit is contained in:
@@ -26,9 +26,9 @@ import android.text.TextWatcher
|
||||
import android.widget.EditText
|
||||
import android.widget.TextView
|
||||
import com.highcapable.betterandroid.system.extension.tool.AndroidVersion
|
||||
import com.highcapable.kavaref.KavaRef.Companion.asResolver
|
||||
import com.highcapable.pangutext.android.PanguText
|
||||
import com.highcapable.pangutext.android.PanguTextConfig
|
||||
import com.highcapable.pangutext.android.core.TextViewDelegate.Companion.delegate
|
||||
import com.highcapable.pangutext.android.extension.injectRealTimePanguText
|
||||
|
||||
/**
|
||||
@@ -40,15 +40,7 @@ import com.highcapable.pangutext.android.extension.injectRealTimePanguText
|
||||
*/
|
||||
class PanguTextWatcher internal constructor(private val base: TextView, private val config: PanguTextConfig) : TextWatcher {
|
||||
|
||||
/**
|
||||
* The text watchers of the base [TextView].
|
||||
* @return [ArrayList]<[TextWatcher]>.
|
||||
*/
|
||||
private val textWatchers
|
||||
get() = base.asResolver().optional(silent = true).firstFieldOrNull {
|
||||
name = "mListeners"
|
||||
superclass()
|
||||
}?.getQuietly<ArrayList<TextWatcher>>()
|
||||
private val delegate = base.delegate
|
||||
|
||||
/**
|
||||
* Whether to automatically re-measure the text width after processing.
|
||||
@@ -62,20 +54,12 @@ class PanguTextWatcher internal constructor(private val base: TextView, private
|
||||
editable?.let { PanguText.format(base.resources, base.textSize, it, config) }
|
||||
if (!isAutoRemeasureText) return
|
||||
|
||||
val currentWatchers = mutableListOf<TextWatcher>()
|
||||
textWatchers?.also {
|
||||
currentWatchers.addAll(it)
|
||||
// Avoid triggering events again during processing.
|
||||
it.clear()
|
||||
delegate.withoutTextWatchers {
|
||||
// Reset the text to trigger remeasurement.
|
||||
base.text = editable
|
||||
}
|
||||
|
||||
// Reset the text to trigger remeasurement.
|
||||
base.text = editable
|
||||
// Re-add to continue listening to text changes.
|
||||
textWatchers?.addAll(currentWatchers)
|
||||
|
||||
currentWatchers.clear()
|
||||
}
|
||||
|
||||
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
|
||||
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
|
||||
}
|
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* PanguText - A typographic solution for the optimal alignment of CJK characters, English words, and half-width digits.
|
||||
* Copyright (C) 2019 HighCapable
|
||||
* https://github.com/BetterAndroid/PanguText
|
||||
*
|
||||
* Apache License Version 2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This file is created by fankes on 2025/8/15.
|
||||
*/
|
||||
package com.highcapable.pangutext.android.core
|
||||
|
||||
import android.text.TextWatcher
|
||||
import android.widget.TextView
|
||||
import com.highcapable.kavaref.KavaRef.Companion.resolve
|
||||
|
||||
/**
|
||||
* A delegate for [TextView] to manage its text watchers.
|
||||
* @param instance the [TextView] instance.
|
||||
*/
|
||||
internal class TextViewDelegate private constructor(private val instance: TextView) {
|
||||
|
||||
companion object {
|
||||
|
||||
private val mListeners by lazy {
|
||||
TextView::class.resolve()
|
||||
.optional(silent = true)
|
||||
.firstFieldOrNull { name = "mListeners" }
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the [TextViewDelegate] for the given [TextView] instance.
|
||||
* @return [TextViewDelegate]
|
||||
*/
|
||||
val TextView.delegate get() = TextViewDelegate(this)
|
||||
}
|
||||
|
||||
/**
|
||||
* The text watchers of the [TextView].
|
||||
* @return [ArrayList]<[TextWatcher]>.
|
||||
*/
|
||||
private val textWatchers
|
||||
get() = mListeners?.copy()?.of(instance)?.getQuietly<ArrayList<TextWatcher>>()
|
||||
|
||||
/**
|
||||
* Execute the given action without triggering text watchers.
|
||||
* @param action the action to execute without triggering text watchers.
|
||||
*/
|
||||
inline fun withoutTextWatchers(action: () -> Unit) {
|
||||
val currentWatchers = mutableListOf<TextWatcher>()
|
||||
textWatchers?.also {
|
||||
currentWatchers.addAll(it)
|
||||
// Avoid triggering events again during processing.
|
||||
it.clear()
|
||||
}
|
||||
|
||||
// Run action.
|
||||
action()
|
||||
// Re-add to continue listening to text changes.
|
||||
textWatchers?.addAll(currentWatchers)
|
||||
|
||||
currentWatchers.clear()
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user