最后我找到了带有 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/