以程序方式将两个视图在一个角落对齐



所以这似乎是一个非常简单的问题,但我不知道如何在缩放视图后获得正确的位置。

我正在尝试将一个imageView排列到另一个imageView的右下角。如果我不修改firstImageView,这个代码就可以正常工作。

secondImageView.setX(firstImageView.getRight());
secondImageView.setY(firstImageView.getBottom());

但是,在我对第一个ImageView应用翻译或缩放后,上面的代码似乎无法正常工作(在角落处没有对齐)。我猜缩放不会影响视图的实际大小,即使它已经明显调整了大小。那么,即使在修改了缩放、旋转和/或平移之后,我该如何将secondImageView设置在firstImageView的右下角呢?

编辑:拐角处的两个视图代码

firstImageView.setOnTouchListener(new View.OnTouchListener() {
            float startX, startY;
            float translationX, translationY;
            float startMoveX, startMoveY;

            public boolean onTouch(View v, MotionEvent e) {
                if (e.getAction() == MotionEvent.ACTION_DOWN) {
                    secondImageView.setX(imageView.getRight());
                    secondImageView.setY(imageView.getBottom());
                    secondImageView.setVisibility(View.VISIBLE);
                    startX = e.getRawX();
                    startY = e.getRawY();
                    startMoveX = firstImageView.getX();
                    startMoveY = firstImageView.getY();


                } else if (e.getAction() == MotionEvent.ACTION_MOVE) {
                    translationX = e.getRawX() - startX + startMoveX;
                    translationY = e.getRawY() - startY + startMoveY;
                    firstImageView.setTranslationX(translationX);
                    firstImageView.setTranslationY(translationY);

                    secondImageView.setTranslationX(firstImageView.getX()+firstImageView.getMeasuredWidth());
                    secondImageView.setTranslationY(firstImageView.getY()+firstImageView.getMeasuredHeight());
                } else if (e.getAction() == MotionEvent.ACTION_UP) {
                }
                return true;
            }
        });
    }

缩放代码:

secondImageView.setScaleX(2);
secondImageView.setScaleY(2);

您的假设是正确的翻译不会影响视图的边界。但是,如果在手势开始时计算第二个视图相对于第一个视图的位置偏移(delta),则可以同时平移两个视图。下面是您可以使用的工作示例

activity_test.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent">
  <ImageView
    android:id="@+id/photo"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="false"
    android:layout_marginTop="0dp"
    android:src="@drawable/photo"/>
  <ImageView
    android:id="@+id/photo_two"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignRight="@+id/photo"
    android:layout_alignBottom="@+id/photo"
    android:src="@drawable/ic_launcher"/>
</RelativeLayout>

测试活动.java

public class TestActivity extends Activity {
  private static String TAG = "TestActivity";
  private ImageView mPhoto;
  private ImageView mPhotoTwo;
  private float mStartX;
  private float mStartY;
  private float mDeltaX;
  private float mDeltaY;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_test);
    Log.d(TAG, "onCreate");
    mPhoto = (ImageView)findViewById(R.id.photo);
    mPhotoTwo = (ImageView)findViewById(R.id.photo_two);
    mPhoto.setOnTouchListener(new View.OnTouchListener(){
      @Override
      public boolean onTouch(View view, MotionEvent e) {
        boolean result = false;
        int action = e.getAction();
        if(action == MotionEvent.ACTION_DOWN){
          mStartX = e.getX();
          mStartY = e.getY();
          mDeltaX = mPhoto.getWidth() - mPhotoTwo.getWidth();
          mDeltaY = mPhoto.getHeight() - mPhotoTwo.getHeight();
          result = true;
        }else if(action == MotionEvent.ACTION_MOVE){
          float x = e.getX();
          float y = e.getY();
          float deltaX = x - mStartX;
          float deltaY = y - mStartY;
          float viewX = view.getX();
          float viewY = view.getY();
          float valueX = deltaX + viewX;
          float valueY = deltaY + viewY;
          mPhoto.setX(valueX);
          mPhoto.setY(valueY);
          float valueTwoX = valueX + mDeltaX;
          float valueTwoY = valueY + mDeltaY;
          mPhotoTwo.setX(valueTwoX);
          mPhotoTwo.setY(valueTwoY);
          result = true;
        }
        return result;
      }
    });
  }
}

更新

根据请求,我正在修改代码以从布局文件中删除所有layout_align属性。所有定位(包括视图的初始渲染)都将通过程序进行。

activity_test.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:id="@+id/relativelayout"
  android:layout_width="match_parent"
  android:layout_height="match_parent">
  <ImageView
    android:id="@+id/photo"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/photo"/>
  <ImageView
    android:id="@+id/photo_two"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/ic_launcher"/>
</RelativeLayout>

测试活动.java

public class TestActivity extends Activity {
  private static String TAG = "TestActivity";
  private RelativeLayout mRelativeLayout;
  private ImageView mPhoto;
  private ImageView mPhotoTwo;
  private float mStartX;
  private float mStartY;
  private float mDeltaX;
  private float mDeltaY;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_test);
    Log.d(TAG, "onCreate");
    mRelativeLayout = (RelativeLayout)findViewById(R.id.relativelayout);
    mPhoto = (ImageView)findViewById(R.id.photo);
    mPhotoTwo = (ImageView)findViewById(R.id.photo_two);
    ViewTreeObserver observer = mRelativeLayout.getViewTreeObserver();
    observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
      @Override
      public void onGlobalLayout() {
        float viewX = mPhoto.getX();
        float viewY = mPhoto.getY();
        mDeltaX = mPhoto.getWidth() - mPhotoTwo.getWidth();
        mDeltaY = mPhoto.getHeight() - mPhotoTwo.getHeight();
        float valueTwoX = viewX + mDeltaX;
        float valueTwoY = viewY + mDeltaY;
        mPhotoTwo.setX(valueTwoX);
        mPhotoTwo.setY(valueTwoY);
      }
    });

    mPhoto.setOnTouchListener(new View.OnTouchListener(){
      @Override
      public boolean onTouch(View view, MotionEvent e) {
        boolean result = false;
        int action = e.getAction();
        if(action == MotionEvent.ACTION_DOWN){
          mStartX = e.getX();
          mStartY = e.getY();
          result = true;
        }else if(action == MotionEvent.ACTION_MOVE){
          float x = e.getX();
          float y = e.getY();
          float deltaX = x - mStartX;
          float deltaY = y - mStartY;
          float viewX = view.getX();
          float viewY = view.getY();
          float valueX = deltaX + viewX;
          float valueY = deltaY + viewY;
          mPhoto.setX(valueX);
          mPhoto.setY(valueY);
          float valueTwoX = valueX + mDeltaX;
          float valueTwoY = valueY + mDeltaY;
          mPhotoTwo.setX(valueTwoX);
          mPhotoTwo.setY(valueTwoY);
          result = true;
        }
        return result;
      }
    });
  }
}

最初使用第一个图像比例绘制布局。稍后进行比例更改时,需要重新绘制布局以实现所做的更改。

按比例变化运行requestLayout()或invalidate()

findViewById(android.R.id.content).invalidate();

如果在处理事件的过程中,视图的边界可能需要更改,则视图将调用requestLayout()。

类似地,如果在处理事件的过程中可能需要更改视图的外观,则视图将调用invalidate()。

如果调用了requestLayout()或invalidate(),框架将负责测量、布局和绘制树。

最新更新