У меня есть ниже TextInputEditTexts
, вложенный в custom TextInputLayouts
, и я хочу, чтобы значок "x" и переключатель пароля были видны одновременно. Однако переключатель глаза перекрывает значок «x».
У меня есть пользовательский TextInputLayout
с именем LoginInputLayout
, в котором я пытаюсь добавить два рисованных элемента в правой части пароля editText, но я продолжаю получать только значок глаза.
Как я могу добавить два рисованных объекта с правой стороны, и чтобы один не перекрывал другой? Как на картинке ниже.
Это дизайн, к которому я пытаюсь добраться
В реализации Android для родителя LayoutInputTextView
похоже, что первый дочерний элемент на самом деле FrameLayout
, а дочерний элемент этого FL - TextInputEditText
.
Когда переключатель пароля (который вызывает появление глаза) настроен на отображение, похоже, что реализация Android раздувает представление для переключателя и устанавливает его внутри FrameLayout, как показано ниже.
if (shouldShowPasswordIcon()) {
if (mPasswordToggleView == null) {
mPasswordToggleView = (CheckableImageButton) LayoutInflater.from(getContext())
.inflate(R.layout.design_text_input_password_icon, mInputFrame, false);
mPasswordToggleView.setImageDrawable(mPasswordToggleDrawable);
mPasswordToggleView.setContentDescription(mPasswordToggleContentDesc);
mInputFrame.addView(mPasswordToggleView);
mPasswordToggleView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
passwordVisibilityToggleRequested(false);
}
});
}
Единственное, переменная-член mFrameLayout является закрытой, и я не могу добавить туда детей или контролировать, где они находятся. Вот почему я чувствую, что я ограничен попыткой составного способа рисования.
<com.ge.cbyge.view.LoginInputTextLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
app:error="@{viewModel.emailError}">
<android.support.design.widget.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/login_fragment_email_text"
android:focusable="true"
android:focusableInTouchMode="true"
android:inputType="textEmailAddress"
android:maxLines="1"
android:text="@={viewModel.email}"/>
</com.ge.cbyge.view.LoginInputTextLayout>
<com.ge.cbyge.view.LoginInputTextLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/placeholder_dimen"
android:maxLines="1"
app:error="@{viewModel.passwordError}"
app:passwordToggleEnabled="true">
<android.support.design.widget.TextInputEditText
android:id="@+id/password_edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/login_fragment_password_text"
android:focusable="true"
android:focusableInTouchMode="true"
android:text="@={viewModel.password}"/>
</com.ge.cbyge.view.LoginInputTextLayout>
Это моя пользовательская реализация TextInputLayout
class LoginInputTextLayout : TextInputLayout, TextWatcher {
lateinit var clearTextIcon: Drawable
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle)
override fun addView(child: View?, index: Int, params: ViewGroup.LayoutParams) {
super.addView(child, index, params)
if(child is EditText) {
Timber.d("$TAG child was an editText")
if (editText != null) {
Timber.d("$TAG initializing the clearText")
init(context)
}
}
}
private fun init(context: Context) {
val drawable = ContextCompat.getDrawable(context, R.drawable.abc_ic_clear_material)
DrawableCompat.setTint(drawable, editText!!.currentHintTextColor)
clearTextIcon = drawable
clearTextIcon.setBounds(0, 0, clearTextIcon.intrinsicHeight, clearTextIcon.intrinsicHeight)
setClearIconVisible(false)
editText!!.transformationMethod = PasswordTransformationMethod.getInstance()
editText!!.setOnTouchListener(onTouchListener)
editText!!.setOnFocusChangeListener(focusChangeListener)
editText!!.addTextChangedListener(this)
}
private val onTouchListener: View.OnTouchListener = OnTouchListener { v, event ->
val x = event.x.toInt()
if (clearTextIcon.isVisible && x > width - paddingRight - clearTextIcon.intrinsicWidth) {
if (event.action == MotionEvent.ACTION_UP) {
editText?.setText("")
}
return@OnTouchListener true
}
return@OnTouchListener false
}
private val focusChangeListener: View.OnFocusChangeListener = OnFocusChangeListener { v, hasFocus ->
if (hasFocus) {
setClearIconVisible(editText!!.text.isNotEmpty())
} else {
setClearIconVisible(false)
}
}
private fun setClearIconVisible(visible: Boolean) {
clearTextIcon.setVisible(visible, false)
val compoundDrawables = TextViewCompat.getCompoundDrawablesRelative(editText!!)
TextViewCompat.setCompoundDrawablesRelative(
editText!!,
compoundDrawables[0],
compoundDrawables[1],
if (visible) clearTextIcon else null,
compoundDrawables[3])
}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
if (editText!!.isFocused) {
setClearIconVisible(s.isNotEmpty())
}
}
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
override fun afterTextChanged(s: Editable) {}
}