How do I create a custom click listener on FAB or use the return performClick()
?
I have been trying to get android floating button to respond to click but it doesn't work on my custom click event, I have also tried passing the custom click while initializing the class with no luck. Please what am I missing?
import com.google.android.material.floatingactionbutton.FloatingActionButton;
public class MovableFloatingActionButton extends FloatingActionButton implements View.OnTouchListener {
private final static float CLICK_DRAG_TOLERANCE = 10; // Often, there will be a slight, unintentional, drag when the user taps the FAB, so we need to account for this.
private float downRawX, downRawY;
private float dX, dY;
CustomClickListener customClickListener;
public MovableFloatingActionButton(Context context) {
super(context);
init();
}
public MovableFloatingActionButton(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public MovableFloatingActionButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
setOnTouchListener(this);
}
@Override
public boolean onTouch(View view, MotionEvent motionEvent){
ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams)view.getLayoutParams();
int action = motionEvent.getAction();
if (action == MotionEvent.ACTION_DOWN) {
downRawX = motionEvent.getRawX();
downRawY = motionEvent.getRawY();
dX = view.getX() - downRawX;
dY = view.getY() - downRawY;
return true; // Consumed
}
else if (action == MotionEvent.ACTION_MOVE) {
int viewWidth = view.getWidth();
int viewHeight = view.getHeight();
View viewParent = (View)view.getParent();
int parentWidth = viewParent.getWidth();
int parentHeight = viewParent.getHeight();
float newX = motionEvent.getRawX() + dX;
newX = Math.max(layoutParams.leftMargin, newX); // Don't allow the FAB past the left hand side of the parent
newX = Math.min(parentWidth - viewWidth - layoutParams.rightMargin, newX); // Don't allow the FAB past the right hand side of the parent
float newY = motionEvent.getRawY() + dY;
newY = Math.max(layoutParams.topMargin, newY); // Don't allow the FAB past the top of the parent
newY = Math.min(parentHeight - viewHeight - layoutParams.bottomMargin, newY); // Don't allow the FAB past the bottom of the parent
view.animate()
.x(newX)
.y(newY)
.setDuration(0)
.start();
return true; // Consumed
}
else if (action == MotionEvent.ACTION_UP) {
float upRawX = motionEvent.getRawX();
float upRawY = motionEvent.getRawY();
float upDX = upRawX - downRawX;
float upDY = upRawY - downRawY;
if (Math.abs(upDX) < CLICK_DRAG_TOLERANCE && Math.abs(upDY) < CLICK_DRAG_TOLERANCE) { // A click
if (customClickListener != null) {
customClickListener.onClick(view);
}
return false;
//return performClick();
}
else { // A drag
return true; // Consumed
}
}
else {
return super.onTouchEvent(motionEvent);
}
}
public void setCustomClickListener(CustomClickListener customClickListener) {
this.customClickListener = customClickListener;
}
public interface CustomClickListener {
void onClick(View view);
}
}
This is how I use the class on main activity
MovableFloatingActionButton fl = new MovableFloatingActionButton(this);
fl.setCustomClickListener(new MovableFloatingActionButton.CustomClickListener() {
@Override
public void onClick(View view) {
Log.e("FAB", "Float Clicked");
}
});
Perform click will not work in this case, because you have created your custom click listener, so whenever you use performClick()
, callback of setOnClickListener
will be executed. But you are using CustomClickListener
.
So as solution you have to create other method for performing your click for CustomClickListener
.
Inside your class MovableFloatingActionButton
just add this method:
public void customClick() {
if (customClickListener != null) {
customClickListener.onClick(this);
}
}
and than use this method to execute code.
Another thing to consider is, You have following code.
MovableFloatingActionButton fl = new MovableFloatingActionButton(this);
If you are dynamically using this Floating button and adding it to your views dynamically than no change require.
But if you are using inside xml file and access in Java file than you have to use like this:
MovableFloatingActionButton fl= findViewById(R.id.mov);
and later you can use fl.customClick()
to execute your custom click listener.