我正在使用TextInputLayout和支持库中的新函数:passwordToggleEnabled。这提供了一个很好的眼睛" -icon,让用户可以打开和关闭密码可见性。
我的问题是,是否有办法使用此功能,但密码可见?
我的xml:
<android.support.design.widget.TextInputLayout
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:passwordToggleEnabled="true">
<EditText
android:id="@+id/password_edit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/prompt_password"
android:inputType="textPassword" />
</android.support.design.widget.TextInputLayout>
我还没有找到在xml中执行此操作的方法,而不是在呈现视图后手动切换可见性的方法。如果我将EditText的输入类型设置为textVisiblePassword,则不会显示切换。如果我在代码中使用例如mPasswordEditText.setTransformationMethod(null);显示密码但切换消失,用户无法再次隐藏密码。我知道我可以手动完成所有操作,但只是想知道我是否可以使用新的魔术切换工作
答案 0 :(得分:0)
其中一种方法是,我们可以根据CheckableImageButton
的密码可见性状态,从TextInputLayout
中搜索onClick
,然后以编程方式对其执行EditText
。 / p>
这是代码段。
private CheckableImageButton findCheckableImageButton(View view) {
if (view instanceof CheckableImageButton) {
return (CheckableImageButton)view;
}
if (view instanceof ViewGroup) {
ViewGroup viewGroup = (ViewGroup) view;
for (int i = 0, ei = viewGroup.getChildCount(); i < ei; i++) {
CheckableImageButton checkableImageButton = findCheckableImageButton(viewGroup.getChildAt(i));
if (checkableImageButton != null) {
return checkableImageButton;
}
}
}
return null;
}
//...
if (passwordEditText.getTransformationMethod() != null) {
CheckableImageButton checkableImageButton = findCheckableImageButton(passwordTextInputLayout);
if (checkableImageButton != null) {
// Make password visible.
checkableImageButton.performClick();
}
}
答案 1 :(得分:0)
我能够用下面的代码让它以纯文本模式启动。基本上,我必须使用内容描述来找到正确的视图。
如果他们为mPasswordToggledVisibility
提供了setter方法,这将使事情变得容易得多...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextInputLayout til = findViewById(R.id.password);
CharSequence cs = til.getPasswordVisibilityToggleContentDescription();
ArrayList<View> ov = new ArrayList<>();
til.findViewsWithText(ov, cs,View.FIND_VIEWS_WITH_CONTENT_DESCRIPTION);
if( ov.size() == 1 ) {
Checkable c = (Checkable)ov.get(0);
// As far as I can tell the check for "isChecked" here isn't needed,
// since it always starts unchecked by default. However, if you
// wanted to check for state, you could do it this way.
if( c != null && !c.isChecked()) {
ov.get(0).performClick();
}
}
}
答案 2 :(得分:0)
最简单的方法是 另一种解决方案是此答案的最后
private void setupPasswordToggleView() {
final TextInputLayout textInputLayout = mRootView.findViewById(R.id.password);
// You can skip post-call and write directly the code which is inside run method.
// But to be safe (as toggle-view is child of TextInputLayout, post call
// has been added.
textInputLayout.post(new Runnable() {
@Override
public void run() {
CheckableImageButton passwordToggleView = textInputLayout.findViewById(R.id.text_input_password_toggle);
// passwordToggleView.toggle(); // Can not use as restricted to use same library group
// passwordToggleView.setChecked(true); // Can not use as restricted to use same library group
passwordToggleView.performClick();
}
});
}
现在让我解释一下答案
在查看TextInputLayout.java
的代码时,我发现有一个布局design_text_input_password_icon.xml
被添加到TextInputLayout.java
中。下面是该代码
private void updatePasswordToggleView() {
if (mEditText == null) {
// If there is no EditText, there is nothing to update
return;
}
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); // << HERE IS THAT
.........
}
现在下一个目标是找到design_text_input_password_icon.xml
和切换视图的查找ID。因此找到布局design_text_input_password_icon.xml here,它写为
18<android.support.design.widget.CheckableImageButton
19 xmlns:android="http://schemas.android.com/apk/res/android"
20 android:id="@+id/text_input_password_toggle"
21 android:layout_width="wrap_content"
22 android:layout_height="wrap_content"
23 android:layout_gravity="center_vertical|end|right"
24 android:background="?attr/selectableItemBackgroundBorderless"
25 android:minHeight="48dp"
26 android:minWidth="48dp"/>
我找到了该视图的ID text_input_password_toggle
,现在可以轻松地在视图组中找到该视图并对其执行操作。
另一种解决方案是迭代TextInputLayout
的子项,并检查其是否为CheckableImageButton
,然后对其进行单击。通过这种方式,就不会依赖于该视图的ID,并且如果Android更改了视图的ID,我们的解决方案仍然可以使用。 (尽管在正常情况下它们不会更改视图的ID)。
private void setupPasswordToggleViewMethod2() {
final TextInputLayout textInputLayout = mRootView.findViewById(R.id.password);
textInputLayout.post(new Runnable() {
@Override
public void run() {
View toggleView = findViewByClassReference(textInputLayout, CheckableImageButton.class);
if (toggleView != null) {
toggleView.performClick();
}
}
});
}
其中findViewByClassReference(View rootView, Class<T> clazz)
original utility class 的定义如下
public static <T extends View> T findViewByClassReference(View rootView, Class<T> clazz) {
if(clazz.isInstance(rootView)) {
return clazz.cast(rootView);
}
if(rootView instanceof ViewGroup) {
ViewGroup viewGroup = (ViewGroup) rootView;
for(int i = 0; i < viewGroup.getChildCount(); i++) {
View child = viewGroup.getChildAt(i);
T match = findViewByClassReference(child, clazz);
if(match != null) {
return match;
}
}
}
return null;
}
答案 3 :(得分:0)
您可以动态更改TextView的属性。如果将XML Atrribute android:password设置为true,则如果将其设置为false,则视图将显示点。
使用方法setTransformationMethod,您应该可以从代码中更改此属性。 (免责声明:显示该视图后,我尚未测试该方法是否仍然有效。如果您遇到问题,请给我留言。)
完整的示例代码为
yourTextView.setTransformationMethod(new PasswordTransformationMethod());
隐藏密码。要显示密码,您可以设置现有的转换方法之一,或实现一个空的TransformationMethod,对输入文本不做任何操作。
yourTextView.setTransformationMethod(new DoNothingTransformation());
答案 4 :(得分:0)
您可以使用以下代码:
TextInputLayout yourTextInputLayoutId=findViewById(R.id.yourTextInputLayoutId);
FrameLayout frameLayout= (FrameLayout) (yourTextInputLayoutId).getChildAt(0);
CheckableImageButton checkableImageButton= (CheckableImageButton) frameLayout.getChildAt(1);
checkableImageButton.performClick();
yourTextInputLayoutId
是xml中的TextInputLayout ID。
答案 5 :(得分:0)
要首先显示可见的密码, 不包括
android:inputType="textPassword"
在
<com.google.android.material.textfield.TextInputEditText>
....
</com.google.android.material.textfield.TextInputEditText>
答案 6 :(得分:0)
使用材料成分库(1.1.0
,1.2.0-beta01
,1.3.0-alpha01
)以可见的密码开头,只需使用:
<com.google.android.material.textfield.TextInputLayout
app:endIconMode="password_toggle"
/>
以及您的代码中
textInputLayout.getEditText().setTransformationMethod(null);
如果要恢复默认行为:
textInputLayout.getEditText()
.setTransformationMethod(PasswordTransformationMethod.getInstance());
答案 7 :(得分:0)
仅删除android:inputType="textPassword"
对我有用
答案 8 :(得分:-2)
您可以使用:
yourEditText.setTransformationMethod(new PasswordTransformationMethod());
要重新显示可读密码,只需将null作为转换方法传递:
yourEditText.setTransformationMethod(null);
因此用户可以再次隐藏它。