onTouch()の罠
2016/01/07 02:37:26
お白湯うめぇ
いえね、1行目は適当なことを言っておかないとtrimされるんでね。実際うまいんですけれども。
先日述べた、FrameLayoutに格納したレイアウトからタッチイベントを受け取る形式を採用すると使うことになるonTouch()のオーバーライド。
自分でイベントを処理したときはtrueを返しなさいよ! ってのが約束事だと思う。なので自分で処理したとこはreturn true; なんもせなんだ時はfalse返すのが正しい道であると思う。
ACTION_UPが取得できないんですよ(結論)。
まあ気付いたのは全部return false;してた時なんですが、自己処理したcaseでtrue返しても依然受け取れない……と思ったら受け取れた。
いえ姉さん違うんですよ。
まずonTouch()内でcase ACTION_DOWN:なり書く。さらに進行状況を示すステータスによるswitch分岐を書く。
分岐(case)該当しなかった場合はfalse返してたんだが、どうやらそもそものcase ACTION_XXX: を書いた時点で「自己処理した」 = return true; と考えなきゃいかんのなこれ。どのcase文にもひっかからずonTouch末尾へ至った時に限りfalse返すんであって。気付いてみればごくごく当たり前のこと……なのか? 多分そうなのだろう。
あるイベントの受け取り処理をした時点でreturn true; を確定。しないとその後のイベント受け取りがおかしなことになる可能性大。そういうことで理解しとこう。
参考文献:日本Androidの会 › setOnTouchListenerでACTION_UPが反応しない
いえね、1行目は適当なことを言っておかないとtrimされるんでね。実際うまいんですけれども。
先日述べた、FrameLayoutに格納したレイアウトからタッチイベントを受け取る形式を採用すると使うことになるonTouch()のオーバーライド。
自分でイベントを処理したときはtrueを返しなさいよ! ってのが約束事だと思う。なので自分で処理したとこはreturn true; なんもせなんだ時はfalse返すのが正しい道であると思う。
ACTION_UPが取得できないんですよ(結論)。
まあ気付いたのは全部return false;してた時なんですが、自己処理したcaseでtrue返しても依然受け取れない……と思ったら受け取れた。
いえ姉さん違うんですよ。
まずonTouch()内でcase ACTION_DOWN:なり書く。さらに進行状況を示すステータスによるswitch分岐を書く。
分岐(case)該当しなかった場合はfalse返してたんだが、どうやらそもそものcase ACTION_XXX: を書いた時点で「自己処理した」 = return true; と考えなきゃいかんのなこれ。どのcase文にもひっかからずonTouch末尾へ至った時に限りfalse返すんであって。気付いてみればごくごく当たり前のこと……なのか? 多分そうなのだろう。
あるイベントの受け取り処理をした時点でreturn true; を確定。しないとその後のイベント受け取りがおかしなことになる可能性大。そういうことで理解しとこう。
参考文献:日本Androidの会 › setOnTouchListenerでACTION_UPが反応しない
PR
【Android】int配列をかぶらない(重複しない)数値で初期化する【Java】
2016/01/05 23:06:27
自分用。
for文がちょっと泥臭いとゆうか無駄あるけど、最初の方はどうせ決まりやすいからええわもう。
ArrayList使ってCollections.shuffle()っつうのもあるようだが、とりあえずこれでよし。どうせこのあと更なるランダム要素が加わる。ふしぎな ちからが くわわる くわわる!
Arrays.fill(card, -1);
Random r = new Random();
int i = 0;
while(i < maxCards) {
int j, rnd;
do {
rnd = r.nextInt(maxCards);
for(j = 0; j < maxCards; ++j) {
if(card[j] == rnd) break;
}
}while(j != maxCards);
card[i] = rnd;
++i;
}
for文がちょっと泥臭いとゆうか無駄あるけど、最初の方はどうせ決まりやすいからええわもう。
ArrayList使ってCollections.shuffle()っつうのもあるようだが、とりあえずこれでよし。どうせこのあと更なるランダム要素が加わる。ふしぎな ちからが くわわる くわわる!
タッチするたび別のFragmentに切り替え(replace)る
2016/01/05 14:49:56
http://qiita.com/dmnlk/items/786840c7d910e59b81dc
あちゃこちゃ参考にしてるんだが上記記事が決め手となった。同じ内容を過去に別の英語サイト(上記のさらなるリンク先とは異なる)で既に見てたのだが、わかりやすさが違ったせいかね。
投稿エディタの不具合なのかpreタグなんぞ使ってるせいかレイアウトガタガタだがご容赦を。
とりあえずActivityから最初のフラグメントを呼び出す。cntnはカントン包茎ではなくてコンテナ。
setContentView()ではR.layoutで指定してaddではR.idだもんだからわかりづらいがモノは同一。こういうの、自分みたいな初心者の混乱を招く種だと思う。
で、最初のフラグメント側でタッチリスナー作成。第二のフラグメントへreplace. cntn(FrameLayout)という箱の中身をFirstFragmentからSecondFragmentへ入れ替える作業。
SecondFragmentでも同様の処理を書き、replaceのターゲットをFirstFragmentにする。もちろん必要に応じて別のFragmentへ移せばよい。
アクティビティですべてのFragmentに対応するタッチイベントを組むのもできるが、各Fragmentの状態――現在アクティブなFragmentはどれか、など――をActivity側で把握する必要が発生する。
追記:
FrameLayoutのタッチイベントを処理しているが、このやり方で統一するとどうやらアクティブでないFragmentがタッチイベントを受け取りわやになる可能性があるので、フツーに各Fragmentの擁するレイアウト(上記例ではactivity_mainとactivity_sub)のタッチイベントをあれこれするのがよさそうだ。
あちゃこちゃ参考にしてるんだが上記記事が決め手となった。同じ内容を過去に別の英語サイト(上記のさらなるリンク先とは異なる)で既に見てたのだが、わかりやすさが違ったせいかね。
投稿エディタの不具合なのかpreタグなんぞ使ってるせいかレイアウトガタガタだがご容赦を。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.frame);
if (savedInstanceState == null) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
Fragment f = new FirstFragment();
ft.add(R.id.cntn, f);
ft.commit();
}
}
とりあえずActivityから最初のフラグメントを呼び出す。cntnはカントン包茎ではなくてコンテナ。
setContentView()ではR.layoutで指定してaddではR.idだもんだからわかりづらいがモノは同一。こういうの、自分みたいな初心者の混乱を招く種だと思う。
で、最初のフラグメント側でタッチリスナー作成。第二のフラグメントへreplace. cntn(FrameLayout)という箱の中身をFirstFragmentからSecondFragmentへ入れ替える作業。
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.activity_main, container, false);
}
@Override
public void onStart() {
super.onStart();
FrameLayout fl = (FrameLayout)getActivity().findViewById(R.id.cnt);
fl.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch(event.getAction()) {
case MotionEvent.ACTION_DOWN:
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
ft.replace(R.id.cntn, new SecondFragment());
ft.commit();
break;
}
return false;
}
});
}
SecondFragmentでも同様の処理を書き、replaceのターゲットをFirstFragmentにする。もちろん必要に応じて別のFragmentへ移せばよい。
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.activity_sub, container, false);
}
@Override
public void onStart() {
super.onStart();
FrameLayout fl = (FrameLayout)getActivity().findViewById(R.id.cnt);
fl.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
ft.replace(R.id.cntn, new FirstFragment());
ft.commit();
return false;
}
});
}
アクティビティですべてのFragmentに対応するタッチイベントを組むのもできるが、各Fragmentの状態――現在アクティブなFragmentはどれか、など――をActivity側で把握する必要が発生する。
追記:
FrameLayoutのタッチイベントを処理しているが、このやり方で統一するとどうやらアクティブでないFragmentがタッチイベントを受け取りわやになる可能性があるので、フツーに各Fragmentの擁するレイアウト(上記例ではactivity_mainとactivity_sub)のタッチイベントをあれこれするのがよさそうだ。