質問するログイン新規登録

回答編集履歴

6

メソッド名修正

2017/11/24 07:08

投稿

keicha_hrs
keicha_hrs

スコア6768

answer CHANGED
@@ -113,7 +113,7 @@
113
113
  animationImageReset();
114
114
 
115
115
  mReplayFlag = true; // 再生中にする
116
- animationPlay(); // 再生する(ここでは1手目だけ、以後はonAnimationEndに任せる)
116
+ animationReplay(); // 再生する(ここでは1手目だけ、以後はonAnimationEndに任せる)
117
117
  }
118
118
  }
119
119
  });
@@ -121,7 +121,7 @@
121
121
       // 中略
122
122
  }
123
123
 
124
- private void animationPlay() {
124
+ private void animationReplay() {
125
125
  if (mReplayFlag) {
126
126
  int dir = mHistory.get(mReplayCount); // リストから取り出し
127
127
 
@@ -156,7 +156,7 @@
156
156
  @Override
157
157
  public void onAnimationEnd(Animator animation) {
158
158
  if (mReplayFlag) {
159
- animationPlay(); // 再生する
159
+ animationReplay(); // 再生する
160
160
  }
161
161
  }
162
162
 

5

サンプル修正

2017/11/24 07:08

投稿

keicha_hrs
keicha_hrs

スコア6768

answer CHANGED
@@ -113,8 +113,7 @@
113
113
  animationImageReset();
114
114
 
115
115
  mReplayFlag = true; // 再生中にする
116
- animationPlay(mHistory.get(0)); // リストの0番目から取り出した値を最初に再生
116
+ animationPlay(); // 再生する(ここでは1手目だけ、以後はonAnimationEndに任せる)
117
- mReplayCount = 1; // 0番目は再生したのでカウンターは1にする
118
117
  }
119
118
  }
120
119
  });
@@ -122,20 +121,32 @@
122
121
       // 中略
123
122
  }
124
123
 
