java - 用户重新定位 float 操作按钮

标签 java android android-studio material-design floating-action-button

最后我找到了带有 float 操作按钮示例的教程。

链接:http://www.viralandroid.com/2016/02/android-floating-action-menu-example.html

现在我想允许用户将操作按钮移动到屏幕上的任何位置。然后,他可能会打开它并选择其中一个选项。

上次我用 View 对象而不是 FloatingActionButton 对象做了非常相同的事情,而且效果很好。使用 FloatingActionButton,它不会脱落。

我做了两次尝试。

1) 在第一个中,我将 setOnTouchListiner 设置为 LayoutInfater 对象(就像在我的 View 示例中一样),但我唯一能做的就是向左或向右滑动屏幕,然后将按钮稍微向右或向左移动。当我触摸按钮然后移动时 - 没有任何反应。

2) 我还尝试将 setOnTouchListiner 直接设置为 FloatingActionButton,但它甚至没有出现。

如何让用户移动 FloatingActionButton?

这是带有 View 对象的代码,下面是我的尝试编号。 1 带有 FloatingActionButton。

再说一句:FlyingButton 扩展了 Service,MaterialDesingDialog 扩展了 Activity。那是故意的。一般来说,我希望在所有系统图标上都有按钮。由于 MaterialDesingDialog 无法正常工作,我扩展了 Activity 类,因为我怀疑问题出在扩展服务上。

查看对象

public class FlyingButton extends Service {


private WindowManager windowManager;
public Dialog dialog;
View layout,dialogLayout;
int ciekawyX, ciekawyY;

ImageView button1,button2,button3,button_cross;


@Override
public IBinder onBind(Intent intent) {
    // TODO Auto-generated method stub
    return null;
}

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

   setTheme(R.style.AppTheme);

    windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);

    LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
    layout = inflater.inflate(R.layout.activity_main, null);

    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.START;
    params.x = 0;
    params.y = 0;

    windowManager.addView(layout, params);


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

            float move_X_axis,move_Y_axis;

            @Override public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:

                        //Log.e("ACTION_DOWN","1");

                        initialX = paramsF.x;
                        initialY = paramsF.y;
                        initialTouchX = event.getRawX();
                        initialTouchY = event.getRawY();

                        break;
                    case MotionEvent.ACTION_UP:
                        //Log.e("ACTION_UP","2");

                        if( (move_X_axis < 0.1) && (move_Y_axis < 0.1)  ) {
                            if (layout.getWindowToken() != null) {
                                //windowManager.removeView(layout);
                                Log.e(""+move_X_axis,""+move_Y_axis);
                                CustomDialog();
                            }
                        }
                        break;
                    case MotionEvent.ACTION_MOVE:
                        //Log.e("ACTION_MOVE","3");

                        paramsF.x = initialX + (int) (event.getRawX() - initialTouchX);
                        paramsF.y = initialY + (int) (event.getRawY() - initialTouchY);
                        windowManager.updateViewLayout(layout, paramsF);

                        move_X_axis = event.getRawX() - initialTouchX;
                        move_Y_axis = event.getRawY() - initialTouchY;

                        ciekawyX = paramsF.x;
                        ciekawyY = paramsF.y;

                        break;
                }

                return false;
            }
        });


    } catch (Exception e) {
        // TODO: handle exception
    }

}

@Override
public void onDestroy() {
    super.onDestroy();
    //if (chatHead != null) windowManager.removeView(chatHead);
}


public void CustomDialog(){

    LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
    dialogLayout = inflater.inflate(R.layout.dialogbox, null);


    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.START;
    params.x = ciekawyX;
    params.y = ciekawyY;


    if(layout.getWindowToken() != null) {

        windowManager.removeView(layout);
    //}

    //if(dialogLayout.getWindowToken() !=  null){
        windowManager.addView(dialogLayout, params);
    }


    button1 = (ImageView) dialogLayout.findViewById(R.id.button1);

    button1.setOnClickListener(new View.OnClickListener(){
        @Override
        public void onClick(View v)
        {
            Log.e("BRAWO","KLIKNALES BUTTON1");
        }

    });

    button2 = (ImageView) dialogLayout.findViewById(R.id.button2);

    button2.setOnClickListener(new View.OnClickListener(){
        @Override
        public void onClick(View v)
        {
            Log.e("BRAWO","KLIKNALES BUTTON2");
        }

    });

    button3 = (ImageView) dialogLayout.findViewById(R.id.button3);

    button3.setOnClickListener(new View.OnClickListener(){
        @Override
        public void onClick(View v)
        {
            Log.e("BRAWO","KLIKNALES BUTTON3");
        }

    });


    button_cross = (ImageView) dialogLayout.findViewById(R.id.cross_button);

    button_cross.setOnClickListener(new View.OnClickListener(){
        @Override
        public void onClick(View v)
        {

            if(dialogLayout.getWindowToken() != null) {
                windowManager.removeView(dialogLayout);
                //}

                //if(dialogLayout.getWindowToken() !=  null){
                windowManager.addView(layout, params);
            }
        }

    });


}

}

