Android 实现无需权限的悬浮球效果,可适配至Android 10

前言:

最近闲来无事,突然想起搞一下悬浮球,之前的项目的悬浮球一直都需要授权,android6.0以后需要手动授权,悬浮球使用时就非常不便,这里为大家带来一种无需权限的悬浮球实现方式。

  • 无需权限!
  • 无需权限!

功能:

  • 自动贴边
  • 显示红点
  • 隐藏红点
  • 自由移动
  • 显示悬浮球
  • 隐藏悬浮球
  • 销毁悬浮球
  • 接入简单,可进行自定义拓展

附上demo地址

效果如下:

[图片上传失败...(image-a6f66e-1612423455825)]

以下是主要的代码部分:

MainActivity.class

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.showbtn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                RoundView.getInstance().showRoundView(MainActivity.this);

            }
        });

        findViewById(R.id.hidebtn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                RoundView.getInstance().hideRoundView(MainActivity.this);
            }
        });

        findViewById(R.id.closebtn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                RoundView.getInstance().closeRoundView(MainActivity.this);
            }
        });

        findViewById(R.id.showMsgbtn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                RoundView.getInstance().showRoundMsg();
            }
        });
        findViewById(R.id.hideMsgbtn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                RoundView.getInstance().hideRoundMsg();
            }
        });
        findViewById(R.id.exitbtn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                android.os.Process.killProcess(android.os.Process.myPid());
            }
        });
    }
}

RoundView.class

/**
 * 悬浮窗管理器
 */
public class RoundView {

    private static RoundView sFloatingLayer;

    /**
     * 用于控制在屏幕上添加或移除悬浮窗
     */
    private static WindowManager mWindowManager;

    public static boolean isNearLeft = true;  //判断悬浮球是否在左边

    private static boolean isShow = false;  //判断悬浮球是否已经显示

    private int mWidth,mHeight;   //屏幕的宽高

    public static final int WIN_NONE = 0;// 不展示
    public static final int WIN_SMALL = 1;// 小浮标
    public static final int WIN_BIG = 2;// 展开
    public static final int WIN_HIDE = 3;// 靠边隐藏 无操作隐藏
    public static int winStatus;

    public static boolean isMsg=false;  //红点消息提示是否显示


    /**
     * 小悬浮窗view的实例
     */
    private static RoundWindowSmallView smallWindow;


    /**
     * 隐藏悬浮窗view的实例
     */
    private static RoundWindowHideView hideWindow;

    /**
     * 大悬浮窗view的实例
     */
    private static RoundWindowBigView bigWindow;


    /**
     * 大小悬浮窗view的参数
     */
    private static WindowManager.LayoutParams mLayoutParams;


    public static RoundView getInstance() {
        if (null == sFloatingLayer) {
            synchronized (RoundView.class) {
                if (null == sFloatingLayer) {
                    sFloatingLayer = new RoundView();
                }
            }
        }
        return sFloatingLayer;
    }

    /**
     * 显示悬浮窗
     * @param context
     */
    public void showRoundView(Context context) {
        if(mWindowManager==null){
            mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        }

        //每一次显示浮窗前都重新获取一次宽高,避免横竖屏切换后宽高变化
        getWidthAndHeight(context);

        if(!isShow){
            //处于非显示状态,可以显示
            isShow=true;
            if(winStatus==WIN_NONE){
                //处于未创建状态,请创建
                showSmallwin(context);
            }else {
                //已创建了,直接显示
                switch (winStatus){
                    case WIN_SMALL:
                        if(smallWindow!=null)
                            smallWindow.setVisibilityState(View.VISIBLE);
                        break;
                    case WIN_BIG:
                        if(bigWindow!=null)
                            bigWindow.setVisibilityState(View.VISIBLE);
                        break;
                    case WIN_HIDE:
                        if(hideWindow!=null)
                            hideWindow.setVisibilityState(View.VISIBLE);
                        break;
                }
            }
        }
    }

