Android开发 之 浮窗

本文介绍如何在Android中使用Service创建一个始终可见的浮动窗口。通过在Service中定义并展示浮窗,确保其即使在其他应用或桌面也能显示。文章详细展示了如何通过按钮触发服务启动,并利用动画效果增强用户体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

自顶定义浮窗

windowManager上添加自己的布局



这个浮窗是在service中定义的,这样才能在任何地方显示他,即使在别的应用中,在桌面上都可以的。因为在于获取WindowManger的传进去的Context对象是谁,activity的话,finish后浮窗就消失,service一直存活于后台,所以会一直显示出来的。

1.在activity中点击按钮启动服务,绑定服务,这里面有个服务链接,可以获取服务对象,调用服务中的显示和隐藏浮窗。
case R.id.bt06:
                Intent intent=new Intent(this,ToastService.class);
                startService(intent);
                bindService(intent, new ServiceConnection() {
                    @Override
                    public void onServiceConnected(ComponentName name, IBinder service) {
                        binder = (ToastService.Mybinder) service;
                        binder.show();
                    }
                    @Override
                    public void onServiceDisconnected(ComponentName name) {
                    }
                }, Context.BIND_AUTO_CREATE);
                break;

2. 再看服务中的代码,有些地方没有优化处理,主要先看这个实现过程
在showToast方法中:通过service获取windowmanger对象,创建windowManger.LayoutParams对象,设置参数
然后加载自己的布局,这里设置了点击布局view隐藏浮动窗口,以及设置了相应的动画。
在hide方法,设置在动画执行结束后windowManger移除所添加的view。
package com.example.zxq.bsquxian.services;

import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.os.Binder;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.view.animation.OvershootInterpolator;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;

import com.example.zxq.bsquxian.R;

/**
 * Created by Administrator on 2017/7/30 0030.
 */

public class ToastService extends Service {
    private View view2;
    private ObjectAnimator translationY;
    private boolean isshow=false;
    private WindowManager windowManager;
    private LinearLayout linearLayout;
    private ObjectAnimator alpha;
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return new Mybinder();
    }

    @Override
    public void onCreate() {
        super.onCreate();

    }

    public class  Mybinder extends Binder
    {
        public void show(){
            showToast();
        }
        public void hide(){
            hide();
        }
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        return super.onStartCommand(intent, flags, startId);
    }
    public void showToast()
    {
        windowManager = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
        WindowManager.LayoutParams params = new WindowManager.LayoutParams();
        params.height = WindowManager.LayoutParams.MATCH_PARENT;
        params.width = WindowManager.LayoutParams.MATCH_PARENT;
        params.format = PixelFormat.TRANSLUCENT;
        params.type = WindowManager.LayoutParams.TYPE_PHONE ;
        params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
                | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                | WindowManager.LayoutParams.FLAG_FULLSCREEN
                | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
        params.gravity = Gravity.LEFT + Gravity.TOP;
        view2 = LayoutInflater.from(getApplicationContext()).inflate(R.layout.windowtoast_layout, null, false);
        view2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                hide();
            }
        });
        ImageView iv= (ImageView) view2.findViewById(R.id.iv);
        linearLayout = (LinearLayout) view2.findViewById(R.id.ll_content);
        iv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(getApplicationContext(),"hhah",Toast.LENGTH_SHORT).show();
            }
        });
        isshow=true;
        windowManager.addView(view2,params);
        alpha = ObjectAnimator.ofFloat(view2, "alpha", 0, 1);
        alpha.setDuration(500);
        alpha.start();

        translationY = ObjectAnimator.ofFloat(linearLayout, "translationY", -100, 0);
        translationY.setDuration(500);
        translationY.setInterpolator(new OvershootInterpolator());
        translationY.start();
    }
    public void hide()
    {
        if(isshow)
        {
            isshow=false;
            alpha = ObjectAnimator.ofFloat(view2, "alpha", 1, 0);
            alpha.setDuration(500);
            alpha.start();

            translationY = ObjectAnimator.ofFloat(linearLayout, "translationY", 0,-100);
            translationY.setDuration(500);
            translationY.start();
            translationY.addListener(new Animator.AnimatorListener() {
                @Override
                public void onAnimationStart(Animator animation) {

                }

                @Override
                public void onAnimationEnd(Animator animation) {
                    windowManager.removeView(view2);
                }

                @Override
                public void onAnimationCancel(Animator animation) {

                }

                @Override
                public void onAnimationRepeat(Animator animation) {

                }
            });

        }
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值