Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/181.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 如何在像WhatsApp这样的软键盘上绘制视图?_Android_View_Android Softkeyboard - Fatal编程技术网

Android 如何在像WhatsApp这样的软键盘上绘制视图?

Android 如何在像WhatsApp这样的软键盘上绘制视图?,android,view,android-softkeyboard,Android,View,Android Softkeyboard,我想知道如何在键盘上添加视图,比如WhatsApp和Hangout。在聊天屏幕中,他们在打开的软键盘顶部插入表情符号视图 有人知道如何实现这种行为吗 据我所知,您可以利用其他应用程序,是的。我自己设计了这样一个应用程序。至于在应用程序(如键盘)或任何其他特定应用程序上绘图,我想,您必须定义一个与键盘高度完全相同的布局。因此,这将因设备而异。所以,这是不可能的 我仍然坚持我的观点,WhatsApp只是在按下smiley按钮时将软键盘丢弃,并将其称为自己的片段 如果您仍然想继续这样做,下面是您如何

我想知道如何在键盘上添加
视图
,比如WhatsApp和Hangout。在聊天屏幕中,他们在打开的软键盘顶部插入表情符号视图


有人知道如何实现这种行为吗

据我所知,您可以利用其他应用程序,是的。我自己设计了这样一个应用程序。至于在应用程序(如键盘)或任何其他特定应用程序上绘图,我想,您必须定义一个与键盘高度完全相同的布局。因此,这将因设备而异。所以,这是不可能的

我仍然坚持我的观点,WhatsApp只是在按下smiley按钮时将软键盘丢弃,并将其称为自己的片段

如果您仍然想继续这样做,下面是您如何在其他应用程序上画一个“窗口”。这些应该是它的布局参数

params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
                PixelFormat.TRANSLUCENT);
尽管如此,您的宽度将更改为绝对像素值,因为您希望活动仅通过键盘进行


如果我误解了这个问题,请纠正我。

经过长时间的研究和反复尝试,我找到了另一个类似于上面的Chirag Jain的解决方案,但使用了自定义对话框

    mDialogKeyboard = new Dialog(this,android.R.style.Theme_NoTitleBar);
    mDialogKeyboard.setContentView(R.layout.your_custom_layout);
    mDialogKeyboard.getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
    mDialogKeyboard.getWindow().setFlags(WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
    mDialogKeyboard.getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
    mDialogKeyboard.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);

    WindowManager.LayoutParams lp=mDialogKeyboard.getWindow().getAttributes();    
    lp.width=WindowManager.LayoutParams.MATCH_PARENT;
    lp.height=mSoftKeyboardHeight;
    lp.gravity=Gravity.BOTTOM | Gravity.LEFT;
    lp.dimAmount=0;

尽管Chirag Jain的答案似乎更清晰,但我还是会在这里发布这篇文章,以便找到另一种方法。

好吧,我已经创建了一个用于聊天的键盘示例

在这里,我使用弹出窗口来显示弹出窗口,弹出窗口的高度是通过键盘的高度来动态计算的

// Initially defining default height of keyboard which is equal to 230 dip
        final float popUpheight = getResources().getDimension(
                R.dimen.keyboard_height);
        changeKeyboardHeight((int) popUpheight);

// Creating a pop window for emoticons keyboard
    popupWindow = new PopupWindow(popUpView, LayoutParams.MATCH_PARENT,
            (int) keyboardHeight, false);
使用此函数计算高度:

/**
 * Checking keyboard height and keyboard visibility
 */
int previousHeightDiffrence = 0;
private void checkKeyboardHeight(final View parentLayout) {

    parentLayout.getViewTreeObserver().addOnGlobalLayoutListener(
            new ViewTreeObserver.OnGlobalLayoutListener() {

                @Override
                public void onGlobalLayout() {

                    Rect r = new Rect();
                    parentLayout.getWindowVisibleDisplayFrame(r);

                    int screenHeight = parentLayout.getRootView()
                            .getHeight();
                    int heightDifference = screenHeight - (r.bottom);

                    if (previousHeightDiffrence - heightDifference > 50) {                          
                        popupWindow.dismiss();
                    }

                    previousHeightDiffrence = heightDifference;
                    if (heightDifference > 100) {

                        isKeyBoardVisible = true;
                        changeKeyboardHeight(heightDifference);

                    } else {

                        isKeyBoardVisible = false;

                    }

                }
            });

}
使用所有这些东西,我能够制作一个完美的重叠键盘

然后,我用viewpager和gridview将弹出窗口充气以显示表情


此外,我还使用spannable string在listview和聊天窗口中显示这些表情符号

我的想法是,他们已经为微笑创建了自己的键盘,单击微笑图标或键盘图标,他们就隐藏了微笑键盘并显示了普通键盘。whats应用程序案例1)有两种情况,如果你没有第一次聚焦EditText,那么你就看不到显示键盘按钮,微笑键盘的高度与普通键盘的高度完全相同,只有在视图布局更改后,我们才能获得键盘高度,这意味着只有在显示键盘后,这意味着他们正在创建自己的键盘。。2) 如果您聚焦编辑文本并单击微笑按钮,则它将显示“显示键盘按钮”选项。如果我不正确,请纠正我。

我最近必须实现一个位于软键盘上方的视图@Chirag Jain的解决方案几乎是正确的,但屏幕底部的系统按钮不起作用!这将使NEXUS 6等设备上的键盘高度不正确。此解决方案应适用于所有设备:

1) 创建包含视图的布局

<RelativeLayout
        android:id="@+id/keyboard_info_container"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:layout_alignParentBottom="true"
        android:background="@color/C12"
        android:padding="10dp"
        android:visibility="invisible">

           ....

    </RelativeLayout>
