【问题标题】:TextInputLayout Password Toggle ListenerTextInputLayout 密码切换监听器
【发布时间】:2018-02-28 20:05:11
【问题描述】:

我有一个 TextInputLayout 作为密码。我添加了 passwordToggleEnabled=true 来切换密码可见性。 当用户切换密码可见性时,我需要捕获事件。我该怎么做。

<android.support.design.widget.TextInputLayout
    android:id="@+id/password_input_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="start|center"
    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/enter_new_password"
            android:inputType="textPassword"/>

</android.support.design.widget.TextInputLayout>

【问题讨论】:

标签: android android-textinputlayout


【解决方案1】:

TextInputLayout 的源中,切换按钮的视图类型是CheckableImageButton。您只需要找到在TextInputLayout 视图的子级上递归迭代的视图。然后setOnTouchListener

View togglePasswordButton = findTogglePasswordButton(mTextInputLayoutView);
if (togglePasswordButton != null) {
    togglePasswordButton.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
            // implementation
            return false;
        }
    });
}

private View findTogglePasswordButton(ViewGroup viewGroup) {
    int childCount = viewGroup.getChildCount();
    for (int ind = 0; ind < childCount; ind++) {
        View child = viewGroup.getChildAt(ind);
        if (child instanceof ViewGroup) {
            View togglePasswordButton = findTogglePasswordButton((ViewGroup) child);
            if (togglePasswordButton != null) {
                return togglePasswordButton;
            }
        } else if (child instanceof CheckableImageButton) {
            return child;
        }
    }
    return null;
}

【讨论】:

  • 如何检查密码是否可见?在这两种情况下,输入类型都是 129
  • 使用布尔变量 isVisible 例如在您的 onTouchListener 中,当用户单击切换按钮时相应地切换变量的值(真或假)。这是我能建议的最好的了
  • 好的,我们可以使用 CheckableImageButton.isChecked 但必须添加 @SuppressLint("RestrictedApi")。否则显示错误“CheckableImageButton.ischecked 只能从同一个库组中调用”
【解决方案2】:

像另一个答案中建议的那样仅设置结束图标单击侦听器将不起作用,因为这样做会删除用于切换EditText 转换方法的现有侦听器。

所以如果你设置一个新的监听器,你需要自己改变它:

textInputLayout.setEndIconOnClickListener {
    // Toggle the EditText transformation method from nothing to password or vice versa.
    // Selection is lost in the process so make sure to restore it.
    val editText = textInputLayout.editText
    val oldSelection = editText.selectionEnd
    val hidePassword = editText.transformationMethod !is PasswordTransformationMethod
    passwordEdt.transformationMethod = PasswordTransformationMethod.getInstance().takeIf { hidePassword }
    if (oldSelection >= 0) {
        passwordEdt.setSelection(oldSelection)
    }

    // Do your own stuff here.
}

【讨论】:

    【解决方案3】:

    如果您仍在寻找有关 TextInputLayout 密码切换侦听器的完整解决方案,请查看此答案:

        public class SampleActivity extends AppCompatActivity {
    
        TextInputLayout password_input_layout;
        TextInputEditText password_edit_text;
    
        //textInputLayoutEndIconPressed will be tracked, EndIcon is pressed and toggled or not
        private boolean textInputLayoutEndIconPressed;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            textInputLayoutEndIconPressed = false;
            password_input_layout = (TextInputLayout) findViewById(R.id.password_input_layout);
            password_edit_text = (TextInputEditText) findViewById(R.id.password_edit_text);
    
            password_input_layout.setEndIconOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
    
                    if(!textInputLayoutEndIconPressed)
                        textInputLayoutEndIconPressed = true;
                    else
                        textInputLayoutEndIconPressed = false;
    
                    if(textInputLayoutEndIconPressed){
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                //Changing Drawable file
                                password_input_layout.setEndIconDrawable(getResources().getDrawable(R.drawable.ic_visibility_on));
                                //Changing TextInputEditText password text to open
                                password_edit_text.setTransformationMethod(null);
                            }
                        });
                    }else{
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                //Changing Drawable file
                                password_input_layout.setEndIconDrawable(getResources().getDrawable(R.drawable.ic_visibility_off));
                                //Changing TextInputEditText password text to hide
                                password_edit_text.setTransformationMethod(new PasswordTransformationMethod());
                            }
                        });
                    }
                }
            });
    
        }
    }
    

    设置 EndIconOnClickListener 时,需要同时检查 TextInputEditText 文本状态和 TextInputLayout EndIcon Drawable 文件。所以你可以像这样管理这个场景。

    【讨论】:

      【解决方案4】:

      请参阅my answer here,但简而言之,由于Material Components v1.1.0 (Kotlin),您可以执行以下操作:

      textInputLayout.setEndIconOnClickListener {
          // do something here
      }
      

      【讨论】:

      • 不,这个监听器将取代切换密码可见性的监听器。
      猜你喜欢
      • 2017-07-26
      • 1970-01-01
      • 1970-01-01
      • 2019-04-16
      • 1970-01-01
      • 2014-01-27
      • 1970-01-01
      • 1970-01-01
      • 2020-05-19
      相关资源
      最近更新 更多