web-dev-qa-db-fra.com

Comment dessiner la vue sur le clavier logiciel comme WhatsApp?

Je veux savoir comment il est possible d'ajouter View au-dessus du clavier comme WhatsApp et Hangout. Dans l'écran de discussion, ils insèrent la vue des émoticônes au-dessus du clavier virtuel ouvert.

sample image

Est-ce que quelqu'un sait comment obtenir ce comportement? 

33
and_dev

Eh bien, j'ai créé un exemple de clavier pour discuter ici ... 

Ici, j'utilise une fenêtre popup pour afficher la fenêtre popup et la hauteur de la popup est calculée dynamiquement par la hauteur du clavier

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

et la hauteur est calculée en utilisant cette fonction:

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

                    }

                }
            });

}

En utilisant toutes ces choses, je suis capable de faire un clavier qui se chevauchent parfaitement ....

puis j'inflate la fenêtre popup avec viewpager et gridview pour les émoticônes.

En outre, j'utilise spannable string pour montrer ces émoticônes dans la fenêtre listview et chat

19
Chirag Jain

Après une longue période de recherches et d'essais et d'essais, j'ai trouvé une autre solution similaire à celle de Chirag Jain ci-dessus, mais en utilisant un dialogue personnalisé.

    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;

Malgré le fait que Chirag Jain réponse semble être plus propre, je vais poster cela ici pour avoir une méthode alternative.

13
Parmaia

Autant que je sache, vous pouvez utiliser d'autres applications, oui. J'ai moi-même conçu une telle application. En ce qui concerne le dessin sur une application telle que le clavier ou toute autre application en particulier, je suppose que vous devrez définir une disposition avec une hauteur exactement celle du clavier. Donc, cela varie d’un appareil à l’autre. Donc, ce n'est pas possible.

Je reste fidèle à mon idée que WhatsApp ne fait que masquer le clavier virtuel en appuyant sur le bouton smiley et appelle son propre fragment.

Si vous souhaitez toujours poursuivre dans cette voie, voici comment vous tracez une "fenêtre" par-dessus d'autres applications. Ceux-ci devraient être ses paramètres de mise en page.

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

Toutefois, votre largeur passera à une valeur absolue en pixels, car vous souhaiteriez que l'activité soit uniquement sur le clavier.

Si j'ai mal compris la question, corrigez-moi s'il vous plaît.

3

J'étais coincé sur le même problème. J'ai finalement réussi à le résoudre en utilisant un clavier contextuel PopupWindow. J'ai téléchargé ma solution en tant que projet sur github: https://github.com/ankushsachdeva/emojicon

3
ankush

@jirkarrr, pourquoi ne pas ajouter le keyboardInfoContainer comme ceci:

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

Je fais comme votre code, mais il ne peut pas montrer le keyboardInfoContainer.

0
GuangkaiRen

J'utilise un popup pour mettre la vue sur le clavier:

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

    }

Ensuite, j'essaie de connaître la hauteur du clavier:

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

Vous pouvez vérifier ce tutoriel et cet exemple dans GitHub

0
Cabezas

J'ai récemment dû implémenter une vue qui serait au-dessus d'un clavier logiciel. La solution de @Chirag Jain est presque correcte, mais elle ne compte pas avec les boutons système en bas de l'écran! Cela rendra la hauteur du clavier incorrecte sur certains appareils tels que NEXUS 6. Cette solution devrait fonctionner sur tous les appareils:

1) créer une mise en page qui contient votre vue

<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) Lier la vue 

@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) vérification du clavier et affichage des paramètres de marge

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
jirkarrrr

ce que je pense, c'est qu'ils ont créé leur propre clavier pour les sourires et qu'en un clic, ils cliquent sur l'icône du sourire ou sur l'icône du clavier pour les masquer et afficher le clavier normal. il y a deux scénarios dans le cas de l'application 1) si vous ne vous concentrez pas sur la 1ère fois d'editext, vous ne pouvez pas voir le bouton Afficher le clavier, et la hauteur du clavier Sourire est exactement la même que celle du clavier normal. après la modification de la présentation de notre vue, signifie uniquement après que le clavier est affiché, cela signifie qu'ils créent leur propre clavier. 2) si vous mettez en évidence le bouton edittext et click of smile, l'option d'affichage du bouton du clavier s'affichera. Corrigez-moi si je ne me trompe pas

0
nilesh