float 操作按钮

public class MaterialDesingDialog extends Activity{

FloatingActionMenu materialDesignFAM;
private WindowManager windowManager;
View inflatedMaterialDesignDialog;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);

    LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
    inflatedMaterialDesignDialog = inflater.inflate(R.layout.material_design_dialogbox, null);

    materialDesignFAM = (FloatingActionMenu) findViewById(R.id.material_design_android_floating_action_menu);


    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.START;
    params.x = 0;
    params.y = 0;

    windowManager.addView(inflatedMaterialDesignDialog, params);

    try {

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

            float move_X_axis,move_Y_axis;

            @Override public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:

                        Log.e("ACTION_DOWN","1");

                        initialX = paramsF.x;
                        initialY = paramsF.y;
                        initialTouchX = event.getRawX();
                        initialTouchY = event.getRawY();

                        break;
                    case MotionEvent.ACTION_UP:
                        Log.e("ACTION_UP","2");


                        break;
                    case MotionEvent.ACTION_MOVE:
                        Log.e("ACTION_MOVE","3");


                        paramsF.x = initialX + (int) (event.getRawX() - initialTouchX);
                        paramsF.y = initialY + (int) (event.getRawY() - initialTouchY);

                        move_X_axis = event.getRawX() - initialTouchX;
                        move_Y_axis = event.getRawY() - initialTouchY;

                        windowManager.updateViewLayout(inflatedMaterialDesignDialog, paramsF);

                        break;
                }

                return false;
            }
        });


    } catch (Exception e) {
        // TODO: handle exception
    }
}
}

最佳答案

我已经在我的项目中实现了这种类型的 float 按钮。我认为您的问题是由 LayoutInflater 引起的。不要在 WindowManager 中设置包含 float 按钮的 View 。将 Floating Button 直接设置为您的 WindowManager

以下是我的代码,对我来说效果很好:

public class notificationService extends Service{

private WindowManager windowManager;
WindowManager.LayoutParams params;
FloatingActionButton Abutton;
Context context;
public FloatingActionMenu menu;
private final IBinder noteBind = new NotificationBinder();

@Override
public boolean onUnbind(Intent intent){
    return false;
}
@Override
public IBinder onBind(Intent intent) {
    // TODO Auto-generated method stub
    return noteBind;
}

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

    windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);

    Abutton = new FloatingActionButton(this);
    Abutton.setProgress(0,true);
    Abutton.setColorNormal(ResourcesCompat.getColor(getResources(),R.color.floatingButtonColor,null));
    Abutton.setColorPressed(ResourcesCompat.getColor(getResources(),R.color.floatingButtonColorPressed,null));
    Abutton.setColorRipple(ResourcesCompat.getColor(getResources(),R.color.floatingButtonColorRipple,null));


    Abutton.setImageResource(R.mipmap.pause_note);
    Abutton.setX(25);


    Abutton.setOnClickListener(new View.OnClickListener() {    //set onclick events here
        @Override
        public void onClick(View view) {

                // Handle your onClick event here.

        }
    });


    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(Abutton,params);  //directly add your floating button here.


    try {
        Abutton.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.

                        initialX = paramsF.x;
                        initialY = paramsF.y;
                        initialTouchX = event.getRawX();
                        initialTouchY = event.getRawY();
                        break;
                    case MotionEvent.ACTION_UP:
                        break;
                    case MotionEvent.ACTION_MOVE:
                        paramsF.x = initialX + (int) (event.getRawX() - initialTouchX);
                        paramsF.y = initialY + (int) (event.getRawY() - initialTouchY);
                        windowManager.updateViewLayout(Abutton, paramsF);
                        break;
                }
                return false;
            }
        });
    } catch (Exception e) {
        // TODO: handle exception
    }

}

@Override
public void onDestroy() {
    super.onDestroy();
    if (Abutton != null) windowManager.removeView(Abutton);
}
}

我仅以编程方式实现了此按钮。所以这里没有 xml 布局。希望这对你有帮助:)

关于java - 用户重新定位 float 操作按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40434722/

相关文章:

java - 可运行不起作用

添加 fragment 后,Android Studio 分解了我的 build.gradle 文件

java - (JAVA) Wildfly 10 CXF 原生依赖模块问题

java - 在 Jenkins 中构建 Maven 期间不支持的类版本

java - 运行 JAR 时出现 ClassNotFoundException,在 IntelliJ IDEA 中运行时没有错误

java - 使用 Java 设置 WebSphere MQ RFH2 header

android - 通过多项选择在 ListView 中获取未选中的项目

android - 如何使 ImageView 在单独的线程上按顺序闪烁?

Android Studio release build 不输出 aar

android-studio - 如何删除Android Studio的模拟器