【问题标题】:Relocationg Floating Action Button by user用户重新定位g浮动操作按钮
【发布时间】:2023-04-04 01:49:01
【问题描述】:

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

链接: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 类,因为我怀疑问题出在扩展 Service 上。

查看对象

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);
            }
        }

    });


}

}

FloatingActionButton

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
    }
}
}

【问题讨论】:

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


    【解决方案1】:

    我在我的项目中实现了这种类型的浮动按钮。我认为您的问题是由于LayoutInflater。不要在WindowManager 中设置包含浮动按钮的视图。将浮动按钮直接设置为您的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布局。希望这对你有帮助:)

    【讨论】:

    • 很遗憾,您的解决方案不起作用。按钮甚至没有出现。我也找不到您设置为按钮的方法。它是:setProgress()、setColorNormal()、setColorPressed()、setColorRipple()。这些都无法解决。也许我们谈论不同的浮动操作按钮?
    • github.com/Clans/FloatingActionButton 我已经实现了这个浮动按钮。我发现也在你的链接中描述了这个按钮。您是否添加了适当的依赖项?
    • 是的,我添加了它。 dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.1.0' compile 'com.android.support:design:23.1.0' compile 'com.github.clans:fab:1.6.2' }
    • 那么问题出在哪里?你能添加错误日志什么的吗?
    • 那是我的错。我导入了 android.support.design.widget.FloatingActionButton 而不是 com.github.clans.fab.FloatingActionButton。现在可以看到方法,但是当谈到 getColor 方法时,它说:Error:(68, 47) error: non-static method getColor(Resources,int,Resources.Theme) cannot be referenced from a static context
    猜你喜欢
    • 2015-06-25
    • 2016-10-10
    • 2020-03-19
    • 1970-01-01
    • 2020-09-23
    • 1970-01-01
    • 1970-01-01
    • 2015-06-25
    • 2019-12-15
    相关资源
    最近更新 更多