Как нарисовать вид сверху мягкой клавиатуры, например WhatsApp?

Я хочу знать, как можно добавить View поверх клавиатуры, например WhatsApp и Hangouts. На экране чата они вставляют смайлики в открытую открытую мягкую клавиатуру.

sample image

Кто-нибудь знает, как добиться такого поведения?

Ответ 1

Хорошо, я создал образец клавиатуры для общения здесь...

Здесь я использую всплывающее окно для отображения всплывающего окна, а высота всплывающего окна вычисляется динамически по высоте клавиатуры

// 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 строку для показа этих смайликов в окне просмотра и чата

Ответ 2

После тяжелого времени исследований и попыток и ошибок, я нашел другое решение, подобное описанному выше 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 кажется более чистым, я отправлю его здесь для альтернативного метода.

Ответ 3

Насколько я знаю, вы можете использовать другие приложения, да. Я сам разработал такое приложение. Что касается рисования приложения, такого как клавиатура или любое другое приложение в определенном смысле, я думаю, вам нужно будет определить макет с высотой, точно такой же, как на клавиатуре. Таким образом, это будет отличаться от устройства к устройству. Таким образом, это невозможно.

Я по-прежнему придерживаюсь своего представления о том, что WhatsApp просто отклоняет мягкую клавиатуру при нажатии кнопки смайлика и называет ее собственным фрагментом.

Если вы все равно хотите преследовать это, вот как вы рисуете "окно" над другими приложениями. Это должны быть параметры компоновки.

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);

Хотя, ваша ширина изменится на абсолютное значение пикселя, так как вы хотите, чтобы активность была только над клавиатурой.

Если я неправильно понял вопрос, пожалуйста, поправьте меня.

Ответ 4

Я застрял в той же проблеме. Наконец, мне удалось решить эту проблему, используя PopupWindow поверх мягкой клавиатуры. Я загрузил свое решение в качестве проекта в github: https://github.com/ankushsachdeva/emojicon

Ответ 5

Я думаю, что они создали свою собственную клавиатуру для улыбок, а по щелчку значка улыбки или значка клавиатуры они скрывают клавиатуру улыбки и показывают обычную клавиатуру. есть два сценария в случае приложения 1), если вы не фокусируете первый раз на editext, тогда вы не можете видеть кнопку кнопки show show, а высота клавиатуры улыбки точно такая же, как у обычной клавиатуры, мы получим только высоту клавиатуры после изменения нашего макета представления, означает только после того, как отображается клавиатура, это означает, что они создают свою собственную клавиатуру. 2) если вы нажмете кнопку edittext и кнопку улыбки, тогда отобразится опция кнопки show keypad. Пожалуйста, исправьте меня если я не прав на этом

Ответ 6

Недавно мне пришлось реализовать представление, которое было бы выше мягкой клавиатуры. Решение @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>

2) Вид привязки

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View rootview = inflater.inflate(R.layout.notifications_email_settings_fragment, container, false);

    ButterKnife.bind(this, rootview);

    checkKeyboardHeight(rootview);

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();
}

Ответ 7

@jirkarrr, почему бы вам не добавить клавиатуруInfoContainer следующим образом:

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

Я использую ваш код, но он не может отображать клавиатуруInfoContainer.

Ответ 8

Я использую всплывающее окно для просмотра над клавиатурой:

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
                }
        }); 

Вы можете проверить этот учебник и этот пример в GitHub