In my android app I let the user move some views. I implemented the moving by adding an OnTouchListener to the views (v.setX()/v.setY()).
Now I want the user to reset the views positions on button click. With resetting I mean setting the position to the original position. And the original position is the position of the views after they were loaded/first displayed.
The views are in a relative layout. So I don't have fixed coordinates for the views.
I tried to fetch the views positions in onCreate() with v.getX()/v.getY(), but the positions are always zero at that time.
XML code:
<?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 code:
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;
}
}
}
I deleted unnecessary parts of the code.
CodePudding user response:
You can use translation
instead of coordinates and then to reset simply do:
view.setTranslationX(0);
view.setTranslationY(0);
Then your code would be:
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;
}
}