在扩展的 EditText 中读取 InputType 的位置 class
Where to read InputType in an extended EditText class
我扩展了 EditText 并希望根据给定的 InputType
添加一些功能。外汇。如果 InputType 是 password
类型,那么我想检查它并更改 right
复合可绘制对象。
问题是,如果我在 init{}
乐趣中这样做,那么我会得到默认的 InputType 131073
,这是不正确的。
问题是:在 EditText 的哪个位置 "lifecycle" 我可以获得正确的 InputType 指示?
open class EditText @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) :
AppCompatEditText(context, attrs, defStyleAttr), View.OnTouchListener, View.OnFocusChangeListener, TextWatcherAdapter.TextWatcherListener {
private var icon: Drawable? = null
private var listener: Listener? = null
private var touchListener: OnTouchListener? = null
private var focusChangeListener: OnFocusChangeListener? = null
init {
icon = compoundDrawables[2]
if (icon == null) {
//////// NOT getting the right InputType !!!
if (isPasswordInputType()) {
icon = resources.getDrawable(R.drawable.ic_password_hide, null)
} else {
icon = resources.getDrawable(R.drawable.ic_delete_ring, null)
}
}
icon?.setBounds(0, 0, icon!!.intrinsicWidth, icon!!.intrinsicHeight)
setClearIconVisible(false)
super.setOnTouchListener(this)
super.setOnFocusChangeListener(this)
addTextChangedListener(TextWatcherAdapter(this, this))
}
override fun onTouch(v: View, event: MotionEvent): Boolean {
if (compoundDrawables[2] != null) {
val left = width - icon!!.intrinsicWidth - paddingRight * 2
val right = width
val top = 0
val bottom = height
// If tapped on icon
if (Rect(left, top, right, bottom).contains(event.x.toInt(), event.y.toInt())) {
if (event.action == MotionEvent.ACTION_UP) {
//////// IS showing the right InputType !!!
if (isPasswordInputType()) {
if (transformationMethod == HideReturnsTransformationMethod.getInstance()) {
transformationMethod = PasswordTransformationMethod.getInstance()
icon = resources.getDrawable(R.drawable.ic_password_show, null)
} else if (transformationMethod == PasswordTransformationMethod.getInstance()) {
transformationMethod = HideReturnsTransformationMethod.getInstance()
icon = resources.getDrawable(R.drawable.ic_password_hide, null)
}
icon?.setBounds(0, 0, icon!!.intrinsicWidth, icon!!.intrinsicHeight)
setPasswordIconVisible(true)
} else {
setText("")
}
if (listener != null) {
listener!!.didClearText()
}
}
return true
}
}
return if (touchListener != null) {
touchListener!!.onTouch(v, event)
} else false
}
override fun onFocusChange(v: View, hasFocus: Boolean) {
if (isPasswordInputType()) {
setClearIconVisible(true)
} else {
if (hasFocus) {
setClearIconVisible(isNotEmpty(text!!))
} else {
setClearIconVisible(false)
}
if (focusChangeListener != null) {
focusChangeListener!!.onFocusChange(v, hasFocus)
}
}
}
override fun onTextChanged(view: EditText, text: String) {
if (isFocused) {
setClearIconVisible(isNotEmpty(text))
}
}
interface Listener {
fun didClearText()
}
fun setListener(listener: Listener) {
this.listener = listener
}
override fun setOnTouchListener(l: View.OnTouchListener) {
this.touchListener = l
}
override fun setOnFocusChangeListener(f: View.OnFocusChangeListener) {
this.focusChangeListener = f
}
fun setDefaultFocusChangeListener() {
this.onFocusChangeListener = OnFocusChangeListener { v, hasFocus ->
if (hasFocus) {
elevation = resources.getDimensionPixelSize(R.dimen.edit_box_elevation_focused).toFloat()
} else {
elevation = resources.getDimensionPixelSize(R.dimen.edit_box_elevation).toFloat()
}
}
}
private fun isNotEmpty(text: Editable): Boolean {
return isNotEmpty(text.toString())
}
private fun isNotEmpty(text: String?): Boolean {
return text != null && text.isNotEmpty()
}
private fun setClearIconVisible(visible: Boolean) {
val wasVisible = compoundDrawables[2] != null
if (visible != wasVisible) {
val d = if (visible) icon else null
setCompoundDrawables(compoundDrawables[0], compoundDrawables[1], d, compoundDrawables[3])
}
}
private fun setPasswordIconVisible(visible: Boolean) {
val d = if (visible) icon else null
setCompoundDrawables(compoundDrawables[0], compoundDrawables[1], d, compoundDrawables[3])
}
private fun isPasswordInputType(): Boolean {
return (inputType == InputType.TYPE_NUMBER_VARIATION_PASSWORD ||
inputType == InputType.TYPE_TEXT_VARIATION_PASSWORD ||
inputType == InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD ||
inputType == InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD ||
inputType == InputType.TYPE_CLASS_TEXT + InputType.TYPE_NUMBER_VARIATION_PASSWORD ||
inputType == InputType.TYPE_CLASS_TEXT + InputType.TYPE_TEXT_VARIATION_PASSWORD ||
inputType == InputType.TYPE_CLASS_TEXT + InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD ||
inputType == InputType.TYPE_CLASS_TEXT + InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD)
}
}
好的,找到答案了,所以我不会删除问题,而是post这里的答案:
我将区分 InputType 的代码移到了 onAttachedToWindow
事件中。在此生命周期事件中,实际的 InputType 已经存在以用于:
...
override fun onAttachedToWindow() {
super.onAttachedToWindow()
icon = compoundDrawables[2]
if (icon == null) {
icon = if (isPasswordInputType()) {
resources.getDrawable(R.drawable.ic_password_show, null)
} else {
resources.getDrawable(R.drawable.ic_delete_ring, null)
}
}
icon?.setBounds(0, 0, icon!!.intrinsicWidth, icon!!.intrinsicHeight)
setClearIconVisible(false)
}
...
我扩展了 EditText 并希望根据给定的 InputType
添加一些功能。外汇。如果 InputType 是 password
类型,那么我想检查它并更改 right
复合可绘制对象。
问题是,如果我在 init{}
乐趣中这样做,那么我会得到默认的 InputType 131073
,这是不正确的。
问题是:在 EditText 的哪个位置 "lifecycle" 我可以获得正确的 InputType 指示?
open class EditText @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) :
AppCompatEditText(context, attrs, defStyleAttr), View.OnTouchListener, View.OnFocusChangeListener, TextWatcherAdapter.TextWatcherListener {
private var icon: Drawable? = null
private var listener: Listener? = null
private var touchListener: OnTouchListener? = null
private var focusChangeListener: OnFocusChangeListener? = null
init {
icon = compoundDrawables[2]
if (icon == null) {
//////// NOT getting the right InputType !!!
if (isPasswordInputType()) {
icon = resources.getDrawable(R.drawable.ic_password_hide, null)
} else {
icon = resources.getDrawable(R.drawable.ic_delete_ring, null)
}
}
icon?.setBounds(0, 0, icon!!.intrinsicWidth, icon!!.intrinsicHeight)
setClearIconVisible(false)
super.setOnTouchListener(this)
super.setOnFocusChangeListener(this)
addTextChangedListener(TextWatcherAdapter(this, this))
}
override fun onTouch(v: View, event: MotionEvent): Boolean {
if (compoundDrawables[2] != null) {
val left = width - icon!!.intrinsicWidth - paddingRight * 2
val right = width
val top = 0
val bottom = height
// If tapped on icon
if (Rect(left, top, right, bottom).contains(event.x.toInt(), event.y.toInt())) {
if (event.action == MotionEvent.ACTION_UP) {
//////// IS showing the right InputType !!!
if (isPasswordInputType()) {
if (transformationMethod == HideReturnsTransformationMethod.getInstance()) {
transformationMethod = PasswordTransformationMethod.getInstance()
icon = resources.getDrawable(R.drawable.ic_password_show, null)
} else if (transformationMethod == PasswordTransformationMethod.getInstance()) {
transformationMethod = HideReturnsTransformationMethod.getInstance()
icon = resources.getDrawable(R.drawable.ic_password_hide, null)
}
icon?.setBounds(0, 0, icon!!.intrinsicWidth, icon!!.intrinsicHeight)
setPasswordIconVisible(true)
} else {
setText("")
}
if (listener != null) {
listener!!.didClearText()
}
}
return true
}
}
return if (touchListener != null) {
touchListener!!.onTouch(v, event)
} else false
}
override fun onFocusChange(v: View, hasFocus: Boolean) {
if (isPasswordInputType()) {
setClearIconVisible(true)
} else {
if (hasFocus) {
setClearIconVisible(isNotEmpty(text!!))
} else {
setClearIconVisible(false)
}
if (focusChangeListener != null) {
focusChangeListener!!.onFocusChange(v, hasFocus)
}
}
}
override fun onTextChanged(view: EditText, text: String) {
if (isFocused) {
setClearIconVisible(isNotEmpty(text))
}
}
interface Listener {
fun didClearText()
}
fun setListener(listener: Listener) {
this.listener = listener
}
override fun setOnTouchListener(l: View.OnTouchListener) {
this.touchListener = l
}
override fun setOnFocusChangeListener(f: View.OnFocusChangeListener) {
this.focusChangeListener = f
}
fun setDefaultFocusChangeListener() {
this.onFocusChangeListener = OnFocusChangeListener { v, hasFocus ->
if (hasFocus) {
elevation = resources.getDimensionPixelSize(R.dimen.edit_box_elevation_focused).toFloat()
} else {
elevation = resources.getDimensionPixelSize(R.dimen.edit_box_elevation).toFloat()
}
}
}
private fun isNotEmpty(text: Editable): Boolean {
return isNotEmpty(text.toString())
}
private fun isNotEmpty(text: String?): Boolean {
return text != null && text.isNotEmpty()
}
private fun setClearIconVisible(visible: Boolean) {
val wasVisible = compoundDrawables[2] != null
if (visible != wasVisible) {
val d = if (visible) icon else null
setCompoundDrawables(compoundDrawables[0], compoundDrawables[1], d, compoundDrawables[3])
}
}
private fun setPasswordIconVisible(visible: Boolean) {
val d = if (visible) icon else null
setCompoundDrawables(compoundDrawables[0], compoundDrawables[1], d, compoundDrawables[3])
}
private fun isPasswordInputType(): Boolean {
return (inputType == InputType.TYPE_NUMBER_VARIATION_PASSWORD ||
inputType == InputType.TYPE_TEXT_VARIATION_PASSWORD ||
inputType == InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD ||
inputType == InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD ||
inputType == InputType.TYPE_CLASS_TEXT + InputType.TYPE_NUMBER_VARIATION_PASSWORD ||
inputType == InputType.TYPE_CLASS_TEXT + InputType.TYPE_TEXT_VARIATION_PASSWORD ||
inputType == InputType.TYPE_CLASS_TEXT + InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD ||
inputType == InputType.TYPE_CLASS_TEXT + InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD)
}
}
好的,找到答案了,所以我不会删除问题,而是post这里的答案:
我将区分 InputType 的代码移到了 onAttachedToWindow
事件中。在此生命周期事件中,实际的 InputType 已经存在以用于:
...
override fun onAttachedToWindow() {
super.onAttachedToWindow()
icon = compoundDrawables[2]
if (icon == null) {
icon = if (isPasswordInputType()) {
resources.getDrawable(R.drawable.ic_password_show, null)
} else {
resources.getDrawable(R.drawable.ic_delete_ring, null)
}
}
icon?.setBounds(0, 0, icon!!.intrinsicWidth, icon!!.intrinsicHeight)
setClearIconVisible(false)
}
...