首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在Android中查看软件键盘的可见性?

如何在Android中查看软件键盘的可见性?
EN

Stack Overflow用户
提问于 2010-01-28 04:39:30
回答 29查看 293.1K关注 0票数 545

我需要做一件非常简单的事情--查看是否显示了软件键盘。这在Android中是可能的吗?

EN

回答 29

Stack Overflow用户

回答已采纳

发布于 2011-01-19 23:42:12

新答案

增加了2012年1月25日

由于写了下面的答案,有人提示我存在

ViewTreeObserver

和朋友,从版本1开始就潜伏在SDK中的API。

与需要自定义布局类型相比,一种更简单的解决方案是为活动的根视图提供一个已知ID

,将一个GlobalLayoutListener挂接到ViewTreeObserver中,然后从那里计算活动的视图根和窗口大小之间的大小差:

代码语言:javascript
运行
复制
final View activityRootView = findViewById(R.id.activityRoot);
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        int heightDiff = activityRootView.getRootView().getHeight() - activityRootView.getHeight();
        if (heightDiff > dpToPx(this, 200)) { // if more than 200 dp, it's probably a keyboard...
            // ... do something here
        }
     }
});

使用以下实用程序:

代码语言:javascript
运行
复制
public static float dpToPx(Context context, float valueInDp) {
    DisplayMetrics metrics = context.getResources().getDisplayMetrics();
    return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, valueInDp, metrics);
}

简单!

注意:

您的应用程序必须在Android Manifest中设置此标志

否则上述解决方案将不起作用。

原始答案

是的,这是可能的,但它比应该的要难得多。

如果我需要关心键盘何时出现和消失(这是很常见的),那么我要做的就是将我的顶级布局类自定义为一个覆盖

..。基本的逻辑是,如果布局发现自己填充的区域比窗口的总面积小得多,那么可能会显示软键盘。

代码语言:javascript
运行
复制
import android.app.Activity;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.widget.LinearLayout;

/*
 * LinearLayoutThatDetectsSoftKeyboard - a variant of LinearLayout that can detect when 
 * the soft keyboard is shown and hidden (something Android can't tell you, weirdly). 
 */

public class LinearLayoutThatDetectsSoftKeyboard extends LinearLayout {

    public LinearLayoutThatDetectsSoftKeyboard(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public interface Listener {
        public void onSoftKeyboardShown(boolean isShowing);
    }
    private Listener listener;
    public void setListener(Listener listener) {
        this.listener = listener;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int height = MeasureSpec.getSize(heightMeasureSpec);
        Activity activity = (Activity)getContext();
        Rect rect = new Rect();
        activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
        int statusBarHeight = rect.top;
        int screenHeight = activity.getWindowManager().getDefaultDisplay().getHeight();
        int diff = (screenHeight - statusBarHeight) - height;
        if (listener != null) {
            listener.onSoftKeyboardShown(diff>128); // assume all soft keyboards are at least 128 pixels high
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);       
    }

    }

然后在你的活动课上..。

代码语言:javascript
运行
复制
public class MyActivity extends Activity implements LinearLayoutThatDetectsSoftKeyboard.Listener {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        LinearLayoutThatDetectsSoftKeyboard mainLayout = (LinearLayoutThatDetectsSoftKeyboard)findViewById(R.id.main);
        mainLayout.setListener(this);
        ...
    }


    @Override
    public void onSoftKeyboardShown(boolean isShowing) {
        // do whatever you need to do here
    }

    ...
}
票数 690
EN

Stack Overflow用户

发布于 2012-02-02 14:45:32

所以希望这能帮助到一些人。

鲁本·斯克拉顿给出的新答案很棒,而且非常有效,但只有当你将windowSoftInputMode设置为adjustResize时,它才能真正起作用。如果将其设置为adjustPan,仍然无法使用他的代码片段检测键盘是否可见。为了解决这个问题,我对上面的代码做了这个小小的修改。

代码语言:javascript
运行
复制
final View activityRootView = findViewById(R.id.activityRoot);
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.height();
    if (heightDiff > 0.25*activityRootView.getRootView().getHeight()) { // if more than 25% of the screen, its probably a keyboard...
        ... do something here
    }
 }
});
票数 309
EN

Stack Overflow用户

发布于 2013-09-25 05:58:44

对于计算机来说,这已经是一个永恒的问题了,但这个问题仍然是令人难以置信的相关!

因此,我采用了上面的答案,并对它们进行了一些组合和提炼……

代码语言:javascript
运行
复制
public interface OnKeyboardVisibilityListener {


    void onVisibilityChanged(boolean visible);
}

public final void setKeyboardListener(final OnKeyboardVisibilityListener listener) {
    final View activityRootView = ((ViewGroup) getActivity().findViewById(android.R.id.content)).getChildAt(0);

    activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

        private boolean wasOpened;

        private final int DefaultKeyboardDP = 100;

        // From @nathanielwolf answer...  Lollipop includes button bar in the root. Add height of button bar (48dp) to maxDiff
        private final int EstimatedKeyboardDP = DefaultKeyboardDP + (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? 48 : 0);

        private final Rect r = new Rect();

        @Override
        public void onGlobalLayout() {
            // Convert the dp to pixels.
            int estimatedKeyboardHeight = (int) TypedValue
                    .applyDimension(TypedValue.COMPLEX_UNIT_DIP, EstimatedKeyboardDP, activityRootView.getResources().getDisplayMetrics());

            // Conclude whether the keyboard is shown or not.
            activityRootView.getWindowVisibleDisplayFrame(r);
            int heightDiff = activityRootView.getRootView().getHeight() - (r.bottom - r.top);
            boolean isShown = heightDiff >= estimatedKeyboardHeight;

            if (isShown == wasOpened) {
                Log.d("Keyboard state", "Ignoring global layout change...");
                return;
            }

            wasOpened = isShown;
            listener.onVisibilityChanged(isShown);
        }
    });
}

适用于我:)

注意:

如果您注意到

DefaultKeyboardDP

不适合你的设备,玩价值,并发表评论,让每个人都知道应该是什么价值……最终,我们将获得适合所有设备的正确值!

有关更多详细信息,请查看

半机械人

票数 56
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2150078

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档