Task
- When you click the
FloatingActionButtonbutton should turn (resulting in the "plus sign - add" icon to "cross - cancel") and apopupWindowpop-up window should appear; - When the
FloatingActionButtonpressed again, the button should return to its original position, and the window should disappear. - The same should happen when you
popupWindowoutside thepopupWindowzonepopupWindow
The first two items are fully implemented via OnClickListener() . To implement the third one, there is the PopupWindow.OnDismissListener() method, but one thing is that it “ PopupWindow.OnDismissListener() button” on the button, which is the source of the problem discussed in this question.
Decision
private void initFAB(){ fab = (FloatingActionButton) findViewById(R.id.fab); //... final PopupWindow popupWindow = new PopupWindow(popup_window, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); // Срабатывает только при нажатии на кнопку fab.setOnClickListener(new View.OnClickListener() { // Триггер; в начальном состоянии окно убрано boolean fABShowMenu = false; public void onClick(View view) { popupWindow.setOutsideTouchable(true); if (!fABShowMenu){ // должно выполняться, когда окно убрано rotateFabForward(); popupWindow.showAtLocation(fab, Gravity.END | Gravity.BOTTOM, 50, 400); fABShowMenu = true; // теперь окно показано } else{ // должно выполняться, когда окно показано rotateFabBackward(); popupWindow.dismiss(); fABShowMenu = false; // теперь онко убрано } } }); popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() { @Override public void onDismiss(){ rotateFabBackward(); //fABShowMenu = false; } }); } This solution works, but if you close the window by touching it outside, then pressing the button again will not open it, because the fABShowMenu trigger is still true; .
- Ideally, to solve the problem, you need one thing: from the
setOnDismissListenermethodsetOnDismissListenerchange the value offABShowMenu = false;. But you can not - this is a local variable of another method. - We cannot declare a variable without initialization outside the
setOnClickListenermethod — it willVariable ... accessed from within inner class, needs to be declared final. To make itfinalwithout initialization is meaningless, and if initialized, then at the inputif (!fABShowMenu){condition will always be!false, that is,true. - You
setOnDismissListenerpushsetOnDismissListenerinsideOnClickListener(), but then when you press the button in order to close the menu, two events will “shoot” at once -DismissandClick. As the experiment shows,onDismissreturnsfalse, then the onClick will work with this value at the input and in theelse(where we need) we do not get.
Anything can be done without fundamentally changing the decision?
Update
Ideally, to solve the problem, you need one thing: from the
setOnDismissListenermethodsetOnDismissListenerchange the value offABShowMenu = false;.
I beg your pardon, nonsense said. Even if in some incredible way I did what I said, then the onClick method will be onClick , in which we come with fABShowMenu = false; and the menu will open immediately. When you press FAB when the menu is open, two events occur, and that’s the problem.