8

我的应用程序在某些时候向用户显示一个按钮作为 TYPE_SYSTEM_ALERT,我试图让用户移动它。触摸和移动操作确实使用以下代码注册,但按钮不移动。我错过了什么?

    //create button
    mbtRec = new Button(ACR.getContext()); 
    mbtRec.setText(R.string.start_recording);
    mbtRec.setTypeface(null, Typeface.BOLD);
    mbtRec.setBackgroundColor(Color.RED);       //mbtRec.setBackgroundResource(R.drawable.ic_launcher); 
    mbtRec.setOnClickListener(recButtonOnClickListener);
    mbtRec.setOnTouchListener(recButtonOnTouchListener);
    //create layout params
    recButtonLayoutParams = new WindowManager.LayoutParams();
    recButtonLayoutParams.flags = WindowManager.LayoutParams.FORMAT_CHANGED; //8
    recButtonLayoutParams.format = PixelFormat.RGBA_8888; //PixelFormat.TRANSLUCENT
    recButtonLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
    recButtonLayoutParams.gravity = Gravity.TOP | Gravity.CENTER; //51
    recButtonLayoutParams.width = WindowManager.LayoutParams.FILL_PARENT;
    recButtonLayoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
    paramWindowManager.addView(this.mbtRec, recButtonLayoutParams);


OnTouchListener recButtonOnTouchListener = new View.OnTouchListener() {
        @TargetApi(Build.VERSION_CODES.FROYO)
        @Override
        public boolean onTouch(View v, MotionEvent event) {
             switch(event.getActionMasked())
                {
                    case MotionEvent.ACTION_DOWN:
                        Tools.Log("Drag", "Started Dragging");
                        break;
                    case MotionEvent.ACTION_UP:
                        Tools.Log("Drag", "Stopped Dragging");
                        break;
                    case MotionEvent.ACTION_MOVE:
                        Tools.Log("Drag", "Dragging");


                        recButtonLayoutParams.x =(int) event.getRawX();
                        recButtonLayoutParams.y= (int) event.getRawY();


                        mbtRec.setLayoutParams(recButtonLayoutParams);
                        mbtRec.invalidate();

                        break;
                    default:
                        break;
                }
                return false;
        }               
    };
4

5 回答 5

12

我已经设法通过@yoah 的提示和 10 天的更多研究得到了我想要的东西。我必须在我的电子邮件中添加@pingpongboss ( https://github.com/pingpongboss/StandOut ) 的回复,这对我有很大帮助。

这是我想出并在我的通话录音应用ACR中实现的内容

private WindowManager recButtonWindowManager;
private Button recButton = null;
WindowManager.LayoutParams prms;
boolean touchconsumedbyMove = false;
int recButtonLastX;
int recButtonLastY;
int recButtonFirstX;
int recButtonFirstY;

OnTouchListener recButtonOnTouchListener = new View.OnTouchListener() {
    @TargetApi(Build.VERSION_CODES.FROYO)
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        WindowManager.LayoutParams prm = getRecbuttonLayout();
        int totalDeltaX = recButtonLastX - recButtonFirstX;
        int totalDeltaY = recButtonLastY - recButtonFirstY;

         switch(event.getActionMasked())
            {
                case MotionEvent.ACTION_DOWN:
                    recButtonLastX = (int) event.getRawX();
                    recButtonLastY = (int) event.getRawY();
                    recButtonFirstX = recButtonLastX;
                    recButtonFirstY = recButtonLastY;                   
                    break;
                case MotionEvent.ACTION_UP:
                    break;
                case MotionEvent.ACTION_MOVE:
                    int deltaX = (int) event.getRawX() - recButtonLastX;
                    int deltaY = (int) event.getRawY() - recButtonLastY;
                    recButtonLastX = (int) event.getRawX();
                    recButtonLastY = (int) event.getRawY();
                    if (Math.abs(totalDeltaX) >= 5  || Math.abs(totalDeltaY) >= 5) {
                        if (event.getPointerCount() == 1) {
                            prm.x += deltaX;
                            prm.y += deltaY;
                            touchconsumedbyMove = true;                
                            recButtonWindowManager.updateViewLayout(getManualRecButton(), prm); 
                        }
                        else{
                            touchconsumedbyMove = false;
                        }
                    }else{
                        touchconsumedbyMove = false;
                    }
                    break;
                default:
                    break;
            }
            return touchconsumedbyMove;
    }               
};
    private WindowManager.LayoutParams getRecbuttonLayout() {
    if (prms != null) {
        return prms;
    }
    prms = new WindowManager.LayoutParams();
    prms.format = PixelFormat.TRANSLUCENT;
    prms.flags = LayoutParams.FORMAT_CHANGED; // 8
    prms.type = LayoutParams.TYPE_SYSTEM_ALERT;
    prms.gravity = Gravity.TOP | Gravity.CENTER;
    prms.width = LayoutParams.WRAP_CONTENT;
    prms.height = LayoutParams.WRAP_CONTENT;
    // Tools.Log("getRecbuttonLayout", "return getRecbuttonLayout()");
    return prms;
}

private Button getManualRecButton() {
    if (recButton != null) {
        return recButton;
    }
    recButton = new Button(ACR.getContext());
    recButton.setText(R.string.start_recording);
    recButton.setTypeface(null, Typeface.BOLD);
    recButton.setGravity(Gravity.CENTER_VERTICAL);
    recButton.setBackgroundColor(Color.parseColor("#65FF0000"));
    recButton.setPadding(100, 30, 100, 30);
    recButton.setOnClickListener(recButtonOnClickListener);
    recButton.setOnTouchListener(recButtonOnTouchListener);
    return recButton;
}
于 2013-06-16T12:30:33.493 回答
3

我正在做类似的事情,但使用 marginLeft 和 marginTop。更改布局后,您需要调用

 windowManager.updateViewLayout(recButton, recButtonLayoutParams);
于 2013-06-14T15:42:52.677 回答
1

我认为您需要mbtRec.postInvalidate()改用,删除gravity

于 2013-06-12T20:52:14.903 回答
1

由于您更改了 WindowManager 的布局参数,而不是调用:

mbtRec.setLayoutParams(recButtonLayoutParams);
mbtRec.invalidate();

您应该致电:

paramWindowManager.updateLayout(this.mbtRec, recButtonLayoutParams);

在 ACTION_MOVE 案例结束时。

于 2013-06-14T15:28:51.997 回答
1

您将按钮设置为适合屏幕

recButtonLayoutParams.width = WindowManager.LayoutParams.FILL_PARENT;

所以你不能在x方向移动它。

除非它的父级设置为包装内容,否则你应该如何在 Y 方向上移动它,那么它也会阻止你。

这是我所看到的任何方式,希望这会有所帮助。

于 2013-06-16T08:04:48.817 回答