Reputation: 85
I am trying to make TextView
which moves across the screen in all directions randomly using translateAnimation
. I need text moving like in screen saver for example going round and round until it is clicked.But have some problems:
1. text moves just from top to bottom
2.it doesn't stop in screen borders , it is going off the screen then coming back again :
public class aktivityStarted extends AppCompatActivity {
TextView textMovin;
/* int loc[]=new int[2];
int x=loc[0];
int y=loc[1];*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_aktivity_started);
textMovin=findViewById(R.id.movingText);
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
final int width = displaymetrics.widthPixels-textMovin.getWidth();
final int height = displaymetrics.heightPixels-textMovin.getHeight();
final Random r = new Random();
final int translationX = r.nextInt(width);
final int translationY = r.nextInt(height);
final int randomx=r.nextInt(50)+1;
final int randomy=r.nextInt(50)+1;
final TranslateAnimation anim = new TranslateAnimation(-translationX,translationX ,-translationY,translationY ); //Use current view position instead of `currentX` and `currentY`
anim.setDuration(2500);
anim.setRepeatCount(-1);
anim.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
anim.reset();
anim.setRepeatMode(Animation.REVERSE);
anim.setFillAfter(true);
}
@Override
public void onAnimationRepeat(Animation animation) {
textMovin.setY(r.nextInt(height));
textMovin.setX(r.nextInt(width));
anim.start();
}
});
textMovin.startAnimation(anim);
}
}
Upvotes: 0
Views: 502
Reputation: 1176
try this code:
public class MainActivity extends AppCompatActivity {
private View parent;
private TextView textMovin;
private float speedX;
private float speedY;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textMovin = findViewById(R.id.textV);
parent = findViewById(R.id.parent);
final Random r = new Random();
speedX = r.nextFloat() * 200;
speedY = r.nextFloat() * 200;
parent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
final int width = parent.getWidth() - textMovin.getWidth();
final int height = parent.getHeight() - textMovin.getHeight();
final int period = 50;
new Timer().scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
textMovin.post(new TimerTask() {
@Override
public void run() {
textMovin.setX(speedX * period / 1000.0f + textMovin.getX());
textMovin.setY(speedY * period / 1000.0f + textMovin.getY());
if (textMovin.getY() <= 0 || textMovin.getY() >= height)
speedY *= -1;
if (textMovin.getX() <= 0 || textMovin.getX() >= width)
speedX *= -1;
}
});
}
}, 50, period);
}
});
findViewById(R.id.random).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final Random r = new Random();
speedX = r.nextFloat() * 200;
speedY = r.nextFloat() * 200;
}
});
}
}
and the layout:
<?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/parent"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/textV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="Hello World!" />
<Button
android:id="@+id/random"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="10dp"
android:text="Random" />
</RelativeLayout>
Upvotes: 1
Reputation: 1049
Hope it works for you.
public class OnDragTouchListener implements View.OnTouchListener {
/**
* Callback used to indicate when the drag is finished
*/
public interface OnDragActionListener {
/**
* Called when drag event is started
*
* @param view The view dragged
*/
void onDragStart(View view);
/**
* Called when drag event is completed
*
* @param view The view dragged
*/
void onDragEnd(View view);
}
private View mView;
private View mParent;
private boolean isDragging;
private boolean isInitialized = false;
private int width;
private float xWhenAttached;
private float maxLeft;
private float maxRight;
private float dX;
private int height;
private float yWhenAttached;
private float maxTop;
private float maxBottom;
private float dY;
private OnDragActionListener mOnDragActionListener;
public OnDragTouchListener(View view) {
this(view, (View) view.getParent(), null);
}
public OnDragTouchListener(View view, View parent) {
this(view, parent, null);
}
public OnDragTouchListener(View view, OnDragActionListener onDragActionListener) {
this(view, (View) view.getParent(), onDragActionListener);
}
public OnDragTouchListener(View view, View parent, OnDragActionListener onDragActionListener) {
initListener(view, parent);
setOnDragActionListener(onDragActionListener);
}
public void setOnDragActionListener(OnDragActionListener onDragActionListener) {
mOnDragActionListener = onDragActionListener;
}
public void initListener(View view, View parent) {
mView = view;
mParent = parent;
isDragging = false;
isInitialized = false;
}
public void updateBounds() {
updateViewBounds();
updateParentBounds();
isInitialized = true;
}
public void updateViewBounds() {
width = mView.getWidth();
xWhenAttached = mView.getX();
dX = 0;
height = mView.getHeight();
yWhenAttached = mView.getY();
dY = 0;
}
public void updateParentBounds() {
maxLeft = 0;
maxRight = maxLeft + mParent.getWidth();
maxTop = 0;
maxBottom = maxTop + mParent.getHeight();
}
@Override
public boolean onTouch(View v, MotionEvent event) {
if (isDragging) {
float[] bounds = new float[4];
// LEFT
bounds[0] = event.getRawX() + dX;
if (bounds[0] < maxLeft) {
bounds[0] = maxLeft;
}
// RIGHT
bounds[2] = bounds[0] + width;
if (bounds[2] > maxRight) {
bounds[2] = maxRight;
bounds[0] = bounds[2] - width;
}
// TOP
bounds[1] = event.getRawY() + dY;
if (bounds[1] < maxTop) {
bounds[1] = maxTop;
}
// BOTTOM
bounds[3] = bounds[1] + height;
if (bounds[3] > maxBottom) {
bounds[3] = maxBottom;
bounds[1] = bounds[3] - height;
}
switch (event.getAction()) {
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
onDragFinish();
break;
case MotionEvent.ACTION_MOVE:
mView.animate().x(bounds[0]).y(bounds[1]).setDuration(0).start();
break;
}
return true;
} else {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
isDragging = true;
if (!isInitialized) {
updateBounds();
}
dX = v.getX() - event.getRawX();
dY = v.getY() - event.getRawY();
if (mOnDragActionListener != null) {
mOnDragActionListener.onDragStart(mView);
}
return true;
}
}
return false;
}
private void onDragFinish() {
if (mOnDragActionListener != null) {
mOnDragActionListener.onDragEnd(mView);
}
dX = 0;
dY = 0;
isDragging = false;
}
}
And you can set it using:
myView.setOnTouchListener(new OnDragTouchListener(myView));
Or by adding this directly in init method of your Custom View:
setOnTouchListener(new OnDragTouchListener(this));
Upvotes: 0