You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

IsEnabled=False时Entry控件密码显隐功能失效的解决方案求助

Fixing Password Toggle for Disabled Entry Controls in Xamarin.Forms Android

Hey there! Let's figure out why your password toggle eye icon isn't responding when the Entry is disabled (IsEnabled=False) and how to fix it.

The Root Cause

When you set an Entry's IsEnabled to False, the underlying Android EditText gets marked as non-clickable and non-touchable by default. That means any click events tied to the eye icon won't fire, even if your effect is attached. Also, standard password toggle logic often relies on the EditText being in an enabled state to modify its input type.

Step-by-Step Fix for Your Android Effect

Here's how to adjust your Effect class to bypass the disabled state restriction while keeping the Entry uneditable:

  1. Use Touch Events Instead of Click Events:
    Disabled controls still receive touch events, so we'll listen for those and check if the tap landed on the eye icon area.

  2. Manually Handle Icon Tap Detection:
    Calculate the icon's position on the screen and validate if the touch happened within that region.

  3. Force Password Visibility Toggle:
    Ignore the EditText's enabled state when modifying the input type to show/hide the password.

Here's the updated Effect code:

using Android.Graphics.Drawables;
using Android.Text;
using Android.Views;
using Android.Widget;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

[assembly: ResolutionGroupName("YourAppNamespace")]
[assembly: ExportEffect(typeof(YourApp.Droid.Effects.PasswordToggleEffect), "PasswordToggleEffect")]
namespace YourApp.Droid.Effects
{
    public class PasswordToggleEffect : PlatformEffect
    {
        private Drawable _eyeOpenIcon;
        private Drawable _eyeClosedIcon;
        private bool _isPasswordVisible;
        private EditText _targetEditText;

        protected override void OnAttached()
        {
            if (Control is EditText editText)
            {
                _targetEditText = editText;
                
                // Load your eye drawables (replace with your actual resource IDs)
                _eyeOpenIcon = Context.GetDrawable(Resource.Drawable.ic_eye_open);
                _eyeClosedIcon = Context.GetDrawable(Resource.Drawable.ic_eye_closed);

                // Set consistent bounds for the icons
                var iconSize = 60; // Adjust based on your design needs
                _eyeOpenIcon.SetBounds(0, 0, iconSize, iconSize);
                _eyeClosedIcon.SetBounds(0, 0, iconSize, iconSize);

                // Initialize the password state and icon
                UpdatePasswordDisplayState();

                // Attach touch event listener (works even when EditText is disabled)
                _targetEditText.Touch += OnEditTextTouch;
            }
        }

        private void OnEditTextTouch(object sender, View.TouchEventArgs e)
        {
            var editText = sender as EditText;
            if (editText == null) return;

            // Only handle the "up" touch event to avoid multiple triggers
            if (e.Event.Action != MotionEventActions.Up) return;

            // Check if the touch was on the eye icon area (right side of the EditText)
            var iconRightEdge = editText.Right - _eyeOpenIcon.Bounds.Width();
            if (e.Event.RawX >= iconRightEdge)
            {
                // Toggle password visibility
                _isPasswordVisible = !_isPasswordVisible;
                UpdatePasswordDisplayState();
                
                // Mark the event as handled so the EditText doesn't process it further
                e.Handled = true;
            }
        }

        private void UpdatePasswordDisplayState()
        {
            if (_targetEditText == null) return;

            // Switch input type to show/hide password
            _targetEditText.InputType = _isPasswordVisible
                ? InputTypes.TextVariationVisiblePassword
                : InputTypes.TextVariationPassword | InputTypes.ClassText;

            // Update the displayed icon
            var activeIcon = _isPasswordVisible ? _eyeOpenIcon : _eyeClosedIcon;
            _targetEditText.SetCompoundDrawables(null, null, activeIcon, null);

            // Preserve the cursor position after updating input type
            var cursorPos = _targetEditText.SelectionStart;
            _targetEditText.SetSelection(cursorPos);
        }

        protected override void OnDetached()
        {
            if (_targetEditText != null)
            {
                _targetEditText.Touch -= OnEditTextTouch;
                _eyeOpenIcon?.Dispose();
                _eyeClosedIcon?.Dispose();
                _targetEditText = null;
            }
        }
    }
}

Key Changes Explained

  • Touch Event Listener: We use Touch instead of Click because disabled controls still register touch input.
  • Icon Region Check: We calculate where the eye icon is positioned and only trigger the toggle if the tap lands there.
  • Unrestricted Input Type Modification: We directly change the EditText's InputType regardless of its enabled state, which lets us toggle password visibility without enabling the control for editing.
  • Cursor Preservation: After switching input types, we reset the cursor to its original position for a smoother user experience.

Final Notes

  • Make sure your Xamarin.Forms Entry still has the Effect attached even when IsEnabled=False (Effects work independently of the control's enabled state).
  • Verify your drawable resources are correctly added to the Android project's Resources/Drawable folder.

This fix will let users toggle password visibility on disabled Entry controls while keeping the control uneditable—exactly what you need!

内容的提问来源于stack exchange,提问作者Jakubee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 04:04:21