    /**
     * 隐藏悬浮窗
     * @param context
     */
    public void hideRoundView(Context context) {
        if(isShow){
            //处于显示状态,可以隐藏
            isShow=false;
            switch (winStatus){
                case WIN_SMALL:
                    if(smallWindow!=null)
                    smallWindow.setVisibilityState(View.GONE);
                    break;
                case WIN_BIG:
                    if(bigWindow!=null)
                    bigWindow.setVisibilityState(View.GONE);
                    break;
                case WIN_HIDE:
                    if(hideWindow!=null)
                    hideWindow.setVisibilityState(View.GONE);
                    break;
            }
        }
    }

    /**
     * 销毁悬浮窗
     * @param context
     */
    public void closeRoundView(Context context) {
        isShow=false;
        isMsg=false;
        winStatus=WIN_NONE;
        removeSmallWindow(context);
        removeBigWindow(context);
        removeHideWindow(context);
    }

    /**
     * 显示红点提示
     */
    public void showRoundMsg() {
        if(!isMsg){
            isMsg=true;
            switch (winStatus){
                case WIN_SMALL:
                    if(smallWindow!=null)
                        smallWindow.showRoundMsg();
                    break;
                case WIN_BIG:
                    if(bigWindow!=null)
                        bigWindow.showRoundMsg();
                    break;
                case WIN_HIDE:
                    if(hideWindow!=null)
                        hideWindow.showRoundMsg();
                    break;
            }
        }
    }

    /**
     * 隐藏红点提示
     */
    public void hideRoundMsg() {
        if(isMsg){
            isMsg=false;
            switch (winStatus){
                case WIN_SMALL:
                    if(smallWindow!=null)
                        smallWindow.hideRoundMsg();
                    break;
                case WIN_BIG:
                    if(bigWindow!=null)
                        bigWindow.hideRoundMsg();
                    break;
                case WIN_HIDE:
                    if(hideWindow!=null)
                        hideWindow.hideRoundMsg();
                    break;
            }
        }
    }

