繁体   English   中英

强制EditText在后退时失去焦点

[英]Force EditText to lose focus when back pressed

当用户按下后退按钮隐藏键盘时,我试图强制EditText控件失去焦点。 有很多类似的问题已经存在,但几个小时后,我无法使其发挥作用。

首先,只是一点点背景。 我有一个带有自定义项目的ListView。 每个项目都有几个TextView和一个EditText。 我有一个AfterTextChanged()方法保存编辑的值。 如果有焦点,我会设置一个样式来突出显示该字段。 不幸的是,现在更明显的是,当您隐藏(软)键盘时,EditText实际上不会失去焦点,我认为这令人困惑。 如果没有键盘,我希望EditText不会聚焦。

似乎最合理的解决方案是为描述重写OnBackPressed()在活动这里 不幸的是,似乎没有调用我的方法。 即场仍然是聚焦的,并且函数中的断点不会触发。

类似地,活动上的OnKeyUp()侦听器不会触发,并且Xamarin似乎不支持EditText控件的OnKeyUp处理程序。

我不打算在创作或任何东西上压制键盘,因此使用任何隐形控制技巧也无济于事。

很明显很多人都有这个问题。 我相信你们其中一个人已经解决了! 你能分享一下你的解决方案吗?

非常感谢! -Karen

PS我不需要知道如何隐藏键盘。 当用户使用后退按钮隐藏键盘时,我需要执行操作。 谢谢 :)

根据我的经验,onBackPressed()(至少在活动中默认为@Override)在按下后退按钮关闭键盘时通常不会触发。 据我所知,只有当Back press会在当前活动中启动finish()时才会触发。

下面是一种通过监视视图大小的变化来了解何时显示/隐藏键盘的“hacky”方式。 您还必须在AndroidManifest.xml中将Activity设置为android:windowSoftInputMode="adjustResize"

final View activityRootView = findViewById("Your main View");
    activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        Rect r = new Rect();
        //r will be populated with the coordinates of your view that area still visible.
        activityRootView.getWindowVisibleDisplayFrame(r);

        int heightDiff = activityRootView.getRootView().getHeight() - (r.bottom - r.top);
        if (heightDiff > 100) { // if more than 100 pixels, its probably a keyboard...
          //Keyboard is shown


        }
        if(heightDiff <= 100) {
            //Keybaord not shown
        }
     }
    });

真诚地感谢@Shadesblade(和Xamarin的示例代码),我的EditTexts现在没有重点! 这是Xamarin化的解决方案:

在您的活动中,添加以下类:

class GlobalLayoutListener : Java.Lang.Object, ViewTreeObserver.IOnGlobalLayoutListener
{
    Action on_global_layout;
    public GlobalLayoutListener (Action onGlobalLayout)
    {
        on_global_layout = onGlobalLayout;
    }

    public void OnGlobalLayout ()
    {
        on_global_layout ();
    }
}

添加一个类变量来保存View,以便委托可以访问它:

View _rootview;

在你的OnCreate()中添加:

GlobalLayoutListener gll = new GlobalLayoutListener(
    delegate {
        Android.Graphics.Rect r = new Android.Graphics.Rect();
        _rootView.GetWindowVisibleDisplayFrame(r);
        int heightDiff = _rootView.RootView.Height - (r.Bottom - r.Top);
        if (heightDiff < 100)
        {
            if (Window.CurrentFocus != null)
                Window.CurrentFocus.ClearFocus();
        }
    });

_rootView = FindViewById<View>(Resource.Id.relativeLayoutOrder);
_rootView.ViewTreeObserver.AddOnGlobalLayoutListener(gll);

我希望需要使用heightDiff级别来调整和/或必须添加一些旋转检查,但此时我还没有做任何旋转支持,所以我可以直到稍后才进行调整。

再次感谢你! * 快乐的舞蹈 *

添加到Shadesblade的答案,如果你使用的是scrollview,他的答案需要改变才能工作,因为并非所有的scrollview都在屏幕上显示。 所以不要这样做

int heightDiff = activityRootView.getRootView().getHeight() - (r.bottom - r.top);

你应该做

int heightDiff = Utils.getScreenHeight(SearchActivity.this) - (r.bottom - r.top);

Utils.getScreenHeight是这样的:

public static int getScreenHeight(Context c) {
    if (screenHeight == 0) {
        WindowManager wm = (WindowManager) c.getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        screenHeight = size.y;
        screenWidth = size.x;
    }
    return screenHeight;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM