重置视图位置,android

Reset view position, android

在我的 android 应用程序中,我让用户移动了一些视图。我通过向视图添加 OnTouchListener 来实现移动 (v.setX()/v.setY()).

现在我希望用户在单击按钮时重置视图位置。重置是指将位置设置为原始位置。而原来的位置就是视图loaded/first显示后的位置。

视图是相对布局的。所以我没有固定的视图坐标。

我尝试使用 v.getX()/v.getY() 在 onCreate() 中获取视图位置,但当时位置始终为零。

XML代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".GameActivity">
    
    ...

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

      ...

        <ImageView
            android:id="@+id/ivCard1"
            android:layout_width="@dimen/card_width"
            android:layout_height="@dimen/card_height"
            android:layout_below="@id/ivCardAnchor"
            android:layout_marginStart="@dimen/card_margin"
            android:layout_marginTop="@dimen/card_margin"
            android:layout_marginEnd="@dimen/card_margin"
            android:layout_marginBottom="@dimen/card_margin"
            android:layout_toStartOf="@+id/ivCard2"
            android:background="@color/black" />

      ...


    </RelativeLayout>

</LinearLayout>

Activity代码:

public class GameActivity extends AppCompatActivity {

    ...
    private ImageView ivCard1;
    ...

    @SuppressLint("ClickableViewAccessibility")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_game);

      ...
        ivCard1 = findViewById(R.id.ivCard1);
      ivCard1.setOnTouchListener(new OnTouchCardListener());
        Log.d(TAG, "onCreate: POS x = " + ivCard1.getX() + ", POS y = " + ivCard1.getY());    // -----> always zero
      ...

    }




     public class OnTouchCardListener implements View.OnTouchListener {
        PointF touchPos = new PointF();
        PointF cardStartPos = new PointF();

        @Override
        public boolean onTouch(View ivCard, MotionEvent event)
        {
            switch (event.getAction())
            {
                case MotionEvent.ACTION_MOVE:
                      ivCard.setX((int) (cardStartPos.x + event.getX() - touchPos.x));
                  ivCard.setY((int) (cardStartPos.y + event.getY() - touchPos.y));
                  cardStartPos.set(ivCard.getX(), ivCard.getY());
                    break;
                case MotionEvent.ACTION_DOWN:
                    touchPos.set(event.getX(), event.getY());
                    cardStartPos.set(ivCard.getX(), ivCard.getY());
                    break;
                case MotionEvent.ACTION_UP:
                    break;
                default :
                    break;
            }
            return true;
        }
    }
}

我删除了代码中不需要的部分。

您可以使用 translation 而不是坐标,然后只需执行以下操作即可重置:

view.setTranslationX(0);
view.setTranslationY(0);

那么您的代码将是:

public class OnTouchCardListener implements View.OnTouchListener {
        PointF touchPos = new PointF();
        PointF cardStartPos = new PointF();

        @Override
        public boolean onTouch(View ivCard, MotionEvent event)
        {
            switch (event.getAction())
            {
                case MotionEvent.ACTION_MOVE:
                    ivCard.setTranslationX((int) (cardStartPos.x + event.getX() - touchPos.x));
                    ivCard.setTranslationY((int) (cardStartPos.y + event.getY() - touchPos.y));
                    cardStartPos.set(ivCard.getTranslationX(), ivCard.getTranslationY());
                    break;
                case MotionEvent.ACTION_DOWN:
                    touchPos.set(event.getX(), event.getY());
                    cardStartPos.set(ivCard.getTranslationX(), ivCard.getTranslationY());
                    break;
                case MotionEvent.ACTION_UP:
                    break;
                default :
                    break;
            }
            return true;
        }
    }