    /**
     * 显示小悬浮窗
     * @param context context
     */
    public void showSmallwin(final Context context) {
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                createSmallWindow(context);
                removeBigWindow(context);
                removeHideWindow(context);
            }
        }, 500);
    }


    /************************************************ 创建窗口 ************************************************************/

    /**
     * 创建一个小悬浮窗。初始位置在屏幕的左上角位置
     *
     * @param context 必须为应用程序的Context
     */
    public void createSmallWindow(Context context) {
        //每一次创建前都要重新获取宽高,不然横竖屏切换时会出问题
        getWidthAndHeight(context);
        if (smallWindow == null) {
            smallWindow = new RoundWindowSmallView(context);
            if (mLayoutParams == null) {
                mLayoutParams = new WindowManager.LayoutParams();

                mLayoutParams.format = PixelFormat.RGBA_8888;// 解决带Alpha的32位png图片失真问题
                mLayoutParams.gravity = Gravity.LEFT | Gravity.TOP; //显示在左上角
                mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
                // 在设置宽高
                mLayoutParams.x = 0;
                mLayoutParams.y = context.getResources().getDisplayMetrics().heightPixels / 3 * 2;

                mLayoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
                mLayoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
            }
        }

        mLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG; //设置悬浮窗的层次

        if (!isNearLeft) {// 当在屏幕右侧时 重新计算x坐标
            int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
            int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
            smallWindow.measure(w, h);
            if (Configuration.ORIENTATION_LANDSCAPE == context.getResources().getConfiguration().orientation) {// 横屏
                mLayoutParams.x = mWidth - smallWindow.getMeasuredWidth();
            } else {// 竖屏
                mLayoutParams.x = mWidth - smallWindow.getMeasuredWidth();
            }
        }

        smallWindow.setParams(mLayoutParams);

        // 将悬浮球添加到窗体
        if (smallWindow.getParent() == null) {
            mWindowManager.addView(smallWindow, mLayoutParams);
        }

        winStatus=WIN_SMALL;

        smallWindow.timehide();// 小悬浮窗3s后隐藏动画
    }

    /**
     * 将小悬浮窗从屏幕上移除
     *
     * @param context 必须为应用程序的context
     */
    public void removeSmallWindow(Context context) {
        if (smallWindow != null) {
            smallWindow.stopDelayed();
            if (context != null) {
                if (mWindowManager != null) {
                    try {
                        mWindowManager.removeView(smallWindow);
                    } catch (Exception e) {

                    }
                }
                smallWindow = null;
            } else {
                smallWindow = null;
            }
        }
    }

    /**
     * 创建一个隐藏悬浮窗。
     *
     * @param context 必须为应用程序的Context
     */
    public void createHideWindow(Context context) {

        //每一次创建前都要重新获取宽高,不然横竖屏切换时会出问题
        getWidthAndHeight(context);

        if (hideWindow == null) {

            int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
            int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
            smallWindow.measure(w, h);// 测量

            int width = smallWindow.getMeasuredWidth();// 获得视图实际宽度(测量宽度)
            if (isNearLeft) {
                hideWindow = new RoundWindowHideView(context);
            } else {
                hideWindow = new RoundWindowHideView(context);
                mLayoutParams.x = mLayoutParams.x + width / 2;
            }

        }

        mWindowManager.addView(hideWindow, mLayoutParams);

        winStatus=WIN_HIDE;
    }


    /**
     * 将隐藏悬浮窗从屏幕上移除
     *
     * @param context 必须为应用程序的context
     */
    public void removeHideWindow(Context context) {
        if (hideWindow != null) {
            if (context != null) {
                if (mWindowManager != null) {
                    mWindowManager.removeView(hideWindow);
                }
            }
            hideWindow = null;
        }
    }

    /**
     * 创建一个大悬浮窗。
     *
     * @param context 必须为应用程序的Context
     */
    public  void createBigWindow(Context context) {

        //每一次创建前都要重新获取宽高,不然横竖屏切换时会出问题
        getWidthAndHeight(context);

        int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
        int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
        if (bigWindow == null) {
            if (smallWindow != null) {
                smallWindow.measure(w, h);
            } else if (hideWindow != null) {
                hideWindow.measure(w, h);
            }
            bigWindow = new RoundWindowBigView(context);
        }
        bigWindow.measure(w,h);
        if (mLayoutParams.x>(mWidth-bigWindow.getMeasuredWidth())){
            // 在右边拖动的时候需要减去虚拟按钮
            mLayoutParams.x = mWidth-bigWindow.getMeasuredWidth();
        }
        mLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL+1; //设置悬浮窗的层次 数据越大则越下面
        mWindowManager.addView(bigWindow, mLayoutParams);

        winStatus=WIN_BIG;
    }


    /**
     * 将大悬浮窗从屏幕上移除
     *
     * @param context 必须为应用程序的context
     */
    public void removeBigWindow(Context context) {
        if (bigWindow != null) {
            if (context != null) {
                if (mWindowManager != null) {
                    mWindowManager.removeView(bigWindow);
                }
            }
            bigWindow = null;
        }
    }



    /**
     * 获取全屏状态下的宽高
     * @param context
     */
    public void getWidthAndHeight(Context context){
        mWidth=context.getResources().getDisplayMetrics().widthPixels;
        mHeight = context.getResources().getDisplayMetrics().heightPixels;

        //有的手机是有虚拟导航键的,当横屏且全屏时,悬浮球无法靠到最右边,所以要用包含虚拟导航键的屏幕宽度
        Point point = new Point();
        if (mWindowManager != null) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                mWindowManager.getDefaultDisplay().getRealSize(point);
                mWidth=point.x;
                //mHeight =point.y;
            }
        }
    }
}

