图像视图不动
Imageview not moving
我试图让 Imageview(一个球)在布局中移动并弹跳多次,然后在按下按钮时停止。问题是虽然 logcat 说它正在发生,但我看不到它在移动。
在这里
public class BallPhisics {
int x =400;
int y = 0;
boolean bounceX = false;
boolean bounceY= false;
int counter =0;
ImageView object;
public BallPhisics(ImageView i){
object=i;
}
public void applyMovement() {
while (true) {
object.setLeft((int) object.getX()+x); //i know i shouldnt use pixels
Log.d("EVENT", "X moved"); Log.d("Ended",Integer.toString(object.getLeft()));
object.setBottom((int)(object.getY() + y));
Log.d("EVENT", "Y moved");
try {
Thread.sleep(1000);
Log.d("EVENT", "Time 1 used");
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
if (object.getX()<=50||(object.getRight()<=50)){
bounceX =true;
break;
}
if (object.getY()<=50||object.getTop()<=50){
bounceY=true;
break;
}
}
this.bouncing();
}
public void bouncing(){
Log.d("EVENT", "Bouncing!!");
if (bounceX&&bounceY){
x=-x;
y=-y;
}
else if (bounceX){
x=-x;
y=(int)(Math.random()*100- 50 +y);
}
else if (bounceY) {
x = (int) (Math.random() * 100 - 50 + x);
y = -y;
}
counter++;
if(counter==5){return;}
this.applyMovement();
}
并且在 mainActivity 上的 onclick 事件。
public void StartBall (View view){
ImageView imageview=(ImageView) findViewById(R.id.imageView);
BallPhisics phisics = new BallPhisics(imageview);
Log.d("EVENT", Integer.toString(imageview.getLeft() )+" before");
phisics.applyMovement();
Log.d("EVENT",Integer.toString(imageview.getLeft())+" after" );
}
抱歉,如果阅读量很大。顺便问一下,有人知道移动视图的正确方法吗?
提前致谢
首先要移动视图,使用 setLeft (int left)
或 setBottom (int bottom)
可能不是一个好主意,因为此方法旨在由布局系统调用,否则通常不应调用, according to the documentation.
要动态移动视图,您应该查看 LayoutParams
或 setX (float x)
和 setY (float Y)
,如果您可以限制对 Honeycomb 的支持(API 级别 11 ).
无论使用哪一种,您都可能会发现很难实现流畅的移动。因此,我建议您使用视图动画系统来执行 ImageView 的补间动画。
下面是一个链式动画示例,它使用任意 y 坐标从左向右移动 ImageView。每次从一个 x 边界转换到下一个 x 边界后,onAnimationEnd
将被调用并开始另一个方向的动画。
public class MainActivity extends Activity {
//the ImageView you want to animate
private ImageView imageview;
private Animation mAnimation;
//The coordinates the view moved to in the last animation
private float lastX=0;
private float lastY=0;
private float secondlastY;
//Listener that implements a translate animation chain
AnimationListener animationListener=new AnimationListener() {
@Override
public void onAnimationEnd(Animation animation) {
float newY=(float)(Math.random()*0.75);
//this prevents that we move back to the position we came from
// to get a more natural bounce animation
while(newY<=secondlastY+0.15 && newY>=secondlastY-0.15){
newY=(float)(Math.random()*0.75);
}
if(lastX==0.75f){
//test if we are on the right border of the parent
mAnimation=newAnimation(lastX,lastY,0f,newY);
mAnimation.setAnimationListener(animationListener);
lastX=0f;
}else if(lastX==0.0f){
//test if we are on the left border of the parent
mAnimation=newAnimation(lastX,lastY,0.75f,newY);
mAnimation.setAnimationListener(animationListener);
lastX=0.75f;
}
secondlastY=lastY;
lastY=newY;
imageview.startAnimation(mAnimation);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageview=(ImageView) findViewById(R.id.imageView);
//the coordinates the first animation should move to
lastY=(float)(Math.random()*0.75);
lastX=0.75f;
mAnimation=newAnimation(0f,0f,lastX,lastY);
mAnimation.setAnimationListener(animationListener);
imageview.startAnimation(mAnimation);
}
//Method that returns a new animation with given start and end coordinates
private Animation newAnimation(float startX, float startY, float endX, float endY){
Animation mAnimation = new TranslateAnimation(
TranslateAnimation.RELATIVE_TO_PARENT, startX,
TranslateAnimation.RELATIVE_TO_PARENT, endX,
TranslateAnimation.RELATIVE_TO_PARENT, startY,
TranslateAnimation.RELATIVE_TO_PARENT, endY );
mAnimation.setDuration(2500);
mAnimation.setRepeatCount(0);
mAnimation.setRepeatMode(Animation.REVERSE);
mAnimation.setFillAfter(true);
return mAnimation;
}
}
注:
平移动画是相对于父类的宽高的。如果将视图一直移动到 x=1.0 或 y=1.0,您会将部分视图移出父布局。因为对于这个例子来说已经足够了,所以我选择将 0.75 设置为任一方向的最大位置。但是您可能应该根据 ImageView 和 ParentLayout 的宽度和高度动态设置它。
我试图让 Imageview(一个球)在布局中移动并弹跳多次,然后在按下按钮时停止。问题是虽然 logcat 说它正在发生,但我看不到它在移动。
在这里
public class BallPhisics {
int x =400;
int y = 0;
boolean bounceX = false;
boolean bounceY= false;
int counter =0;
ImageView object;
public BallPhisics(ImageView i){
object=i;
}
public void applyMovement() {
while (true) {
object.setLeft((int) object.getX()+x); //i know i shouldnt use pixels
Log.d("EVENT", "X moved"); Log.d("Ended",Integer.toString(object.getLeft()));
object.setBottom((int)(object.getY() + y));
Log.d("EVENT", "Y moved");
try {
Thread.sleep(1000);
Log.d("EVENT", "Time 1 used");
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
if (object.getX()<=50||(object.getRight()<=50)){
bounceX =true;
break;
}
if (object.getY()<=50||object.getTop()<=50){
bounceY=true;
break;
}
}
this.bouncing();
}
public void bouncing(){
Log.d("EVENT", "Bouncing!!");
if (bounceX&&bounceY){
x=-x;
y=-y;
}
else if (bounceX){
x=-x;
y=(int)(Math.random()*100- 50 +y);
}
else if (bounceY) {
x = (int) (Math.random() * 100 - 50 + x);
y = -y;
}
counter++;
if(counter==5){return;}
this.applyMovement();
}
并且在 mainActivity 上的 onclick 事件。
public void StartBall (View view){
ImageView imageview=(ImageView) findViewById(R.id.imageView);
BallPhisics phisics = new BallPhisics(imageview);
Log.d("EVENT", Integer.toString(imageview.getLeft() )+" before");
phisics.applyMovement();
Log.d("EVENT",Integer.toString(imageview.getLeft())+" after" );
}
抱歉,如果阅读量很大。顺便问一下,有人知道移动视图的正确方法吗?
提前致谢
首先要移动视图,使用 setLeft (int left)
或 setBottom (int bottom)
可能不是一个好主意,因为此方法旨在由布局系统调用,否则通常不应调用, according to the documentation.
要动态移动视图,您应该查看 LayoutParams
或 setX (float x)
和 setY (float Y)
,如果您可以限制对 Honeycomb 的支持(API 级别 11 ).
无论使用哪一种,您都可能会发现很难实现流畅的移动。因此,我建议您使用视图动画系统来执行 ImageView 的补间动画。
下面是一个链式动画示例,它使用任意 y 坐标从左向右移动 ImageView。每次从一个 x 边界转换到下一个 x 边界后,onAnimationEnd
将被调用并开始另一个方向的动画。
public class MainActivity extends Activity {
//the ImageView you want to animate
private ImageView imageview;
private Animation mAnimation;
//The coordinates the view moved to in the last animation
private float lastX=0;
private float lastY=0;
private float secondlastY;
//Listener that implements a translate animation chain
AnimationListener animationListener=new AnimationListener() {
@Override
public void onAnimationEnd(Animation animation) {
float newY=(float)(Math.random()*0.75);
//this prevents that we move back to the position we came from
// to get a more natural bounce animation
while(newY<=secondlastY+0.15 && newY>=secondlastY-0.15){
newY=(float)(Math.random()*0.75);
}
if(lastX==0.75f){
//test if we are on the right border of the parent
mAnimation=newAnimation(lastX,lastY,0f,newY);
mAnimation.setAnimationListener(animationListener);
lastX=0f;
}else if(lastX==0.0f){
//test if we are on the left border of the parent
mAnimation=newAnimation(lastX,lastY,0.75f,newY);
mAnimation.setAnimationListener(animationListener);
lastX=0.75f;
}
secondlastY=lastY;
lastY=newY;
imageview.startAnimation(mAnimation);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageview=(ImageView) findViewById(R.id.imageView);
//the coordinates the first animation should move to
lastY=(float)(Math.random()*0.75);
lastX=0.75f;
mAnimation=newAnimation(0f,0f,lastX,lastY);
mAnimation.setAnimationListener(animationListener);
imageview.startAnimation(mAnimation);
}
//Method that returns a new animation with given start and end coordinates
private Animation newAnimation(float startX, float startY, float endX, float endY){
Animation mAnimation = new TranslateAnimation(
TranslateAnimation.RELATIVE_TO_PARENT, startX,
TranslateAnimation.RELATIVE_TO_PARENT, endX,
TranslateAnimation.RELATIVE_TO_PARENT, startY,
TranslateAnimation.RELATIVE_TO_PARENT, endY );
mAnimation.setDuration(2500);
mAnimation.setRepeatCount(0);
mAnimation.setRepeatMode(Animation.REVERSE);
mAnimation.setFillAfter(true);
return mAnimation;
}
}
注: 平移动画是相对于父类的宽高的。如果将视图一直移动到 x=1.0 或 y=1.0,您会将部分视图移出父布局。因为对于这个例子来说已经足够了,所以我选择将 0.75 设置为任一方向的最大位置。但是您可能应该根据 ImageView 和 ParentLayout 的宽度和高度动态设置它。