为了训练自己,我创造了一些2048游戏的克隆。该程序运行良好,但今天我想添加移动单元格的动画。这是我的布局(不要发誓,如果我的代码看起来像转储,我试图尽可能好,但我还有很多东西需要学习):
<ru.igaleksus.Game2048.FieldView
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:id="@+id/background"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="60dp"
android:focusable="true">
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="25">
<ru.igaleksus.Game2048.CellView
android:id="@+id/cell0"
android:textColor="@color/fontcolor"
android:layout_weight="25"
android:layout_height="wrap_content"
android:text=""
android:layout_margin="10dp"/>
<ru.igaleksus.Game2048.CellView
android:id="@+id/cell1"
android:textColor="@color/fontcolor"
android:layout_weight="25"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text=""/>
<ru.igaleksus.Game2048.CellView
android:id="@+id/cell2"
android:textColor="@color/fontcolor"
android:layout_weight="25"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text=""/>
<ru.igaleksus.Game2048.CellView
android:id="@+id/cell3"
android:textColor="@color/fontcolor"
android:layout_weight="25"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text=""/>
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="25">
<ru.igaleksus.Game2048.CellView
android:id="@+id/cell4"
android:textColor="@color/fontcolor"
android:layout_weight="25"
android:layout_height="wrap_content"
android:text="2"
android:layout_margin="10dp"/>
<ru.igaleksus.Game2048.CellView
android:id="@+id/cell5"
android:textColor="@color/fontcolor"
android:layout_weight="25"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text=""/>
<ru.igaleksus.Game2048.CellView
android:id="@+id/cell6"
android:textColor="@color/fontcolor"
android:layout_weight="25"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text=""/>
<ru.igaleksus.Game2048.CellView
android:id="@+id/cell7"
android:textColor="@color/fontcolor"
android:layout_weight="25"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text=""/>
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="25">
<ru.igaleksus.Game2048.CellView
android:id="@+id/cell8"
android:textColor="@color/fontcolor"
android:layout_weight="25"
android:layout_height="wrap_content"
android:text=""
android:layout_margin="10dp"/>
<ru.igaleksus.Game2048.CellView
android:id="@+id/cell9"
android:textColor="@color/fontcolor"
android:layout_weight="25"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text=""/>
<ru.igaleksus.Game2048.CellView
android:id="@+id/cell10"
android:textColor="@color/fontcolor"
android:layout_weight="25"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text=""/>
<ru.igaleksus.Game2048.CellView
android:id="@+id/cell11"
android:textColor="@color/fontcolor"
android:layout_weight="25"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text=""/>
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="25">
<ru.igaleksus.Game2048.CellView
android:id="@+id/cell12"
android:textColor="@color/fontcolor"
android:layout_weight="25"
android:layout_height="wrap_content"
android:text=""
android:layout_margin="10dp"/>
<ru.igaleksus.Game2048.CellView
android:id="@+id/cell13"
android:textColor="@color/fontcolor"
android:layout_weight="25"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text=""/>
<ru.igaleksus.Game2048.CellView
android:id="@+id/cell14"
android:textColor="@color/fontcolor"
android:layout_weight="25"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text=""/>
<ru.igaleksus.Game2048.CellView
android:id="@+id/cell15"
android:textColor="@color/fontcolor"
android:layout_weight="25"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text=""/>
</TableRow>
<RelativeLayout android:layout_height="match_parent"
android:layout_width="wrap_content"
android:layout_marginTop="25dp">
<TextView
android:id="@+id/score"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/score_text_size_for_large_screen"
android:textColor="@color/fontcolor"
android:text="Score: 0"
android:layout_marginLeft="10dp"
android:layout_alignParentLeft="true"
/>
<Button
android:id="@+id/startAgain"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/fontcolor"
android:layout_marginLeft="300dp"
android:text="@string/play_again_button"
android:background="@color/button_color"
/>
</RelativeLayout>
</ru.igaleksus.Game2048.FieldView>
CellView和FieldView是我的自定义视图。第一个 - 扩展TextView,它的特点是,每次获得新标签时,它都会重新绘制新颜色。第二个 - 扩展TableLayout并且几乎无法区分它。问题是我正在尝试为单元格从一个位置移动到另一个位置创建一个动画。为此,我通过getLocationInWindow方法计算每个单元格的位置:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
init();
if (savedInstanceState == null) startNewGame();
else {
gameStateKeeper = savedInstanceState.getStringArray(CURRENT_GAME_STATE_KEY_FOR_SAVING_STATE);
scoreTextView.setText(savedInstanceState.getString(CURRENT_SCORE_STATE_KEY_FOR_SAVING_STATE));
scoreTextView.invalidate();
restorePreviousGame();
myField.invalidate();
}
myField.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
myField.getViewTreeObserver().removeOnGlobalLayoutListener(this);
} else {
myField.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
for (int i = 0; i < myCells.length; i++){
myCells[i].positionOnScreen = new int[2];
myCells[i].getLocationInWindow(myCells[i].positionOnScreen);
}
animate(myCells[4], myCells[0], OFFSET_DIRECTION_VERTICAL_UP);
}
});
}
然后,在创建动画的方法中检索每个单元格的结果。然后我将这些坐标用作构造函数TranslateAnimation中的参数。
protected void animate(CellView from, CellView to, int direction){
CellView tempCellForAnimation = new CellView(myField.getContext());
tempCellForAnimation.setText(from.getText());
to.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
from.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
float animXStartPoint = 0;
float animXEndPoint = 0;
float animYStartPoint = 0;
float animYEndPoint = 0;
switch (direction){
case OFFSET_DIRECTION_VERTICAL_UP:
Log.d("MYSUPERTAG2", Integer.toString(from.getPositionOnScreen()[1]));
animYEndPoint = to.getPositionOnScreen()[1];
animYStartPoint = from.getPositionOnScreen()[1];
break;
case OFFSET_DIRECTION_VERTICAL_DOWN:
break;
case OFFSET_DIRECTION_HORIZONTAL_LEFT:
break;
case OFFSET_DIRECTION_HORIZONTAL_RIGHT:
break;
}
TranslateAnimation ta = new TranslateAnimation(Animation.ABSOLUTE, -10,
Animation.ABSOLUTE, -10,
Animation.ABSOLUTE, animYStartPoint,
Animation.ABSOLUTE, animYEndPoint);
ta.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
ta.setDuration(1000);
myField.addView(tempCellForAnimation);
tempCellForAnimation.startAnimation(ta);
}
结果并不像我预期的那样。单元格不在getLocationInWindow中获得的坐标之间移动。他们移动,但不是在这两个单元格的实际位置之间,我在参数中委托给这个方法。我做错了什么?
另外,我想知道,也许有一些方法可以在Activiti中添加一个可见对象,但是不能将它添加到Layout的根元素中,只是让它执行一个特定的动画然后消失?或者,最好使用其他一些动画方法。感谢。