Ошибка в анимации свойства
Я создаю небольшое приложение для практики в программировании на Android. Это своего рода игра-головоломка, подобная этой:
У меня следующая проблема: когда я перемещаю кнопку влево или вправо в свойстве x, все в порядке. Я могу часто перемещать каждую кнопку влево и вправо. Проблема начинается, когда я перемещаю кнопку вниз или вверх в свойстве y. Я могу только переместить кнопку один раз, и затем она больше не будет доступна для onTouchListener. Он становится неподвижным в любом направлении, и никакие действия не выполняются. Вот мой файл активности Java и макет XML.
MainActivity.java
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
class MyPoint{
private boolean canMove;
private View associatedView;
private int x;
private int y;
private MyPoint nord;
private MyPoint south;
private MyPoint est;
private MyPoint west;
MyPoint(int x, int y, View associatedView){
this.x = x;
this.y = y;
this.associatedView = associatedView;
canMove = false;
}
public MyPoint getEst() {
return est;
}
public MyPoint getNord() {
return nord;
}
public MyPoint getSouth() {
return south;
}
public MyPoint getWest() {
return west;
}
public void setNeighbors(MyPoint nord, MyPoint south, MyPoint west, MyPoint est){
this.nord = nord;
this.south = south;
this.est = est;
this.west = west;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public View getAssociatedView() {
return associatedView;
}
public void setAssociatedView(View associatedView) {
this.associatedView = associatedView;
}
public boolean isSpace(){
if(associatedView.getId() == R.id.space)
return true;
else
return false;
}
public void allowMovement(){
canMove = true;
}
public void denyMovement(){
canMove = false;
}
public void allowMovementNeighbords(){
nord.allowMovement();
south.allowMovement();
est.allowMovement();
west.allowMovement();
}
public boolean isMoveable(){
if(canMove) return true;
else return false;
}
}
public class MainActivity extends ActionBarActivity {
LinearLayout mainScreen;
MyPoint[] board = new MyPoint[16];
View[] views = new View[16];
View blank;
MyPoint blankPoint, associatedPoint;
int DX,DY;
private MyPoint findPointByView(View target){
MyPoint tempResult = blankPoint;
for(int i=0; i<16; i++)
if(board[i].getAssociatedView().getId() == target.getId())
tempResult = board[i];
return tempResult;
}
private MyPoint findSpace(){
MyPoint tempResult = blankPoint;
for(int i=0; i<16; i++)
if(board[i].isSpace()){
tempResult = board[i];
}
return tempResult;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mainScreen = (LinearLayout) findViewById(R.id.main_screen);
blank = findViewById(R.id.blank);
blankPoint = new MyPoint(0,0,blank);
blankPoint.setNeighbors(blankPoint,blankPoint,blankPoint,blankPoint);
associatedPoint = blankPoint;
final View.OnTouchListener mTouchListener = new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event){
float x1=0, x2, y1=0, y2, dx, dy;
switch(event.getActionMasked()) {
case(MotionEvent.ACTION_DOWN):
associatedPoint = findPointByView(v);
x1 = event.getX();
y1 = event.getY();
break;
case(MotionEvent.ACTION_UP): {
x2 = event.getX();
y2 = event.getY();
dx = x2-x1;
dy = y2-y1;
if(associatedPoint.isMoveable()){
if(Math.abs(dx) > Math.abs(dy)) {
if(dx>0){
if(associatedPoint.getEst().isSpace()){
v.animate().xBy(DX);
associatedPoint.setAssociatedView(findViewById(R.id.space));
associatedPoint.getEst().setAssociatedView(v);
}
}
else{
if(associatedPoint.getWest().isSpace()){
v.animate().xBy(-DX);
associatedPoint.setAssociatedView(findViewById(R.id.space));
associatedPoint.getWest().setAssociatedView(v);
}
}
} else {
if(dy>0){
if(associatedPoint.getSouth().isSpace()){
v.animate().yBy(DY);
associatedPoint.setAssociatedView(findViewById(R.id.space));
associatedPoint.getSouth().setAssociatedView(v);
}
}
else{
if(associatedPoint.getNord().isSpace()){
v.animate().yBy(-DY);
associatedPoint.setAssociatedView(findViewById(R.id.space));
associatedPoint.getNord().setAssociatedView(v);
}
}
}
denyMovementAll();
findSpace().allowMovementNeighbords();
}
return true;
}
}
return false;
}
};
views[0] = findViewById(R.id.button1);
views[1] = findViewById(R.id.button2);
views[2] = findViewById(R.id.button3);
views[3] = findViewById(R.id.button4);
views[4] = findViewById(R.id.button5);
views[5] = findViewById(R.id.button6);
views[6] = findViewById(R.id.button7);
views[7] = findViewById(R.id.button8);
views[8] = findViewById(R.id.button9);
views[9] = findViewById(R.id.button10);
views[10] = findViewById(R.id.button11);
views[11] = findViewById(R.id.button12);
views[12] = findViewById(R.id.button13);
views[13] = findViewById(R.id.button14);
views[14] = findViewById(R.id.button15);
views[15] = findViewById(R.id.space);
for(int i=0; i<15; i++)
views[i].setOnTouchListener(mTouchListener);
}
private void denyMovementAll() {
for(int i=0; i<16; i++)
board[i].denyMovement();
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int offsetY = displayMetrics.heightPixels - mainScreen.getMeasuredHeight();
for (int i=0 ; i<16; i++){
int[] tempCoords = new int[2];
views[i].getLocationOnScreen(tempCoords);
int x = tempCoords[0];
int y = tempCoords[1] - offsetY;
board[i] = new MyPoint(x,y,views[i]);
}
board[0].setNeighbors(blankPoint,board[4],blankPoint,board[1]);
board[1].setNeighbors(blankPoint,board[5],board[0],board[2]);
board[2].setNeighbors(blankPoint,board[6],board[1],board[3]);
board[3].setNeighbors(blankPoint,board[7],board[2],blankPoint);
board[4].setNeighbors(board[0],board[8],blankPoint,board[5]);
board[5].setNeighbors(board[1],board[9],board[4],board[6]);
board[6].setNeighbors(board[2],board[10],board[5],board[7]);
board[7].setNeighbors(board[3],board[11],board[6],blankPoint);
board[8].setNeighbors(board[4],board[12],blankPoint,board[9]);
board[9].setNeighbors(board[5],board[13],board[8],board[10]);
board[10].setNeighbors(board[6],board[14],board[9],board[11]);
board[11].setNeighbors(board[7],board[15],board[10],blankPoint);
board[12].setNeighbors(board[8],blankPoint,blankPoint,board[13]);
board[13].setNeighbors(board[9],blankPoint,board[12],board[14]);
board[14].setNeighbors(board[10],blankPoint,board[13],board[15]);
board[15].setNeighbors(board[11],blankPoint,board[14],blankPoint);
DX = board[1].getX() - board[0].getX();
DY = board[4].getY() - board[0].getY();
denyMovementAll();
findSpace().allowMovementNeighbords();
}
}
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"
android:collapseColumns="4"
android:orientation="vertical"
android:clipChildren="false"
android:id="@+id/main_screen"
android:clipToPadding="false">
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:clipChildren="false"
android:clipToPadding="false"
android:id="@+id/row1">
<Button
android:layout_width="0dp"
android:layout_height="match_parent"
android:text="@string/b1"
android:id="@+id/button1"
android:layout_weight="1" />
<Button
android:layout_width="0dp"
android:layout_height="match_parent"
android:text="@string/b2"
android:id="@+id/button2"
android:layout_weight="1" />
<Button
android:layout_width="0dp"
android:layout_height="match_parent"
android:text="@string/b3"
android:id="@+id/button3"
android:layout_weight="1" />
<Button
android:layout_width="0dp"
android:layout_height="match_parent"
android:text="@string/b4"
android:id="@+id/button4"
android:layout_weight="1" />
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:clipChildren="false"
android:clipToPadding="false"
android:id="@+id/row2">
<Button
android:layout_width="0dp"
android:layout_height="match_parent"
android:text="@string/b5"
android:id="@+id/button5"
android:layout_weight="1" />
<Button
android:layout_width="0dp"
android:layout_height="match_parent"
android:text="@string/b6"
android:id="@+id/button6"
android:layout_weight="1" />
<Button
android:layout_width="0dp"
android:layout_height="match_parent"
android:text="@string/b7"
android:id="@+id/button7"
android:layout_weight="1" />
<Button
android:layout_width="0dp"
android:layout_height="match_parent"
android:text="@string/b8"
android:id="@+id/button8"
android:layout_weight="1" />
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:clipChildren="false"
android:clipToPadding="false"
android:id="@+id/row3">
<Button
android:layout_width="0dp"
android:layout_height="match_parent"
android:text="@string/b9"
android:id="@+id/button9"
android:layout_weight="1" />
<Button
android:layout_width="0dp"
android:layout_height="match_parent"
android:text="@string/b10"
android:id="@+id/button10"
android:layout_weight="1" />
<Button
android:layout_width="0dp"
android:layout_height="match_parent"
android:text="@string/b11"
android:id="@+id/button11"
android:layout_weight="1" />
<Button
android:layout_width="0dp"
android:layout_height="match_parent"
android:text="@string/b12"
android:id="@+id/button12"
android:layout_weight="1" />
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:clipChildren="false"
android:clipToPadding="false"
android:id="@+id/row4">
<Button
android:layout_width="0dp"
android:layout_height="match_parent"
android:text="@string/b13"
android:id="@+id/button13"
android:layout_weight="1" />
<Button
android:layout_width="0dp"
android:layout_height="match_parent"
android:text="@string/b14"
android:id="@+id/button14"
android:layout_weight="1" />
<Button
android:layout_width="0dp"
android:layout_height="match_parent"
android:text="@string/b15"
android:id="@+id/button15"
android:layout_weight="1" />
<Space
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:id="@+id/space"
android:visibility="invisible"/>
<Space
android:layout_width="0dp"
android:layout_height="0dp"
android:visibility="invisible"
android:id="@+id/blank"/>
</LinearLayout>
</LinearLayout>
Я действительно понятия не имею, что является причиной этой проблемы. Пожалуйста, дайте мне небольшую подсказку о том, что может вызвать эту проблему. заранее спасибо
2 ответа
Вы должны вернуть true, если слушатель использовал событие. В противном случае он должен вернуть false по умолчанию.
View.OnTouchListener mTouchListener = new View.OnTouchListener() {
...
return false;
}
Я изменил свой код, следуя вашему совету:
View.OnTouchListener mTouchListener = new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event){
float x1=0, x2, y1=0, y2, dx, dy;
switch(event.getActionMasked()) {
case(MotionEvent.ACTION_DOWN):
x1 = event.getX();
y1 = event.getY();
break;
case(MotionEvent.ACTION_UP): {
x2 = event.getX();
y2 = event.getY();
dx = x2-x1;
dy = y2-y1;
if(Math.abs(dx) > Math.abs(dy)) {
if(dx>0){
v.animate().xBy(DX);
}
else{
v.animate().xBy(-DX);
}
} else {
if(dy>0){
v.animate().yBy(DY);
}
else{
v.animate().yBy(-DY);
}
}
return true;
}
}
return false;
}
};
К сожалению, это не решает мою проблему. Пожалуйста, поправьте меня, если я ошибся