草庐IT

android - 带有 TextInputLayouts passwordToggleEnabled 的可见密码

coder 2023-11-24 原文

我正在使用带有支持库中新功能的 TextInputLayout:passwordToggleEnabled。这提供了一个漂亮的“眼睛”图标,允许用户打开和关闭密码可见性。

我的问题是是否有一种方法可以使用此功能但以可见的密码开始?

我的 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 中执行此操作的方法,也没有找到在呈现 View 后手动切换可见性的方法。如果我将 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();
        }
    });
}

Now let me explain the answer

在查看 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和切换 View 的查找 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那个 View ,现在一切都很容易,只需在它的 View 组中找到那个 View 并对其执行操作。


另一种解决方案是迭代 TextInputLayout 的子项并检查它是否是 CheckableImageButton然后点击它。通过这种方式,不会依赖于该 View 的 id,如果 Android 更改了 View 的 id,我们的解决方案仍然有效。 (尽管在正常情况下它们不会更改 View 的 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;
}

关于android - 带有 TextInputLayouts passwordToggleEnabled 的可见密码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41611476/

有关android - 带有 TextInputLayouts passwordToggleEnabled 的可见密码的更多相关文章

  1. ruby - 即时确定方法的可见性 - 2

    我正在编写一个方法,它将在一个类中定义一个实例方法;类似于attr_accessor:classFoocustom_method(:foo)end我通过将custom_method函数添加到Module模块并使用define_method定义方法来实现它,效果很好。但我无法弄清楚如何考虑类(class)的可见性属性。例如,在下面的类中classFoocustom_method(:foo)privatecustom_method(:bar)end第一个生成的方法(foo)必须是公共(public)的,第二个(bar)必须是私有(private)的。我怎么做?或者,如何找到调用我的cust

  2. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  3. ruby-on-rails - 带有 Zeus 的 RSpec 3.1,我应该在 spec_helper 中要求 'rspec/rails' 吗? - 2

    使用rspec-rails3.0+,测试设置分为spec_helper和rails_helper我注意到生成的spec_helper不需要'rspec/rails'。这会导致zeus崩溃:spec_helper.rb:5:in`':undefinedmethod`configure'forRSpec:Module(NoMethodError)对thisissue最常见的回应是需要'rspec/rails'。但这是否会破坏仅使用spec_helper拆分rails规范和PORO规范的全部目的?或者这无关紧要,因为Zeus无论如何都会预加载Rails?我应该在我的spec_helper中做

  4. Ruby:如何使用带有散列的 'send' 方法调用方法? - 2

    假设我有一个类A,里面有一些方法。假设stringmethodName是这些方法之一,我已经知道我想给它什么参数。它们在散列中{'param1'=>value1,'param2'=>value2}所以我有:params={'param1'=>value1,'param2'=>value2}a=A.new()a.send(methodName,value1,value2)#callmethodnamewithbothparams我希望能够通过传递我的哈希以某种方式调用该方法。这可能吗? 最佳答案 确保methodName是一个符号,而

  5. ruby-on-rails - 带有 Pry 的 Rails 控制台 - 2

    当我进入Rails控制台时,我已将pry设置为加载代替irb。我找不到该页面或不记得如何将其恢复为默认行为,因为它似乎干扰了我的Rubymine调试器。有什么建议吗? 最佳答案 我刚发现问题,pry-railsgem。忘记了它的目的是让“railsconsole”打开pry。 关于ruby-on-rails-带有Pry的Rails控制台,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/question

  6. 带有 attr_accessor 的类上的 Ruby instance_eval - 2

    我了解instance_eval和class_eval之间的基本区别。我在玩弄时发现的是一些涉及attr_accessor的奇怪东西。这是一个例子:A=Class.newA.class_eval{attr_accessor:x}a=A.newa.x="x"a.x=>"x"#...expectedA.instance_eval{attr_accessor:y}A.y="y"=>NoMethodError:undefinedmethod`y='forA:Classa.y="y"=>"y"#WHATTT?这是怎么回事:instance_eval没有访问我们的A类(对象)然后它实际上将它添加到

  7. ruby-on-rails - 在 Rails 中自定义 "Password confirmation doesn' t 匹配密码 - 2

    有没有办法在Rails中为确认字段自定义消息?例如在设计中我必须输入密码和password_confirmation并且错误消息是:Passwordconfirmationdoesn'tmatchPassword我可以更改事件记录语言环境消息(“不匹配”),但它会在该语言环境消息的开头和结尾输出密码确认和密码,所以我得到如下内容:"PasswordconfirmationmustmatchPassword"有没有办法将其更改为不同的字符串?PasswordconfirmationandPasswordmustmatch.编辑另一件事是拥有完全自定义的消息,例如:'Setpassword

  8. ruby-on-rails - Rails 渲染带有驼峰命名法的 json 对象 - 2

    我在一个简单的RailsAPI中有以下Controller代码:classApi::V1::AccountsControllerehead:not_foundendendend问题在于,生成的json具有以下格式:{id:2,name:'Simpleaccount',cash_flows:[{id:1,amount:34.3,description:'simpledescription'},{id:2,amount:1.12,description:'otherdescription'}]}我需要我生成的json是camelCase('cashFlows'而不是'cash_flows'

  9. ruby-on-rails - 在 Ruby 或 Rails 中,hash.merge({ :order => 'asc' }) can return a new hash with a new key. 什么可以返回带有已删除键的新散列? - 2

    在Ruby(或Rails)中,我们可以做到new_params=params.merge({:order=>'asc'})现在new_params是一个带有添加键:order的散列。但是是否有一行可以返回带有已删除key的散列?线路new_params=params.delete(:order)不会工作,因为delete方法返回值,仅此而已。我们必须分3步完成吗?tmp_params=paramstmp_params.delete(:order)returntmp_params有没有更好的方法?因为我想做一个new_params=(params[:order].blank?||para

  10. ruby-on-rails - 我如何比较 'Bcrypt' Gem解密的密码和加密的密码 - 2

    我正在尝试对某些帖子的评论使用简单的身份验证。用户使用即时ID和密码输入评论我使用“bcrypt”gem将密码存储在数据库中。在comments_controller.rb中像这样@comment=Comment.new(comment_params)bcrypted_pwd=BCrypt::Password.create(@comment.user_pwd)@comment.user_pwd=bcrypted_pwd当用户想要删除他们的评论时,我使用data-confirm-modalgem来确认数据在这部分,我必须解密用户输入的密码以与数据库中的加密密码进行比较我怎样才能解密密码,

随机推荐