サポートライブラリの新しい関数passwordToggleEnabledでTextInputLayoutを使用しています。これにより、ユーザーがパスワードの表示のオンとオフを切り替えることができる素敵な「目」アイコンが表示されます。
私の質問は、この機能を使用する方法があるが、パスワードを表示して開始するかどうかです。
私の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);を使用してコードでそれを行う場合。パスワードは表示されますが、トグルが消え、ユーザーはパスワードを再び非表示にすることはできません。私はそれをすべて手動で行うことができることを知っていますが、新しい魔法のトグルでそれを機能させることができるかどうか疑問に思っています
最も簡単な方法は以下のとおりです 別の解決策はこの答えの最後です
_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)
元のユーティリティクラス 以下のように定義されます
_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;
}
_
次のコードを使用して、クリアテキストモードで起動することができました。基本的に、コンテンツの説明を使用して適切なビューを見つける必要がありました。
彼らがmPasswordToggledVisibility
のセッターメソッドを提供した場合、それは物事をはるかに簡単にするでしょう...
@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();
}
}
}
次のコードを使用できます。
TextInputLayout yourTextInputLayoutId=findViewById(R.id.yourTextInputLayoutId);
FrameLayout frameLayout= (FrameLayout) (yourTextInputLayoutId).getChildAt(0);
CheckableImageButton checkableImageButton= (CheckableImageButton) frameLayout.getChildAt(1);
checkableImageButton.performClick();
ここで、yourTextInputLayoutId
はxmlからのTextInputLayoutIDです。
TextViewの属性を動的に変更できます。 XML Atrribute Android:passwordをtrueに設定すると、ビューにドットが表示され、falseに設定するとテキストが表示されます。
メソッド setTransformationMethod を使用すると、この属性をコードから変更できるはずです。 (免責事項:ビューが表示された後もメソッドが機能するかどうかはテストしていません。問題が発生した場合は、コメントを残してください。)
完全なサンプルコードは次のようになります
yourTextView.setTransformationMethod(new PasswordTransformationMethod());
パスワードを非表示にします。パスワードを表示するには、既存の変換メソッドの1つを設定するか、入力テキストを処理しない空のTransformationMethodを実装します。
yourTextView.setTransformationMethod(new DoNothingTransformation());
これを試して
if (inputEditText.getTransformationMethod() == null) {
inputEditText.setTransformationMethod(new PasswordTransformationMethod());
inputEditText.setSelection(inputEditText.getText().length());
} else {
inputEditText.setTransformationMethod(null);
inputEditText.setSelection(inputEditText.getText().length());
}
方法の1つは、CheckableImageButton
からTextInputLayout
を検索し、onClick
のパスワード表示ステータスに基づいてプログラムでEditText
を実行することです。
これがコードスニペットです。
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();
}
}