3) 键盘检查和查看边距设置

private void checkKeyboardHeight(final View parentLayout) {

    parentLayout.getViewTreeObserver().addOnGlobalLayoutListener(
            new ViewTreeObserver.OnGlobalLayoutListener() {

                int previousHeightDiffrence = 0;
                int systemBarHigh = 999999;

                @Override
                public void onGlobalLayout() {


                    Rect r = new Rect();
                    parentLayout.getWindowVisibleDisplayFrame(r);

                    int screenHeight = parentLayout.getRootView()
                            .getHeight();
                    int keyboardHeight = screenHeight - (r.bottom);

                    if(systemBarHigh > keyboardHeight) {
                        systemBarHigh = keyboardHeight;
                    }

                    if (keyboardHeight > 250) {

                        int keyboardHightWithoutSystemBar = keyboardHeight - systemBarHigh;
                        // no need to update when the keyboard goes down
                        if (previousHeightDiffrence != keyboardHightWithoutSystemBar) { // if (Math.abs(previousHeightDiffrence - keyboardHeight) > 10) {
                            adjustKeyboard(keyboardHightWithoutSystemBar);
                        }

                        keyboardInfoContainer.setVisibility(View.VISIBLE);
                        isKeyBoardVisible = true;
                        previousHeightDiffrence = keyboardHightWithoutSystemBar;

                    } else {
                        isKeyBoardVisible = false;
                        if (keyboardInfoContainer != null) {
                            keyboardInfoContainer.setVisibility(View.INVISIBLE);
                        }
                    }
                }
            });
}

private void adjustKeyboard(int keyboardHeight) {
    RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) keyboardInfoContainer.getLayoutParams();
    lp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
    lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
    lp.bottomMargin = keyboardHeight;
    keyboardInfoContainer.requestLayout();
}

@jirkarrr,为什么不这样添加keyboardInfoContainer:

WindowManager wm = getWindowManager();
WindowManager.LayoutParams lps = new WindowManager.LayoutParams();
lps.x = 0; lps.y = keyboardHeight;
wm.addView(keyboardInfoContainer, lps);

我按照您的代码操作,但它无法显示keyboardInfoContainer。

我使用弹出窗口将视图置于键盘上方:

public void showPopUpKeyboard() {
        mIsPopupVisible = true;
        // Initialize a new instance of LayoutInflater service
        LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);

        // Inflate the custom layout/view
        View customView = inflater.inflate(R.layout.popup_in_keyboard, null);


        mScrollView = (ScrollView) customView.findViewById(R.id.keyboard_layout_view);
        // Initialize a new instance of popup window
        mPopupWindow = new PopupWindow(
                customView,
                RelativeLayout.LayoutParams.MATCH_PARENT,
                RelativeLayout.LayoutParams.MATCH_PARENT
        );


        setSizeForSoftKeyboard();

        // Get a reference for the custom view close button
        Button closeButton = (Button) customView.findViewById(R.id.ib_close);

        // Set a click listener for the popup window close button
        closeButton.setOnClickListener((View view) -> {
                // Dismiss the popup window
                mIsPopupVisible = false;
                mPopupWindow.dismiss();
        });
        mPopupWindow.showAtLocation(mParentLayout, Gravity.CENTER, 0, 0);

    }
然后我试着知道键盘的高度:

mParentLayout.getViewTreeObserver().addOnGlobalLayoutListener(() -> {
                Rect r = new Rect();

                mParentLayout.getWindowVisibleDisplayFrame(r);

                int heightDiff = mParentLayout.getRootView().getHeight() - (r.bottom - r.top);
                if (heightDiff > 100) {
                    //enter your code here
                    if (mIsPopupVisible) {
                        keepKeyboard();
                        mIsPopupVisible = false;
                        mPopupWindow.dismiss();
                    }
                } else {
                    //enter code for hid
                }
        }); 

你可以检查这个和这个

我认为WhatsApp中不会发生这种情况。点击表情按钮只会关闭软键盘并打开笑脸片段,我猜。我的理解是,它不会关闭键盘。我认为它是在打开的键盘上绘制的。看看这些,这是关于如何创建自己的键盘的教程,这并不是我想要的,我可以确认它并没有抛弃软键盘,而是在上面画得很完美。您可以在打开表情视图时看到输入法仍处于活动状态的通知。感谢您的重播,我认为这种方法比WhatsApp贵一点,因为它需要权限android:name=“android.permission.SYSTEM\u ALERT\u WINDOW”和WhatsApp没有向您提供此权限,因此,他们没有在键盘上绘制笑脸片段:)这只是一个简单的“取消”命令。我不确定,因为他们取消了该键盘,并且本机键盘在没有动画的情况下进入,更不用说活动在表情键盘打开时继续缩小视图。您始终可以调整活动其余部分的大小适合表情标签。我确信这只是设计。好的,谢谢你的反馈,我将研究这种方法,并进行必要的更新。如果customlayout是一个片段,并且你正在使用此对话框在片段活动中扩大它,那么如何执行此操作。。它会给你二进制充气错误。不是吗?我很想看看你的项目是如何运作的,但我无法用我的Android Studio克隆它。
mParentLayout.getViewTreeObserver().addOnGlobalLayoutListener(() -> {
                Rect r = new Rect();

                mParentLayout.getWindowVisibleDisplayFrame(r);

                int heightDiff = mParentLayout.getRootView().getHeight() - (r.bottom - r.top);
                if (heightDiff > 100) {
                    //enter your code here
                    if (mIsPopupVisible) {
                        keepKeyboard();
                        mIsPopupVisible = false;
                        mPopupWindow.dismiss();
                    }
                } else {
                    //enter code for hid
                }
        });