web-dev-qa-db-ja.com

TextInputLayoutspasswordToggleEnabledを使用した表示可能なパスワード

サポートライブラリの新しい関数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>

トグルは次のようになります。 enter image description here

Xmlでこれを行う方法は見つかりませんでした。また、ビューがレンダリングされた後に手動で表示を切り替える方法もありません。 EditTextの入力タイプをtextVisiblePasswordに設定すると、トグルが表示されません。たとえばmPasswordEditText.setTransformationMethod(null);を使用してコードでそれを行う場合。パスワードは表示されますが、トグルが消え、ユーザーはパスワードを再び非表示にすることはできません。私はそれをすべて手動で行うことができることを知っていますが、新しい魔法のトグルでそれを機能させることができるかどうか疑問に思っています

10
Gober

最も簡単な方法は以下のとおりです 別の解決策はこの答えの最後です

_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;
}
_
3
Pankaj Kumar

次のコードを使用して、クリアテキストモードで起動することができました。基本的に、コンテンツの説明を使用して適切なビューを見つける必要がありました。

彼らが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();
        }
    }
}
0
Tyler V

次のコードを使用できます。

TextInputLayout yourTextInputLayoutId=findViewById(R.id.yourTextInputLayoutId);
       FrameLayout frameLayout= (FrameLayout) (yourTextInputLayoutId).getChildAt(0);
       CheckableImageButton checkableImageButton= (CheckableImageButton) frameLayout.getChildAt(1);
       checkableImageButton.performClick();

ここで、yourTextInputLayoutIdはxmlからのTextInputLayoutIDです。

0

TextViewの属性を動的に変更できます。 XML Atrribute Android:passwordをtrueに設定すると、ビューにドットが表示され、falseに設定するとテキストが表示されます。

メソッド setTransformationMethod を使用すると、この属性をコードから変更できるはずです。 (免責事項:ビューが表示された後もメソッドが機能するかどうかはテストしていません。問題が発生した場合は、コメントを残してください。)

完全なサンプルコードは次のようになります

yourTextView.setTransformationMethod(new PasswordTransformationMethod());

パスワードを非表示にします。パスワードを表示するには、既存の変換メソッドの1つを設定するか、入力テキストを処理しない空のTransformationMethodを実装します。

yourTextView.setTransformationMethod(new DoNothingTransformation());
0
Jasur Kurbanov

これを試して

if (inputEditText.getTransformationMethod() == null) {
        inputEditText.setTransformationMethod(new PasswordTransformationMethod());
        inputEditText.setSelection(inputEditText.getText().length());
    } else {
        inputEditText.setTransformationMethod(null);
        inputEditText.setSelection(inputEditText.getText().length());
    }
0
Nithesh

方法の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();
    }
}
0
Cheok Yan Cheng