简体   繁体   English

为什么我的View.setVisibility(View.INVISIBLE)方法不能按时工作?

[英]Why is my View.setVisibility(View.INVISIBLE) method not working on time?

I'm working on my Android demo which will launch a floating window when certain button is clicked. 我正在开发我的Android演示,当单击某些按钮时,该演示将启动一个浮动窗口。 Then, by clicking the floating window the window itself will hide until the screenshot of current displayed window is taken, and then show itself. 然后,通过单击浮动窗口,窗口本身将隐藏,直到拍摄了当前显示窗口的屏幕截图,然后显示了它自己。

Basically, click floating window -- hide itself -- take screenshot -- display itself . 基本上, 单击浮动窗口-隐藏自身-截屏-显示自身

I Googled around and managed to write some code to make it work. 我在Google周围搜索,并设法编写了一些代码来使其工作。 There is something weird: whenever I clicked the floating window, the window itself is not disappearing on time, namely my every screenshots contain the window's view. 有点奇怪:每当我单击浮动窗口时,窗口本身都不会按时消失,即我的每个屏幕截图都包含该窗口的视图。

The sequence seems to turned into click floating window -- take screenshot -- hide itself -- display itself . 该序列似乎变成了单击浮动窗口-截屏-隐藏自身-显示自身 It shouldn't behave like this! 它不应该这样表现!

The Code: 编码:

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

    windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
    floatIcon = new ImageView(this);
    floatIcon.setImageResource(R.drawable.floating);

    final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.TYPE_PHONE,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
            PixelFormat.TRANSLUCENT);

    params.gravity = Gravity.TOP | Gravity.LEFT;
    params.x = 0;
    params.y = 100;

    windowManager.addView(floatIcon, params);

    try {
        floatIcon.setOnTouchListener(new View.OnTouchListener() {
            private WindowManager.LayoutParams paramsF = params;
            private int initialX;
            private int initialY;
            private float initialTouchX;
            private float initialTouchY;

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        // Get current time in nano seconds.
                        long pressTime = System.currentTimeMillis();

                        // If double click...(click interval should be longer than 2000)
                        if (pressTime - lastPressTime <= 2000) {
//                              createNotification();
//                              ServiceFloating.this.stopSelf();
                            mHasDoubleClicked = true;
                        } else {
                            mHasDoubleClicked = false;
                        }
                        lastPressTime = pressTime;
                        initialX = paramsF.x;
                        initialY = paramsF.y;
                        initialTouchX = event.getRawX();
                        initialTouchY = event.getRawY();
                        break;
                    case MotionEvent.ACTION_UP:
                        if (!mHasDoubleClicked && !mHasMoved) {
                            if (rootUtil == null) {
                                rootUtil = RootUtil.getInstance();
                            }

                            while (floatIcon.isShown()) {
                                try {
                                    Thread.sleep(300);
                                    floatIcon.setVisibility(View.INVISIBLE);
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                            }

                            Vibrator vb = (Vibrator) getSystemService(VIBRATOR_SERVICE);
                            vb.vibrate(100);

                            String tempFileName = String.valueOf(System.currentTimeMillis());
                            rootUtil.execute("screencap -p /sdcard/" + tempFileName + ".png");
                        }
                        floatIcon.setVisibility(View.VISIBLE);
                        break;
                    case MotionEvent.ACTION_MOVE:
                        paramsF.x = initialX + (int) (event.getRawX() - initialTouchX);
                        paramsF.y = initialY + (int) (event.getRawY() - initialTouchY);
                        windowManager.updateViewLayout(floatIcon, paramsF);
                        if ((int) (event.getRawX() - initialTouchX) < 3 && (int) (event.getRawY() - initialTouchY) < 3) {
                            mHasMoved = false; //Move distance within 3 is not recognized as a real move
                        } else {
                            mHasMoved = true;
                        }
                        break;
                }
                return false;
            }
        });
    } catch (Exception e) {
        // TODO: handle exception
    }

I'm stuck here for several days. 我被困在这里几天。 Really appreciate it if anyone could help or give me a hint. 如果有人可以帮助或给我提示,我将不胜感激。

Ps. PS。 I can't understand why no one seems to be interested in this question, is it because that this question is not worth answering at all or just that I'm asking questions in the wrong way/style here? 我不明白为什么没有人对此问题感兴趣,是因为这个问题根本不值得回答,还是因为我在这里以错误的方式/方式提出问题?

[UPDATE] [UPDATE]

Although nobody answered my question after about a week. 尽管大约一个星期后没有人回答我的问题。 I managed to solve this problem, and now I want to post the solve here in case anyone encountered the same kind of question in the future. 我设法解决了这个问题,现在我想在这里发布解决方案,以防将来有人遇到同样的问题。

I did solve the problem of click floating window -- hide itself -- take screenshots -- display itself sequence with the implementation of AsyncTask provided by Android. 我确实通过Android提供的AsyncTask实现解决了单击浮动窗口的问题-隐藏自身-截取屏幕截图-显示其自身顺序。

In the onPreExecute() method of AsyncTask, I put the code of hiding floating window in it. 在AsyncTask的onPreExecute()方法中,我将隐藏浮动窗口的代码放入其中。

In the doInBackground() method of AsyncTask, I put the code of taking screenshots in it. 在AsyncTask的doInBackground()方法中,我放入了获取屏幕截图的代码。

In the onPostExectue() method of AsyncTask, I put the code of displaying floating window in it. 在AsyncTask的onPostExectue()方法中,我放入了显示浮动窗口的代码。

Then at the onTouch() method of my onCreate() , just initialise the AsyncTask and execute it. 然后在我的onCreate()onTouch()方法中,只需初始化AsyncTask并执行它。

Everything works exactly as I expected, I have no idea why the previous code is not working. 一切都按我的预期工作,我不知道为什么以前的代码不起作用。 I've tried to start a new Thread and use Thread.join to wait for the thread of taking screenshots' finish, and then display the floating window, even this is not working), but AsyncTask works. 我试图启动一个新线程并使用Thread.join等待完成截图的线程,然后显示浮动窗口,即使这不起作用),但是AsyncTask也可以工作。

Just hope this will help someone, and I do wish someone could explain to me as well. 只是希望这会对某人有所帮助,我希望有人也能向我解释。

This answer may help to someone, I also faced this issue. 这个答案可能对某人有所帮助,我也遇到了这个问题。 But in my case, I used RotateAnimation to the View. 但就我而言,我对视图使用了RotateAnimation。 If I comment the RotateAnimation code, then View.INVISIBLE is working. 如果我注释RotateAnimation代码,则View.INVISIBLE正在运行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM