Pregunta ¿Cómo dibujar vista sobre el teclado suave como WhatsApp?


Quiero saber cómo es posible agregar View en la parte superior del teclado, como WhatsApp y Hangout. En la pantalla de chat, insertan la vista de emoticones en la parte superior del teclado virtual abierto.

sample image

¿Alguien sabe cómo lograr este comportamiento?


32
2018-04-17 12:52


origen


Respuestas:


Bueno, he creado un teclado de muestra para chatear aquí...

Aquí, uso la ventana emergente para mostrar la ventana emergente y la altura de la ventana emergente se calcula dinámicamente por la altura del teclado

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

y la altura se calcula usando esta función:

/**
 * 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;

                    }

                }
            });

}

Usando todas estas cosas, puedo hacer un teclado superpuesto perfecto ...

luego, infló la ventana emergente con viewpager y gridview para emoticones.

Además, utilizo una secuencia para mostrar estos emoticones en la vista de lista y la ventana de chat


19
2018-05-13 13:13



Después de un largo tiempo de investigación y prueba y error, encontré otra solución similar a la de Chirag Jain arriba, pero usando un Diálogo personalizado.

    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;

A pesar de que Chirag Jain la respuesta parece ser más clara, la publicaré aquí para tener un método alternativo.


13
2018-05-13 10:04



Por lo que sé, puedes dibujar en otras aplicaciones, sí. Yo mismo he diseñado una aplicación de este tipo. En cuanto a dibujar en una aplicación como el teclado o cualquier otra aplicación en específico, supongo que tendrás que definir un diseño con una altura que sea exactamente la del teclado. Entonces, eso variaría de un dispositivo a otro. Entonces, esto no es posible.

Sigo apegado a mi idea de que WhatsApp simplemente descarta el teclado virtual al presionar el botón de emoticón y lo llama fragmento propio.

Si aún desea seguir con esto, así es como dibuja una "ventana" sobre otras aplicaciones. Estos deberían ser sus parámetros de diseño.

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

Sin embargo, su ancho cambiará a un valor de píxel absoluto ya que desea que la actividad solo se realice sobre el teclado.

Si he entendido mal la pregunta, por favor corrígeme.


3
2018-04-17 15:03



Estaba atrapado en el mismo problema. Finalmente logré resolverlo usando una ventana emergente sobre el teclado virtual. He subido mi solución como un proyecto en github: https://github.com/ankushsachdeva/emojicon


3
2017-09-01 21:44



Lo que pienso es que han creado su propio teclado para sonrisas, y al hacer clic en el icono de la sonrisa o en el icono del teclado, ocultan el teclado de la sonrisa y muestran el teclado normal. hay dos escenarios en el caso de la aplicación 1) si no enfoca la primera vez de editext, entonces no puede ver el botón Mostrar teclado, y la altura del teclado de la sonrisa es exactamente la misma que la del teclado normal, solo obtendremos la altura del teclado después de cambiar el diseño de la vista, significa solo después de que se muestre el teclado, eso significa que están creando su propio teclado ... 2) si enfocas el texto de edición y haces clic en el botón de sonrisa, aparecerá la opción de mostrar el botón del teclado. Corrígeme si no estoy bien en esto


0
2017-08-29 05:24



Recientemente tuve que implementar una vista que estaría encima de un teclado suave. La solución de @Chirag Jain es casi correcta, ¡pero no cuenta con los botones del sistema en la parte inferior de la pantalla! Esto hará que la altura del teclado sea incorrecta en algunos dispositivos como NEXUS 6. Esta solución debería funcionar en todos los dispositivos:

1) cree un diseño que contenga su vista

<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) Vista de enlace

@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) comprobar el teclado y ver la configuración de márgenes

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

0
2018-03-09 11:54



@jirkarrr, ¿por qué no agregas el keyboardInfoContainer de esta manera?

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

Lo hago como su código, pero no puede mostrar el keyboardInfoContainer.


0
2018-05-12 08:13



Utilizo una ventana emergente para poner vista sobre el teclado:

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

    }

Luego trato de saber la altura del teclado:

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

Puedes verificar esto tutorial y esto ejemplo en GitHub


0
2017-11-01 08:59