我在RelativeLayout里面有一个骰子的图像。我想要的是让它在布局内反弹。我尝试的是当imageView越过底部或顶部然后改变它当前的动画方向并播放它们。对于x运动,我做了同样的事情。但是当我一起玩的时候,事情并没有按照我的意愿行事。以下是我的代码:
package com.example.aaa111.androidrnd;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.graphics.Rect;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;
import android.widget.RelativeLayout;
public class AnimationTest extends AppCompatActivity {
private ObjectAnimator diceOneAnim;
private ObjectAnimator diceTwoAnim;
private ObjectAnimator diceOneTrAnim;
private ImageView diceOneImage;
private ImageView diceTwoImage;
private RelativeLayout relativeLayout;
private boolean animSet;
private Rect r1;
private Rect r2;
private int currX = 0;
private int currY = 0;
private int toX = 2500;
private int toY = 2000;
private boolean newAnim = false;
private Rect rootRect;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_animation_test);
animSet = false;
relativeLayout = (RelativeLayout)findViewById(R.id.relativeLayout);
diceOneImage = (ImageView)findViewById(R.id.diceOneImage);
diceTwoImage = (ImageView)findViewById(R.id.diceTwoImage);
relativeLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout()
{
relativeLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
});
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
int[] l = new int[2];
relativeLayout.getLocationOnScreen(l);
rootRect = new Rect(l[0], l[1], l[0] + relativeLayout.getWidth(), l[1] + relativeLayout.getHeight());
System.out.println("relativeLayout width : " + relativeLayout.getWidth());
System.out.println("relativeLayout height : " + relativeLayout.getHeight());
makeNewAnim();
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.menu_animation_test, menu);
return true;
}
private void makeNewAnim()
{
final AnimatorSet animSetXY = new AnimatorSet();
ValueAnimator y = ObjectAnimator.ofFloat(diceOneImage,"translationY",currY, toY);
ValueAnimator x = ObjectAnimator.ofFloat(diceOneImage, "translationX", currX, toX);
ValueAnimator rotate = ObjectAnimator.ofFloat(diceOneImage,"rotation",0, 360);
rotate.setInterpolator(new LinearInterpolator());
rotate.setRepeatCount(Animation.INFINITE);
rotate.setDuration(2000);
x.addUpdateListener(new ValueAnimator.AnimatorUpdateListener()
{
@Override
public void onAnimationUpdate(ValueAnimator animation)
{
final int[] l = new int[2];
l[0] = (int) diceOneImage.getX();
l[1] = (int) diceOneImage.getY();
System.out.println("l[0] : " + l[0]);
System.out.println("l[1] : " + l[1]);
Rect rect = new Rect(l[0], l[1], l[0] + diceOneImage.getWidth(), l[1] + diceOneImage.getHeight());
float rx = relativeLayout.getX();
float rw = relativeLayout.getWidth();
if (rect.right > relativeLayout.getX() + relativeLayout.getWidth()) {
final float offset = l[0] - diceOneImage.getWidth() - (rect.right - (relativeLayout.getX() + relativeLayout.getWidth()));
animSetXY.cancel();
ObjectAnimator animator = ObjectAnimator.ofFloat(diceOneImage, "translationX", l[0], l[0] - diceOneImage.getWidth() - (rect.right - (relativeLayout.getX() + relativeLayout.getWidth())));
animator.setDuration(5);
animator.start();
animator.addListener(new Animator.AnimatorListener()
{
@Override
public void onAnimationStart(Animator animation)
{
}
@Override
public void onAnimationEnd(Animator animation)
{
currY = l[1];
currX = (int) offset;
toX = toX * (-1);
makeNewAnim();
}
@Override
public void onAnimationCancel(Animator animation)
{
}
@Override
public void onAnimationRepeat(Animator animation)
{
}
});
return;
}
if (rect.left < relativeLayout.getLeft())
{
animSetXY.cancel();
ObjectAnimator animator = ObjectAnimator.ofFloat(diceOneImage, "translationX", l[0], l[0] + 20);
animator.setDuration(5);
animator.start();
animator.addListener(new Animator.AnimatorListener()
{
@Override
public void onAnimationStart(Animator animation)
{
}
@Override
public void onAnimationEnd(Animator animation)
{
currY = l[1];
currX = l[0] + 20;
toX = toX * (-1);
makeNewAnim();
}
@Override
public void onAnimationCancel(Animator animation)
{
}
@Override
public void onAnimationRepeat(Animator animation)
{
}
});
return;
}
}
});
y.addUpdateListener(new ValueAnimator.AnimatorUpdateListener()
{
@Override
public void onAnimationUpdate(ValueAnimator animation)
{
final int[] l = new int[2];
l[0] = (int) diceOneImage.getX();
l[1] = (int) diceOneImage.getY();//getRelativeTop(diceOneImage);
System.out.println("l[0] : " + l[0]);
System.out.println("l[1] : " + l[1]);
Rect rect = new Rect(l[0], l[1], l[0] + diceOneImage.getWidth(), l[1] + diceOneImage.getHeight());
if (rect.bottom > relativeLayout.getY() + relativeLayout.getHeight())
{
animSetXY.cancel();
ObjectAnimator animator = ObjectAnimator.ofFloat(diceOneImage, "translationY", l[1], l[1] - 20);
animator.setDuration(2);
animator.start();
animator.addListener(new Animator.AnimatorListener()
{
@Override
public void onAnimationStart(Animator animation)
{
}
@Override
public void onAnimationEnd(Animator animation)
{
currY = l[1] - 20;
toY = -1 * toY;
//currX = (int) diceOneImage.getX();
//toX = toX * (-1);
makeNewAnim();
}
@Override
public void onAnimationCancel(Animator animation)
{
}
@Override
public void onAnimationRepeat(Animator animation)
{
}
});
return;
}
if (rect.top < relativeLayout.getTop())
{
animSetXY.cancel();
ObjectAnimator animator = ObjectAnimator.ofFloat(diceOneImage, "translationY", l[1], l[1] + 20);
animator.setDuration(2);
animator.start();
animator.addListener(new Animator.AnimatorListener()
{
@Override
public void onAnimationStart(Animator animation)
{
}
@Override
public void onAnimationEnd(Animator animation)
{
currY = l[1] + 20;
toY = -1 * toY;
//currX = (int) diceOneImage.getX();
//toX = toX * (-1);
makeNewAnim();
}
@Override
public void onAnimationCancel(Animator animation)
{
}
@Override
public void onAnimationRepeat(Animator animation)
{
}
});
return;
}
}
});
animSetXY.playTogether(rotate, x,y);
animSetXY.setInterpolator(new LinearInterpolator());
animSetXY.setDuration(2000);
animSetXY.start();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
我已经研究过surfaceview选项以实现这种效果,并且我正在努力实现这一目标。但问题是我必须在弹跳结束一段时间之后播放视频广告(很像全向滑动)并且我的表面视图在广告结束后被绞死。在logcat里面我得到并发异常。所以我选择使用此选项。顺便说一句,我正在使用HeyZap SDK进行视频广告。