RoundWindowBigView.class

/**
 * 悬浮窗展开状态
 */
public class RoundWindowBigView extends LinearLayout {

    private Context context;
    private ImageView iv_content;

    /**
     * 红点消息提示
     */
    private View msg;


    public RoundWindowBigView(Context context) {
        super(context);
        this.context = context;
        if (RoundView.isNearLeft) {
            LayoutInflater.from(context).inflate(FileUtil.getResIdFromFileName(context, "layout", "pop_left"), this);
        } else {
            LayoutInflater.from(context).inflate(FileUtil.getResIdFromFileName(context, "layout", "pop_right"), this);
        }
        iv_content = (ImageView) findViewById(  FileUtil.getResIdFromFileName(context, "id", "iv_content"));

        msg=findViewById(FileUtil.getResIdFromFileName(context, "id", "round_msg"));

        if(RoundView.isMsg){
            msg.setVisibility(VISIBLE);
        }else {
            msg.setVisibility(GONE);
        }

        setupViews();
    }

    private void setupViews() {
        iv_content.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View arg0) {
                new Handler().post(new Runnable() {
                    @Override
                    public void run() {
                        // 只能先创建在移除,不然有问题
                        RoundView.getInstance().createSmallWindow(context);
                        RoundView.getInstance().removeBigWindow(context);
                    }
                });
            }
        });

    }

    public void setVisibilityState(int state){
        this.setVisibility(state);
    }


    /**
     * 红点消息显示
     */
    public void showRoundMsg(){
        msg.setVisibility(VISIBLE);
    }

    /**
     * 红点消息隐藏
     */
    public void hideRoundMsg(){
        msg.setVisibility(GONE);
    }
}

RoundWindowHideView.class

/**
 * 悬浮窗贴边状态
 */
public class RoundWindowHideView extends LinearLayout {

    private ImageView hideview;
    private Context context;
    /**
     * 红点消息提示
     */
    private View msg;

    public RoundWindowHideView(Context context) {
        super(context);
        this.context = context;
        if (RoundView.isNearLeft) {
            LayoutInflater.from(context).inflate(FileUtil.getResIdFromFileName(context, "layout", "layout_hide_float_left"), this);
        } else {
            LayoutInflater.from(context).inflate(FileUtil.getResIdFromFileName(context, "layout", "layout_hide_float_right"), this);
        }
        hideview = (ImageView) findViewById(  FileUtil.getResIdFromFileName(context, "id", "hide_float_iv"));

        msg=findViewById(FileUtil.getResIdFromFileName(context, "id", "round_msg"));

        if(RoundView.isMsg){
            msg.setVisibility(VISIBLE);
        }else {
            msg.setVisibility(GONE);
        }

        setupViews();
    }
    private void setupViews() {
        hideview.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View arg0) {
                // 只能先创建在移除,不然有问题
                RoundView.getInstance().createSmallWindow(context);
                RoundView.getInstance().removeHideWindow(context);
            }
        });

    }

    public void setVisibilityState(int state){
        this.setVisibility(state);
    }

    /**
     * 红点消息显示
     */
    public void showRoundMsg(){
        msg.setVisibility(VISIBLE);
    }

    /**
     * 红点消息隐藏
     */
    public void hideRoundMsg(){
        msg.setVisibility(GONE);
    }

}

RoundWindowSmallView.class

/**
 * 悬浮窗常规状态
 */
public class RoundWindowSmallView extends LinearLayout {

    private static final String TAG = "RoundView";
    private Context context;

    private WindowManager windowManager;

    private WindowManager.LayoutParams mParams;

    private float mPrevX;
    private float mPrevY;
    private int mWidth,mHeight;

    private Timer mAnimationTimer;
    private AnimationTimerTask mAnimationTask;
    private Handler mHandler = new Handler();
    private int mAnimationPeriodTime = 16;

