312 votes

Création d'une fenêtre de superposition système (toujours en haut)

Je suis en train de créer un toujours-op-bouton haut/cliquables-image ce qui reste au-dessus de toutes les fenêtres de tous les temps.

La preuve de le concept est

J'ai été exemple de code suivant que l'habitude de vivre à cette URL, mais le lien est mort.

J'ai eu du succès et de l'exécution d'un service. Le service affiche du texte en haut à gauche de l'écran tout le temps alors l'utilisateur peut interagir librement avec le reste des applications dans des conditions normales.

Ce que je suis faites est sous-classe ViewGroup et l'ajouter à la racine du gestionnaire de fenêtre avec drapeau TYPE_SYSTEM_OVERLAY. Maintenant, je veux ajouter un bouton cliquable-image à la place de ce texte, qui peut recevoir des événements tactiles sur lui-même. J' essayé primordial "onTouchEvent" pour l'ensemble de l' ViewGroup , mais il n' de ne pas recevoir tout événement.

Comment puis-je recevoir des événements seulement sur certaines parties de mon toujours-sur-dessus vue de groupe? Veuillez suggérer.

public class HUD extends Service {
    HUDView mView;

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Toast.makeText(getBaseContext(),"onCreate", Toast.LENGTH_LONG).show();
        mView = new HUDView(this);
        WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
                0,
//              WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
//                      | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
                PixelFormat.TRANSLUCENT);
        params.gravity = Gravity.RIGHT | Gravity.TOP;
        params.setTitle("Load Average");
        WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
        wm.addView(mView, params);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Toast.makeText(getBaseContext(),"onDestroy", Toast.LENGTH_LONG).show();
        if(mView != null)
        {
            ((WindowManager) getSystemService(WINDOW_SERVICE)).removeView(mView);
            mView = null;
        }
    }
}

class HUDView extends ViewGroup {
    private Paint mLoadPaint;

    public HUDView(Context context) {
        super(context);
        Toast.makeText(getContext(),"HUDView", Toast.LENGTH_LONG).show();

        mLoadPaint = new Paint();
        mLoadPaint.setAntiAlias(true);
        mLoadPaint.setTextSize(10);
        mLoadPaint.setARGB(255, 255, 0, 0);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawText("Hello World", 5, 15, mLoadPaint);
    }

    @Override
    protected void onLayout(boolean arg0, int arg1, int arg2, int arg3, int arg4) {
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        //return super.onTouchEvent(event);
        Toast.makeText(getContext(),"onTouchEvent", Toast.LENGTH_LONG).show();
        return true;
    }
}

168voto

Sarwar Erfan Points 11946

Cela pourrait être une solution stupide. Mais ça marche. Si vous pouvez l’améliorer, s’il vous plaît laissez-moi savoir.

OnCreate de votre Service : J’ai utilisé `` drapeau. C’est le seul changement dans le service.

Maintenant, vous allez commencer à obtenir chaque événement de clic. Ainsi, vous devez rectifier dans votre gestionnaire d’événements.

Dans votre cas de touch ViewGroup

67voto

amirlazarovich Points 496

Suite réponse de @Sam Lu, en effet 4.x Android bloque certains types d’écouter des événements tactiles à l’extérieur, mais certains types, tels que `` , encore faire le travail.

Exemple de

Autorisations

18voto

Sam Lu Points 827

À partir de 4.x Android, Android équipe fixe un problème de sécurité potentiel en ajoutant une nouvelle fonction dans lequel il va ajouter , et enlever drapeaux pour `` windows.

Autrement dit, un fenêtre ne recevra pas n’importe quel événement touch sur plate-forme ICS et, bien sûr, d’utiliser n’est pas une solution viable pour ICS et futurs dispositifs.

13voto

Danny Points 138

Je suis l'un des développeurs de la Tooleap SDK. Nous fournissons également un moyen pour les développeurs d'afficher toujours au-dessus des fenêtres et des boutons, et des et nous l'avons traité avec une situation similaire.

Un des problèmes les réponses ici n'ont pas abordé est celui de l'Android "Sécurisé Boutons".

Sécurisé boutons ont l' filterTouchesWhenObscured de la propriété ce qui signifie que ne peut pas être en interaction avec, si placé sous une fenêtre, même si cette fenêtre ne reçoit aucune touche. Citant le Android documentation:

Indique si le filtre de touche lorsque la vue de la fenêtre est masquée par une autre fenêtre visible. Lorsque la valeur est true, la vue ne sera pas recevoir touche à chaque fois qu'un toast, une boîte de dialogue ou une autre fenêtre s'affiche au-dessus de la vue de la fenêtre. Reportez-vous à la {@link android.vue.Afficher} de sécurité la documentation pour plus de détails.

Un exemple d'un tel bouton est de l' installer bouton lorsque vous essayez d'installer tiers apk. Toute application peut afficher un bouton de ce type s'ajoutant à la disposition de l'affichage de la ligne suivante:

android:filterTouchesWhenObscured="true"

Si vous affichez un toujours-sur-dessus de la fenêtre sur une "Sécurisé Bouton", de sorte que toutes les garanties bouton parties qui sont couverts par une superposition ne le sera pas pour tout touche, même si cette superposition n'est pas cliquable. Donc, si vous êtes de rabotage pour afficher une telle fenêtre, vous devez fournir un moyen pour l'utilisateur de le déplacer ou de le rejeter. Et si une partie de votre superposition transparente, prendre en compte le fait que votre utilisateur peut être confondu pourquoi est un bouton de certaines sous-jacents, l'application n'est pas en travaillant pour lui tout d'un coup.

12voto

Onur Öztürk Points 51

TRAVAILLANT TOUJOURS SUR LE BOUTON IMAGE DU HAUT

premier de tous Désolé pour mon anglais

J’ai éditer vos codes et bouton d’image de travail font qui écoute son événement tactile ne donnent pas de commande tactile pour ses éléments de fond.

Il donne aussi des auditeurs de toucher à d’autres éléments

bouton alingments sont bas et gauche

vous pouvez alingments chage, mais vous devez chages cordinats en cas de contact dans la fi élément

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