31 votes

Comment faire un clavier à l'écran incurvé pour Android

Je voudrais faire une courbe sur le clavier à l'écran pour Android. J'ai examiné le softkeyboard, et de divers autres claviers virtuels sur google code. Aucun que j'ai trouvé impliquent un clavier de forme qui n'est rien d'autre qu'un rectangle. Idéalement, je voudrais créer un clavier est composé de touches réparties sur deux demi-cercles sur les côtés de l'écran (c'est à dire, imaginez la tenue d'un comprimé par les côtés et d'être en mesure de frapper les touches avec vos pouces).

Le code que j'ai examinés, des claviers virtuels sont créés en tant que points de vue (s'étendant habituellement KeyboardView) et apparaissent comme une barre continue à travers le bas de l'écran. Comme une approximation de mon objectif, j'ai essayé de modifier le code que j'ai trouvé sur google code (dotdash-clavier-android) à ne dessiner ses touches dans le coin en bas à gauche et quitter le coin en bas à droite transparent. J'ai été en mesure de remplacer onMeasure affecter les dimensions de la vue (voir ci-dessous), mais cela ne semble modifier la position des touches et pas les positions du conteneur. En d'autres termes, il y a toujours une barre noire de remplir le fond de l'écran.

//Located within KeyboardView
@Override public void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
    this.setMeasuredDimension(200, 200);
}

Est ce que je veux faire encore possible? Est-il plus exact de dire cela? Sont il des projets que je peux utiliser comme des exemples?

J'ai également essayé de définir l'affichage des dimensions à l'aide de ce.setLayoutParams -- mais, ces appels semblent avoir aucun effet. J'ai aussi essayé d'utiliser ce.getParent pour accéder à la vue parent (s'il en existe encore) et d'en modifier les dimensions, mais cette approche ne fonctionne pas (ou, je suis juste de faire le mal). Toute aide serait grandement appréciée.

Merci

Mise à JOUR: 12/21/2012 - je pense que j'ai besoin de remplacer le parent de la classe de la méthode onDraw. La recherche ici , ça ressemble à KeyboardView onDraw méthode s'appuie sur un canevas qui est égale à la taille de l'écran en utilisant le code suivant:

final int width = Math.max(1, getWidth());
final int height = Math.max(1, getHeight());
mBuffer = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBuffer);

Je pense que je peux remplacer onDraw et de dessiner ce que je veux sur la toile.

Mise à JOUR: 12/21/2012 - j'ai surchargé onDraw et il est maintenant clair que la keyboardView est les dimensions que je suis le paramètre (200x200). À l'aide de Hierarchyview, je peux voir que la keyboardview est à l'intérieur d'un framelayout avec l'id InputArea. Ainsi, la barre horizontale qui remplit toute la largeur est-ce framelayout. Mais, je ne suis pas la création d'il -- d'où vient-il et comment puis-je modifier ses dimensions?

Mise à JOUR: 12/22/2012 - Après plusieurs essais, il semble que le comportement (dimensions) d'un keyboardview sont en partie déterminées par l'activité qui l'appelle. Dans le navigateur, j'obtiens le comportement que j'ai décrit: la hauteur de la fenêtre du navigateur se rétrécit à accueillir une barre dans le bas de l'écran qui tient le clavier, même si la largeur du clavier est inférieure à la largeur de l'écran. Dans l'application calendrier, le clavier de taille apparaît comme je l'ai mis (comme un carré dans le coin inférieur gauche) avec le calendrier figurant inchangé en dessous. Donc, il semble impossible d'atteindre mon but avec la plupart des applications à l'aide de cette approche. Une approche alternative pourrait être d'avoir l'IME de service créer un popupwindow ou de la boîte de dialogue. Un des problèmes est que popupwindows besoin d'une vue parent ou d'ancrage pour fixer et je ne pense pas qu'il est possible de trouver le plus haut de la vue à partir de l'éditeur de service. Peut-être que je peux créer une vue transparente sur l'activité en cours et de la place du popup sur le dessus de qui?

Mise à JOUR: 12/23/2012 - Progrès. J'ai trouvé comment afficher un popup à partir du clavier IME. La prochaine étape est de comprendre comment faire les fenêtres pop-up un peu ronde/organique. Voici une capture d'écran de ce que j'ai accompli, suivie par la source. Emulator screenshot of keyboard

Source. La méthode suivante est dans le service de classe IME et appelé par l'enfant (du service) vue onMeasure méthode de sorte que les fenêtres pop-up ouvert, dans le même temps, le clavier est dessiné. J'ai mis les dimensions du clavier pour 1x1 de sorte qu'il n'est pas visible. Le journal des états sont là pour m'aider à comprendre comment la position des fenêtres pop-up.

public void initiatePopupWindow()
{
    try {
        WindowManager wm = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();
        DisplayMetrics dm = new DisplayMetrics();
        display.getMetrics(dm);
        //display.getSize(p);


        Log.i("dotdashkeyboard","initiatePopupWindow (from IME service)");
        LayoutInflater inflater = (LayoutInflater) this.getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View layoutLeft = inflater.inflate(R.layout.popup_layout_left,null);
        View layoutRight = inflater.inflate(R.layout.popup_layout_right, null);
        // create a 300px width and 470px height PopupWindow
        int popupHeight = 300;
        int popupWidth = 200;
        if (popUpLeft == null) popUpLeft = new PopupWindow(layoutLeft, popupWidth, popupHeight, false);
        if (popUpRight == null) popUpRight = new PopupWindow(layoutRight, popupWidth, popupHeight, false);

        int ypos = 0;
        int xposRight = 0;



        if (display.getRotation() == Surface.ROTATION_0) {
            ypos = -(dm.heightPixels / 2 + popupHeight/2);
            xposRight = (dm.widthPixels - popupWidth);
            Log.i("dotdashkeyboard","test rotation=normal");
        } else if (display.getRotation() == Surface.ROTATION_90) {
            ypos = -(dm.heightPixels / 2 + popupHeight/2)/2;
            xposRight = (dm.widthPixels - popupWidth)*2-popupWidth;
            Log.i("dotdashkeyboard","test rotation=90-degrees");
        } else {
            Log.i("dotdashkeyboard","test rotation=unknown=" + display.getRotation());
        }

        popUpLeft.showAtLocation(inputView, Gravity.NO_GRAVITY, 0, ypos);
        popUpRight.showAtLocation(inputView, Gravity.NO_GRAVITY, xposRight, ypos);

        Log.i("dotdashkeyboard","test created popup at ypos="+ypos  + " xposRight=" + xposRight);
        Log.i("dotdashkeyboard","test screenWidth=" + dm.widthPixels + " screenHeight=" + dm.heightPixels);

        Button cancelButton = (Button) layoutLeft.findViewById(R.id.popup_cancel_button);
        //cancelButton.setOnClickListener(inputView.cancel_button_click_listener);
        cancelButton.setOnClickListener(cancel_button_click_listener);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

1voto

j__m Points 5167

Vous semblez être sur la bonne voie ici. Comme vous l'avez indiqué, la plupart des activités réduisent leurs vues pour laisser de la place à la fenêtre du clavier. Par conséquent, si vous voulez que l'activité d'appel remplisse l'écran, vous devez utiliser une fenêtre secondaire, telle qu'une fenêtre contextuelle. Vous pouvez définir les dimensions de votre fenêtre principale sur 0x0.

Avez-vous essayé d'appeler popUpLeft.setBackgroundDrawable(null) / popUpRight.setBackgroundDrawable(null) ? Cela devrait supprimer l’arrière-plan semi-transparent et ne montrer que ce que vous dessinez dessus.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X