125
- private void animationPlay(int dir) {
124
+ private void animationPlay() {
125
+ if (mReplayFlag) {
126
+ int dir = mHistory.get(mReplayCount); // リストから取り出し
127
+
126
- switch (dir) {
128
+ switch (dir) {
127
- case 0: // 0は上を意味する
129
+ case 0: // 0は上を意味する
128
- upAnimation();
130
+ upAnimation();
129
- break;
131
+ break;
130
- case 1: // 1は下を意味する
132
+ case 1: // 1は下を意味する
131
- downAnimation();
133
+ downAnimation();
132
- break;
134
+ break;
133
- case 2: // 2は左を意味する
135
+ case 2: // 2は左を意味する
134
- leftAnimation();
136
+ leftAnimation();
135
- break;
137
+ break;
136
- case 3: // 3は右を意味する
138
+ case 3: // 3は右を意味する
137
- rightAnimation();
139
+ rightAnimation();
138
- break;
140
+ break;
141
+ }
142
+
143
+ mReplayCount++; // カウンターを増やす
144
+
145
+ // 再生終了したらフラグをクリアする
146
+ if (mReplayCount == mHistory.size()) {
147
+ mReplayFlag = false;
148
+ mReplayCount = 0;
149
+ }
139
150
  }
140
151
  }
141
152
 
@@ -144,14 +155,8 @@
144
155
  // アニメーションが終了したらこのメソッドが実行される
145
156
  @Override
146
157
  public void onAnimationEnd(Animator animation) {
147
- if (mReplayFlag) { // 再生中か
158
+ if (mReplayFlag) {
148
- if (mReplayCount < mHistory.size()) { // リストに格納された手数に到達していないか
149
- int dir = mHistory.get(mReplayCount); // リストから取り出し
150
- animationPlay(dir); // 再生する
159
+ animationPlay(); // 再生する
151
- mReplayCount++; // カウンターを増やす
152
- } else {
153
- mReplayFlag = false; // 再生終了
154
- }
155
160
  }
156
161
  }
157
162
 

4

サンプル追加

2017/11/24 06:59

投稿

keicha_hrs
keicha_hrs

スコア6768

answer CHANGED
@@ -70,4 +70,89 @@
70
70
 
71
71
  という処理を実装すればいいんじゃないですかね。そうすれば、アニメーションが終わる度にonAnimationEndが呼び出され、カウンターの値がArrayListの格納数に満ちるまで繰り返してくれます。
72
72
 
73
- そんな感じでいけるんじゃないかな?
73
+ そんな感じでいけるんじゃないかな?
74
+
75
+ ---
76
+
77
+ (2017/11/24 15:25追記)
78
+ このような感じにしたらというサンプルです。
79
+
80
+
81
+ ```Java
82
+ public class MainActivity extends AppCompatActivity implements Animator.AnimatorListener {
83
+
84
+ // 中略
85
+
86
+ private ArrayList<Integer> mHistory; // 履歴を格納するリスト
87
+ private boolean mReplayFlag; // 再生中であることを示すフラグ
88
+ private int mReplayCount; // 再生経過のカウンター
89
+
90
+ // 中略
91
+
92
+ @Override
93
+ protected void onCreate(Bundle savedInstanceState) {
94
+ super.onCreate(savedInstanceState);
95
+ setContentView(R.layout.activity_main);
96
+
97
+ // 初期値をセット
98
+ mHistory = new ArrayList<>();
99
+ mReplayFlag = false;
100
+ mReplayCount = 0;
101
+
102
+ // 中略
103
+
104
+ btn6.setOnClickListener(new View.OnClickListener() {
105
+ // スタートボタンを押したときの処理
106
+        @Override
107
+ public void onClick(View v) {
108
+ // isEmpty()でリストが空っぽではない(1手以上の記録がある)か調べる
109
+ if (!mHistory.isEmpty()) {
110
+ // 猫を最初の位置に戻す
111
+ x = 0;
112
+ y = 0;
113
+ animationImageReset();
114
+
115
+ mReplayFlag = true; // 再生中にする
116
+ animationPlay(mHistory.get(0)); // リストの0番目から取り出した値を最初に再生
117
+ mReplayCount = 1; // 0番目は再生したのでカウンターは1にする
118
+ }
119
+ }
120
+ });
121
+
122
+      // 中略
123
+ }
124
+
125
+ private void animationPlay(int dir) {
126
+ switch (dir) {
127
+ case 0: // 0は上を意味する
128
+ upAnimation();
129
+ break;
130
+ case 1: // 1は下を意味する
131
+ downAnimation();
132
+ break;
133
+ case 2: // 2は左を意味する
134
+ leftAnimation();
135
+ break;
136
+ case 3: // 3は右を意味する
137
+ rightAnimation();
138
+ break;
139
+ }
140
+ }
141
+
142
+ // 中略
143
+
144
+ // アニメーションが終了したらこのメソッドが実行される
145
+ @Override
146
+ public void onAnimationEnd(Animator animation) {
147
+ if (mReplayFlag) { // 再生中か
148
+ if (mReplayCount < mHistory.size()) { // リストに格納された手数に到達していないか
149
+ int dir = mHistory.get(mReplayCount); // リストから取り出し
150
+ animationPlay(dir); // 再生する
151
+ mReplayCount++; // カウンターを増やす
152
+ } else {
153
+ mReplayFlag = false; // 再生終了
154
+ }
155
+ }
156
+ }
157
+
158
+ ```

3

処理例提案追記

2017/11/24 06:25

投稿

keicha_hrs
keicha_hrs

スコア6768

answer CHANGED
@@ -4,4 +4,70 @@
4
4
 
5
5
  「1つのアニメーションが終わるのを待つ」というところが、「意外と厄介」になる部分です。Javaには時間稼ぎをするためのメソッドも存在しますが、単純にそれを「待つ」部分に突っ込んでしまうと、アプリが強制終了してしまうことでしょう。onCreateやonClickなどAndroidのイベントによって実行されるメソッドは、迅速に処理を終えて抜けるのが大原則です。それらの中で時間がかかる処理を行うと、強制終了されてしまいます。
6
6
 
7
- それを避けるためには、Handlerを用いたり、ThreadやAsyncTaskのような別スレッドとして動作するオブジェクトを作成して、非同期処理として実装したりといったことが必要になります。まずはその辺りのキーワードを検索して、下調べしてみてはどうでしょうか。
7
+ それを避けるためには、Handlerを用いたり、ThreadやAsyncTaskのような別スレッドとして動作するオブジェクトを作成して、非同期処理として実装したりといったことが必要になります。まずはその辺りのキーワードを検索して、下調べしてみてはどうでしょうか。
8
+
9
+ ---
10
+
11
+ 非同期処理は必要なさそうですね。
12
+
13
+ アニメーション処理には、「アニメーションが始まった」「アニメーションが終わった」のようなイベントを取得するためのAnimator.AnimatorListenerというインターフェイスがあります。それを下のようにして実装します。
14
+
15
+ ```Java
16
+ // 末尾にimplements Animator.AnimatorListenerを加える
17
+ public class MainActivity extends AppCompatActivity implements Animator.AnimatorListener {
18
+
19
+ // 中略
20
+
21
+ private void animationImageView(String property, float start, float end) {
22
+ ImageView imageView = (ImageView) findViewById(MyCat);
23
+ ObjectAnimator animator = ObjectAnimator.ofFloat(imageView, property, start, end);
24
+ animator.setDuration(1000);
25
+ animator.addListener(this); // この行を加える
26
+ animator.start();
27
+ }
28
+
29
+ // 中略
30
+
31
+ // 下記の4つのメソッドを加える
32
+ // 実装必須なのですることがなくても空のメソッドを記述する必要あり
33
+ @Override
34
+ public void onAnimationStart(Animator animation) {
35
+ }
36
+
37
+ @Override
38
+ public void onAnimationEnd(Animator animation) {
39
+ // アニメーションが終了するとここが実行される
40
+ }
41
+
42
+ @Override
43
+ public void onAnimationCancel(Animator animation) {
44
+ }
45
+
46
+ @Override
47
+ public void onAnimationRepeat(Animator animation) {
48
+ }
49
+ }
50
+ ```
51
+
52
+ - 履歴を記録するためのArrayList
53
+ - 再生処理中であることを示すフラグ
54
+ - 何手目まで再生したか数えるカウンター
55
+
56
+ をフィールド変数として用意しておけばいいでしょう。
57
+
58
+ 「スタート」ボタンを押したら
59
+ 0. ArrayListが空っぽでなければ
60
+ 0. フラグを有効にして
61
+ 0. ArrayListから1手目を取り出してアニメーション開始
62
+
63
+ というところまでをonClickに記述します。
64
+
65
+ onAnimationEndには、
66
+ 0. フラグが有効だったら
67
+ 0. ArrayListに格納されている数がカウンターの値未満だったら
68
+ 0. カウンターを1増やして
69
+ 0. ArrayListからカウンターの値に従った手を取り出してアニメーション開始
70
+
71
+ という処理を実装すればいいんじゃないですかね。そうすれば、アニメーションが終わる度にonAnimationEndが呼び出され、カウンターの値がArrayListの格納数に満ちるまで繰り返してくれます。
72
+
73
+ そんな感じでいけるんじゃないかな?

2

修正

2017/11/21 16:12

投稿

keicha_hrs
keicha_hrs

スコア6768

answer CHANGED
@@ -1,6 +1,6 @@
1
1
  これは意外と厄介ですね。
2
2
 
3
- 操作の履歴を記録するのは、先に出ている答えの通りArrayListを用いればいいでしょうが、再現を行う処理はいろいろ考える必要がありそうです。当然、アニメーションしながら再現を行うことを考えておられると思いますが、単純にArrayListから取り出した端から処理をボンボン行うのではなく、1つのアニメーションが終わるのを待ってから次のアニメーションを実行しないと、思ったように再現されないでしょう。そこをうまく考える必要があります。
3
+ 操作の履歴を記録するのは、先に出ている答えの通りArrayListを用いればいいでしょうが、再現を行う処理はいろいろ考える必要がありそうです。当然、アニメーションしながら再現を行うことを考えておられると思いますが、ArrayListから取り出した端から処理をボンボン行うのではなく、1つのアニメーションが終わるのを待ってから次のアニメーションを実行しないと、思ったように再現されないでしょう。そこをうまく考える必要があります。
4
4
 
5
5
  「1つのアニメーションが終わるのを待つ」というところが、「意外と厄介」になる部分です。Javaには時間稼ぎをするためのメソッドも存在しますが、単純にそれを「待つ」部分に突っ込んでしまうと、アプリが強制終了してしまうことでしょう。onCreateやonClickなどAndroidのイベントによって実行されるメソッドは、迅速に処理を終えて抜けるのが大原則です。それらの中で時間がかかる処理を行うと、強制終了されてしまいます。
6
6
 

1

文章がおかしなところがあった

2017/11/20 12:16

投稿

keicha_hrs
keicha_hrs

スコア6768

answer CHANGED
@@ -1,6 +1,6 @@
1
1
  これは意外と厄介ですね。
2
2
 
3
- 操作の履歴を記録するのは、先に出ている答えの通りArrayListを用いればいいでしょうが、再現を行う処理はいろいろ考える必要がありそうです。当然、アニメーションしながら再現を行うことを考えておられると思いますが、単純にArrayListから取り出した内容通りの処理をボンボン行ってい、1つのアニメーションが終わるのを待ってから次のアニメーションを実行しないと、思ったように再現されないでしょう。そこをうまく考える必要があります。
3
+ 操作の履歴を記録するのは、先に出ている答えの通りArrayListを用いればいいでしょうが、再現を行う処理はいろいろ考える必要がありそうです。当然、アニメーションしながら再現を行うことを考えておられると思いますが、単純にArrayListから取り出した端から処理をボンボン行うのではなく、1つのアニメーションが終わるのを待ってから次のアニメーションを実行しないと、思ったように再現されないでしょう。そこをうまく考える必要があります。
4
4
 
5
5
  「1つのアニメーションが終わるのを待つ」というところが、「意外と厄介」になる部分です。Javaには時間稼ぎをするためのメソッドも存在しますが、単純にそれを「待つ」部分に突っ込んでしまうと、アプリが強制終了してしまうことでしょう。onCreateやonClickなどAndroidのイベントによって実行されるメソッドは、迅速に処理を終えて抜けるのが大原則です。それらの中で時間がかかる処理を行うと、強制終了されてしまいます。
6
6