@@ -24,11 +24,17 @@ open class WFloatingHintEditText @JvmOverloads constructor(
2424 defStyle : Int = R .attr.editTextStyle,
2525) : AppCompatEditText(context, attrs, defStyle), WThemedView {
2626
27- private var floatingHintGravity: Int = Gravity .CENTER_VERTICAL or Gravity .START
27+ var floatingHintGravity: Int = Gravity .CENTER_VERTICAL or Gravity .START
28+ set(value) {
29+ if (field == value) {
30+ return
31+ }
32+ field = value
33+ invalidateHintLayout()
34+ invalidate()
35+ }
2836 private var floatingHintText: CharSequence? = null
29- private var floatingHintLayout: StaticLayout ? = null
30- private var floatingHintLayoutWidth: Int = - 1
31- private var floatingHintLayoutText: CharSequence? = null
37+ private var floatingHintDrawState: FloatingHintDrawState ? = null
3238
3339 override fun updateTheme () {
3440 setHintTextColor(WColor .SecondaryText .color)
@@ -40,19 +46,11 @@ open class WFloatingHintEditText @JvmOverloads constructor(
4046 super .requestLayout()
4147 }
4248
43- fun setFloatingHintGravity (gravity : Int ) {
44- if (floatingHintGravity == gravity) {
49+ private fun setFloatingHint (hint : CharSequence ) {
50+ super .setHint(null )
51+ if (TextUtils .equals(floatingHintText, hint)) {
4552 return
4653 }
47- floatingHintGravity = gravity
48- invalidateHintLayout()
49- invalidate()
50- }
51-
52- fun getFloatingHintGravity (): Int = floatingHintGravity
53-
54- private fun setFloatingHint (hint : CharSequence? ) {
55- super .setHint(null )
5654 floatingHintText = hint
5755 invalidateHintLayout()
5856 }
@@ -84,9 +82,7 @@ open class WFloatingHintEditText @JvmOverloads constructor(
8482 }
8583
8684 private fun invalidateHintLayout () {
87- floatingHintLayout = null
88- floatingHintLayoutWidth = - 1
89- floatingHintLayoutText = null
85+ floatingHintDrawState = null
9086 }
9187
9288 override fun onDraw (canvas : Canvas ) {
@@ -96,7 +92,28 @@ open class WFloatingHintEditText @JvmOverloads constructor(
9692 return
9793 }
9894
99- val textForHint = floatingHintText ? : return
95+ val floatingHintDrawState = obtainFloatingHintDrawState() ? : return
96+
97+ val save = canvas.save()
98+ canvas.translate(floatingHintDrawState.x - scrollX, floatingHintDrawState.y - scrollY)
99+
100+ floatingHintDrawState.hintLayout.draw(canvas)
101+ canvas.restoreToCount(save)
102+ }
103+
104+ private fun shouldDrawHint (): Boolean {
105+ if (! text.isNullOrEmpty() || floatingHintText.isNullOrEmpty()) {
106+ return false
107+ }
108+ return alpha > 0f && visibility == VISIBLE
109+ }
110+
111+ private fun obtainFloatingHintDrawState (): FloatingHintDrawState ? {
112+ if (floatingHintDrawState != null ) {
113+ return floatingHintDrawState
114+ }
115+
116+ val textForHint = floatingHintText ? : return null
100117
101118 val hintGravity = floatingHintGravity
102119 val isRtl = layoutDirection == LAYOUT_DIRECTION_RTL
@@ -133,10 +150,10 @@ open class WFloatingHintEditText @JvmOverloads constructor(
133150 val contentWidth = (contentRight - contentLeft).coerceAtLeast(0 )
134151
135152 if (contentWidth == 0 ) {
136- return
153+ return null
137154 }
138155
139- val layout = obtainHintLayout (textForHint, contentWidth) ? : return
156+ val layout = createHintLayout (textForHint, contentWidth)
140157
141158 val layoutWidth = layout.width
142159 val x = when (horizontalGravity) {
@@ -152,29 +169,12 @@ open class WFloatingHintEditText @JvmOverloads constructor(
152169 else -> contentTop
153170 }.toFloat()
154171
155- val save = canvas.save()
156- canvas.translate(x - scrollX, y - scrollY)
157-
158- layout.draw(canvas)
159- canvas.restoreToCount(save)
160- }
161-
162- private fun shouldDrawHint (): Boolean {
163- if (! text.isNullOrEmpty() || floatingHintText.isNullOrEmpty()) {
164- return false
172+ return FloatingHintDrawState (hintLayout = layout, x = x, y = y).also {
173+ floatingHintDrawState = it
165174 }
166- return alpha > 0f && visibility == VISIBLE
167175 }
168176
169- private fun obtainHintLayout (hintText : CharSequence , availableWidth : Int ): StaticLayout ? {
170- if (floatingHintLayout != null && floatingHintLayoutWidth == availableWidth && TextUtils .equals(
171- floatingHintLayoutText,
172- hintText
173- )
174- ) {
175- return floatingHintLayout
176- }
177-
177+ private fun createHintLayout (hintText : CharSequence , availableWidth : Int ): StaticLayout {
178178 val hintPaint = TextPaint (paint)
179179 hintPaint.color = (hintTextColors?.defaultColor ? : currentTextColor).let { color ->
180180 hintTextColors?.defaultColor ? : color
@@ -203,10 +203,6 @@ open class WFloatingHintEditText @JvmOverloads constructor(
203203 .setHyphenationFrequency(hyphenationFrequency)
204204 .setTextDirection(textDir)
205205 .build()
206-
207- floatingHintLayout = layout
208- floatingHintLayoutWidth = availableWidth
209- floatingHintLayoutText = hintText
210206 return layout
211207 }
212208
@@ -239,14 +235,24 @@ open class WFloatingHintEditText @JvmOverloads constructor(
239235
240236 private fun resolveVerticalGravity (gravity : Int ): Int {
241237 val vGravity = gravity and Gravity .VERTICAL_GRAVITY_MASK
242- return if (vGravity == 0 ) Gravity .TOP else vGravity
238+ return if (vGravity == 0 ) {
239+ Gravity .TOP
240+ } else {
241+ vGravity
242+ }
243243 }
244244
245245 override fun onCreateInputConnection (outAttrs : EditorInfo ): InputConnection ? {
246246 val inputConnection = super .onCreateInputConnection(outAttrs)
247247 if (outAttrs.hintText == null ) {
248- outAttrs.hintText = floatingHintLayoutText
248+ outAttrs.hintText = floatingHintText
249249 }
250250 return inputConnection
251251 }
252+
253+ private data class FloatingHintDrawState (
254+ val hintLayout : StaticLayout ,
255+ val x : Float ,
256+ val y : Float
257+ )
252258}
0 commit comments