Reputation:
I am trying to move the TextView
around on the screen on my android app. But after dragging the TextView
to final position, Its randomly moving to other opposition.
private final class TextViewTouchListener implements View.OnTouchListener {
@Override
public boolean onTouch(View view, MotionEvent event) {
ClipData data = ClipData.newPlainText("", "");
View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
//start dragging the item touched
view.startDrag(data, shadowBuilder, view, 0);
return true;
}
}
private final class TextViewDragListener implements View.OnDragListener {
@Override
public boolean onDrag(View v, DragEvent event) {
final float x = event.getX();
final float y =event.getY();
// handling the case when the textview gets dragged out of screen
leftMargin = Math.min(x, mDisplaySize.x - textview.getWidth());
topargin = Math.min(y, mDisplaySize.y - textview.getHeight());
final FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) textView.getLayoutParams();
params.leftMargin = (int) leftMargin;
params.topMargin = (int) topargin;
params.rightMargin = 0;
params.bottomMargin = 0;
textView.setLayoutParams(params);
return true;
}
}
Seems like I am handling it wrong. Can someone help me what exactly I am doing wrong.
Upvotes: 1
Views: 1104
Reputation: 40820
If you just want to move the view around the screen, no need to use drag/drop; you just can update the view x & y location on the screen using the MotionEvent.ACTION_DOWN
& MotionEvent.ACTION_MOVE
events of View.OnTouchListener
.
And to avoid moving the view off the screen, then we will calculate width & height of the root view using its getViewTreeObserver()
So, your layout would have a root view holding a TextView
which you want to move around the screen.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/root_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World" />
</RelativeLayout>
And your behaviour will be:
public class MainActivity extends AppCompatActivity {
private int mXDelta = 0;
private int mYDelta = 0;
private int mRootWidth;
private int mRootHeight;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final RelativeLayout rootLayout = findViewById(R.id.root_layout);
rootLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
rootLayout.getViewTreeObserver()
.removeOnGlobalLayoutListener(this);
}
mRootWidth = rootLayout.getWidth();
mRootHeight = rootLayout.getHeight();
}
});
TextView textView = findViewById(R.id.textview);
textView.setOnTouchListener(mOnTouchListener);
}
View.OnTouchListener mOnTouchListener = new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent event) {
int xScreenTouch = (int) event.getRawX(); // x location relative to the screen
int yScreenTouch = (int) event.getRawY(); // y location relative to the screen
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
RelativeLayout.LayoutParams lParams = (RelativeLayout.LayoutParams) view.getLayoutParams();
mXDelta = xScreenTouch - lParams.leftMargin;
mYDelta = yScreenTouch - lParams.topMargin;
break;
case MotionEvent.ACTION_MOVE:
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) view
.getLayoutParams();
layoutParams.leftMargin = Math.max(0, Math.min(mRootWidth - view.getWidth(), xScreenTouch - mXDelta));
layoutParams.topMargin = Math.max(0, Math.min(mRootHeight - view.getHeight(), yScreenTouch - mYDelta));
view.setLayoutParams(layoutParams);
break;
}
return true;
}
};
}
Result
Upvotes: 1