Move a button in constrainlayout according to finger movement in Android

35 Views Asked by At

I want to move a button in constrainlayout according to finger movement however it has problem. I used the constrainset to reposition the button where I put my finger down, but the button automatically shifted a bit more than I expected. I already know how to do this with RelativeLayout but I want to apply it with ConstrainLayout. Hope everybody help please.

Below is my code:

public class MainActivity extends AppCompatActivity implements View.OnTouchListener {
    AppCompatButton btn;
    ConstraintLayout mLayout;
    ConstraintSet constraintSet;

    @SuppressLint("ClickableViewAccessibility")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        hideNavigationBar();
        constraintSet = new ConstraintSet();
        mLayout = findViewById(R.id.view_layout);
        constraintSet.clone(mLayout);
        btn = findViewById(R.id.btn);
        btn.setOnTouchListener(this);

    }

    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        final float x = motionEvent.getRawX();
        final float y = motionEvent.getRawY();
        switch (motionEvent.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_POINTER_DOWN:
            case MotionEvent.ACTION_POINTER_UP:
                break;
            case MotionEvent.ACTION_MOVE:
                if (x >= 0 && y >= 0) {
                    constraintSet.setHorizontalBias(R.id.btn, (x) / (mLayout.getWidth()));
                    constraintSet.setVerticalBias(R.id.btn, (y) / (mLayout.getHeight()));
                    constraintSet.applyTo(mLayout);
                }
                break;
        }
        return true;
    }
1

There are 1 best solutions below

1
On BEST ANSWER

The problem is the math.

The horizontal bias in ConstraintLayout works so that 0 the button is all the way to the left. and 1 is all the way to the right. So the total travel distance is layout width - button width

float hBias = (x) / (mLayout.getWidth()-mButton.getWidth())
float vBias = (y) / (mLayout.getHeight()-mButton.getHeight())
constraintSet.setHorizontalBias(R.id.btn, hBias);
constraintSet.setVerticalBias(R.id.btn,  vBias);

But you did not say where on the button your finger should position. This would be top left hand corner.

You might want to offset to the middle of the button which would be something like

float hBias = (x - mButton.getWidth() / 2) / (mLayout.getWidth() - mButton.getWidth())
float vBias = (y - mButton.getHeight() / 2) / (mLayout.getHeight() - mButton.getHeight())
constraintSet.setHorizontalBias(R.id.btn, hBias);
constraintSet.setVerticalBias(R.id.btn,  vBias);