4

I've got a small ImageView inside of a fullscreen FrameLayout, and I'd like to set it such that when I touch the FrameLayout, the imageview moves to that position.

I've read all the other SO questions I can find about moving ImageView but I haven't seen why my solution is not working yet.

In a custom view which extends FrameLayout:

@Override
public boolean onInterceptTouchEvent(MotionEvent event){

    if(event.getActionMasked() == MotionEvent.ACTION_DOWN){
        ImageView iv = (ImageView) this.findViewById(R.id.draggedImage);
        FrameLayout.LayoutParams params = (LayoutParams) iv.getLayoutParams();
        params.leftMargin = (int) event.getX();
        params.bottomMargin = (int) event.getY();
        iv.setLayoutParams(params);
        iv.invalidate();
        invalidate();           
    }
    return true;
}

I've changed the layoutparams margin to reflect the new touch position, and invalidated the imageview and framelayout (not sure which of these I should be doing), but the imageView doesn't budge (just sits always in the top left corner of the frame).

I've also verified that this method is being called when I touch the screen and the params is getting set with sane X and Y values.

My layout:

<CustomFrameLayout
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <!-- some other unrelated views -->

    <ImageView
        android:id="@+id/draggedImage"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:src="@drawable/pause" />    

</CustomFrameLayout>

Edit: Should have mentioned that I'm trying to target API level 10, so I can't use any of the Honeycomb view orientation goodness :(

Tim
  • 35,413
  • 11
  • 95
  • 121

4 Answers4

3

Through trial and error and searching found that I was missing this call:

params.gravity = Gravity.LEFT | Gravity.BOTTOM;

Initially the gravity was just -1, so the margins had no effect, because it didn't know which side it was supposed to be basing the margins from. Adding a gravity gives it a side to anchor to so that it can be moved out by the amount in the margin.

Works perfectly now.

Tim
  • 35,413
  • 11
  • 95
  • 121
1

I believe that you want to set the top and left padding. See the following question which explains it better than I could. Difference between a View's Padding and Margin

Community
  • 1
  • 1
cstrutton
  • 5,667
  • 3
  • 25
  • 32
  • I think changing the padding does work, though that feels a bit weird to me. To move it by changing the padding, I have to make the imageview fill the entire screen, instead of just moving the imageview. This might be a solution but I kind of wanted to just move the view. – Tim May 10 '12 at 16:30
  • I did a bunch of searching when trying to figure out an alternative to the depreciated absolute layout. The general concensus was to use a frame layout and set positions with padding. If anyone has a better way I would love to hear it. – cstrutton May 10 '12 at 17:40
1

I think that:

iv.setLayoutParams(params);

Is just Setting the params to iv´s layout which is the FrameLayout itself.

You might be able to set ImageView´s Position by iv.setX(); iv.setY();

YuDroid
  • 1,599
  • 5
  • 22
  • 44
Ostkontentitan
  • 6,930
  • 5
  • 53
  • 71
  • Unfortunately setX and setY are only available on API 11+, trying to target API 10 (2.3) – Tim May 10 '12 at 16:28
0

I found Tim's solution of:

params.gravity = Gravity.LEFT | Gravity.BOTTOM;

to change a view's margin, only became necessary when running on devices with android level 10 or less!

The problem didn't show up on levels 14 or 17.

Adding the above code gave the desired behavior on all android levels... Thank you Tim.

Chris Johnson
  • 131
  • 1
  • 5