    private long mLastTouchDownTime;  //按下的时间
    private final int TOUCH_TIME_THRESHOLD = 150;  //少于150毫秒算点击事件
    private long lastClickTime;

    /**
     * 小悬浮窗对象
     */
    private View view;

    /**
     * 红点消息提示
     */
    private View msgLeft,msgRight;


    public RoundWindowSmallView(final Context context) {
        super(context);
        this.context=context;
        windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);

        mWidth=getContext().getResources().getDisplayMetrics().widthPixels;
        mHeight = getContext().getResources().getDisplayMetrics().heightPixels;

        Point point = new Point();
        if (windowManager != null) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                windowManager.getDefaultDisplay().getRealSize(point);
                mWidth=point.x;
                //mHeight =point.y;
            }
        }

        // 获取布局文件
        LayoutInflater.from(context).inflate(FileUtil.getResIdFromFileName(context, "layout", "round_view"), this);
        view = findViewById(FileUtil.getResIdFromFileName(context, "id", "rl_content"));
        msgLeft=findViewById(FileUtil.getResIdFromFileName(context, "id", "round_msg_left"));
        msgRight=findViewById(FileUtil.getResIdFromFileName(context, "id", "round_msg_right"));

        if(RoundView.isMsg){
            if(RoundView.isNearLeft){
                msgLeft.setVisibility(VISIBLE);
            }else {
                msgRight.setVisibility(VISIBLE);
            }
        }else {
            msgLeft.setVisibility(GONE);
            msgRight.setVisibility(GONE);
        }

        this.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                switch (motionEvent.getActionMasked()) {
                    case MotionEvent.ACTION_DOWN:   //按下
                        mLastTouchDownTime = System.currentTimeMillis();
                        handler.removeMessages(1);
                        mPrevX = motionEvent.getRawX();
                        mPrevY = motionEvent.getRawY();
                        break;
                    case MotionEvent.ACTION_MOVE:
                        float deltaX = motionEvent.getRawX() - mPrevX;
                        float deltaY = motionEvent.getRawY() - mPrevY;
                        mParams.x += deltaX;
                        mParams.y += deltaY;
                        mPrevX = motionEvent.getRawX();
                        mPrevY = motionEvent.getRawY();

                        //判断是否越界
                        if (mParams.x < 0) mParams.x = 0;
                        if (mParams.x > mWidth - view.getWidth())
                            mParams.x = mWidth - view.getWidth();
                        if (mParams.y < 0) mParams.y = 0;
                        if (mParams.y > mHeight - view.getHeight())
                            mParams.y = mHeight - view.getHeight();

                        try {
                            windowManager.updateViewLayout(view, mParams);
                        } catch (Exception e) {
                            Log.d(TAG, e.toString());
                        }

                        break;
                    case MotionEvent.ACTION_CANCEL:
                    case MotionEvent.ACTION_UP:  //松开
                        if (isOnClickEvent()) {
                            //添加点击事件
                            if (isFastDoubleClick()) {
                                //防止连续点击,如果连续点击这里什么也不做
                            } else {
                                //Toast.makeText(context, "你点击了悬浮球", Toast.LENGTH_SHORT).show();
                                new Handler().post(new Runnable() {
                                    @Override
                                    public void run() {
                                        RoundView.getInstance().createBigWindow(context);
                                        RoundView.getInstance().removeSmallWindow(context);
                                    }
                                });
                                return false;
                            }
                        }

                        //贴边
                        mAnimationTimer = new Timer();
                        mAnimationTask = new AnimationTimerTask();
                        mAnimationTimer.schedule(mAnimationTask, 0,mAnimationPeriodTime);
                        timehide();  //3s钟后隐藏
                        break;

                }

                return false;
            }
        });
    }


    /**
     * 将小悬浮窗的参数传入,用于更新小悬浮窗的位置
     *
     * @param params 小悬浮窗的参数
     */
    public void setParams(WindowManager.LayoutParams params) {
        mParams = params;
    }


    //防止连续点击
    private boolean isFastDoubleClick() {
        long time = System.currentTimeMillis();
        if (time - lastClickTime < 500) {   //点击间隔设置大于动画执行时间,避免重复点击造成多次执行动画
            return true;
        }
        lastClickTime = time;
        return false;
    }
    protected boolean isOnClickEvent() {
        return System.currentTimeMillis() - mLastTouchDownTime < TOUCH_TIME_THRESHOLD;
    }

    class AnimationTimerTask extends TimerTask {

        int mStepX;
        int mDestX;

        public AnimationTimerTask() {
            if (mParams.x > mWidth / 2) {
                RoundView.isNearLeft = false;
                mDestX = mWidth - view.getWidth();
                mStepX = (mWidth - mParams.x) / 10;
            } else {
                RoundView.isNearLeft = true;
                mDestX = 0;
                mStepX = -((mParams.x) / 10);
            }
        }

        @Override
        public void run() {
            if (Math.abs(mDestX - mParams.x) <= Math.abs(mStepX)) {
                mParams.x = mDestX;
            } else {
                mParams.x += mStepX;
            }
            try {
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        updateViewPosition();
                    }
                });
            } catch (Exception e) {
                Log.d(TAG, e.toString());
            }
            if (mParams.x == mDestX) {
                mAnimationTask.cancel();
                mAnimationTimer.cancel();
            }
        }


    }

    public void setVisibilityState(int state){
        if(state==View.VISIBLE){
            timehide();
        }else if(state==View.GONE){
            handler.removeMessages(1);
        }
        this.setVisibility(state);
    }

    public void updateViewPosition(){
        windowManager.updateViewLayout(this, mParams);
    }

    /**
     * 显示小浮标是否添加3秒隐藏
     */
    public void timehide() {
        Message msg = new Message();
        msg.what = 1;
        handler.sendMessageDelayed(msg, 3000);
    }

    /**
     * 小浮标停止隐藏
     */
    public void stopDelayed() {
        if (handler != null) {
            handler.removeMessages(1);
        }
    }
    /**
     * handler处理:隐藏半球
     */
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 1:
                    hidePop();
                    break;
                default:
                    break;
            }
        }
    };

    /**
     * 退出动画
     *
     */
    public void hidePop(){
        Animation mAnimation = null;
        if (RoundView.isNearLeft) {
            mAnimation = AnimationUtils.loadAnimation(context,  FileUtil.getResIdFromFileName(context, "anim", "slide_out_left"));
        } else {
            mAnimation = AnimationUtils.loadAnimation(context,   FileUtil.getResIdFromFileName(context, "anim", "slide_out_right"));
        }
        view.startAnimation(mAnimation);
        mAnimation.setAnimationListener(new Animation.AnimationListener() {

            @Override
            public void onAnimationStart(Animation animation) {
            }

            @Override
            public void onAnimationRepeat(Animation animation) {
            }

            @Override
            public void onAnimationEnd(Animation animation) {
                //动画执行完毕后切换视图
                // 只能先创建在移除,不然有问题
                RoundView.getInstance().createHideWindow(context);
                RoundView.getInstance().removeSmallWindow(context);
            }
        });
    }

    /**
     * 红点消息显示
     */
    public void showRoundMsg(){
        if(RoundView.isNearLeft){
            msgLeft.setVisibility(VISIBLE);
        }else {
            msgRight.setVisibility(VISIBLE);
        }
    }

    /**
     * 红点消息隐藏
     */
    public void hideRoundMsg(){
        msgLeft.setVisibility(GONE);
        msgRight.setVisibility(GONE);
    }
}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,056评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,842评论 2 378
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,938评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,296评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,292评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,413评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,824评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,493评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,686评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,502评论 2 318
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,553评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,281评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,820评论 3 305
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,873评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,109评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,699评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,257评论 2 341

推荐阅读更多精彩内容