0

I have a View in a RelativeLayout with layout_alignParentBottom and layout_alignParentRight attributes set to true like this :

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/rlroot"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin">

<View
        android:id="@+id/v_green"
        android:layout_height="@dimen/square_size"
        android:layout_width="@dimen/square_size"
        android:background="@color/green"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        />
</RelativeLayout>

I want to be able to move this view around. I am trying to achieve that as below :

@Override
    public boolean onTouch(View v, MotionEvent event) {

        final int X = (int) event.getRawX();
        final int Y = (int) event.getRawY();
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                RelativeLayout.LayoutParams lParams = (RelativeLayout.LayoutParams) v.getLayoutParams();
                xDelta = X - lParams.leftMargin;
                yDelta = Y - lParams.topMargin;
                Log.d("MainActivity","Action_Down:X="+X+",Y="+Y+",xD="+xDelta+",yD="+yDelta+",lm="+lParams.leftMargin+",tm="+lParams.topMargin);             
                break;
            case MotionEvent.ACTION_UP:
                Log.d("MainActivity","Action_up");
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
                Log.d("MainActivity","Action_Pointer_Down");
                break;
            case MotionEvent.ACTION_POINTER_UP:
                Log.d("MainActivity","Action_Pointer_Up");
                break;
            case MotionEvent.ACTION_MOVE:
                RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) v.getLayoutParams();
                layoutParams.leftMargin = X - xDelta;
                layoutParams.topMargin = Y - yDelta;
                layoutParams.rightMargin = -250;
                layoutParams.bottomMargin = -250;

                v.setLayoutParams(layoutParams);

                Log.d("MainActivity","Action_Move:X="+X+",Y="+Y+",xD="+xDelta+",yD="+yDelta);
                break;
        }
        rootLayout.invalidate();
        return true;
    }

The problem is that layoutParams.leftMargin and layoutParams.topMargin are found to be 0 (found from log) so the moment I touch the view it jumps to top left corner then I can move it properly. Why is it 0 when its on bottom right corner of RelativeLayout? Thing is I have four views in four corners of screen inside RelativeLayout and I want to be able to move them around. All have same problem.

nayakasu
  • 889
  • 1
  • 11
  • 32

1 Answers1

1

Finally I found a solution. The problem was with view attributes like alignParentBottom or alignParentTop equal to true. I verified it by removing these attributes from view and I could drag them. So what I did was inside ACTION_DOWN of onTouch I checked if any of the 4 alignParentXXXX attributes are true for the view. If found to be set to true I set it to false and added required initial margin. Below is the sample code for 2 attributes :

case MotionEvent.ACTION_DOWN:
            RelativeLayout.LayoutParams lParams = (RelativeLayout.LayoutParams) v.getLayoutParams();
            if(lParams.getRule(RelativeLayout.ALIGN_PARENT_BOTTOM)==RelativeLayout.TRUE)
            {
                lParams.topMargin = v.getTop();
                lParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM,0);
                Log.d("MainActivity","added Rule bottom");
            }
            if(lParams.getRule(RelativeLayout.ALIGN_PARENT_TOP)==RelativeLayout.TRUE)
            {
                lParams.bottomMargin = v.getBottom();
                lParams.addRule(RelativeLayout.ALIGN_PARENT_TOP,0);
                Log.d("MainActivity","added Rule top");
            }

And similarly for other 2 attributes. And this works for me now. I have also written full code in my blog in case anyone faces this problem in future.

nayakasu
  • 889
  • 1
  • 11
  • 32