Gallery内のviewのクリックイベント検知

1,320 views
Skip to first unread message

北上

unread,
Feb 25, 2011, 9:19:40 AM2/25/11
to 日本Androidの会
北上です。

独自にLinearLayout内に子ビュー(複数のImageViewやTextViewなど)を持つ親viewを作成しました。
この親viewを、Galleryで使用しようとしています。

子ビューのクリックイベントを取得したく、リスナーを設定したところ、Galleryで子ビューのエリアを
タッチしても反応が無くなり、フリングなどが行えません。

調べたところ、子ビュー→Galleryの順でタッチイベントが通知されており、子ビューでイベントを
取得(消費)すると、Galleryに通知されていないようでした。

子ビューでクリックイベントを取得しつつ、Galleryのフリングも普通に出来る方法をご存知の方、
教えて頂けないでしょうか?

ちなみに、GridViewでは上記の問題は発生しません。

あんざいゆき

unread,
Feb 25, 2011, 12:33:26 PM2/25/11
to android-g...@googlegroups.com
あんざいです。

 多分 Click を実装しているの(setOnClickListener) だと思いますが、
 setOnTouchListener にしてみてください。

 Clickの場合、押して、離したときにイベントが飛びます。
 Click でタッチイベントが消費されてしまうので、
   button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
   });

  のように、onClick の戻り値は void です。

 一方、 Touch の場合は、押したときにイベントが
 飛ぶので、そのイベントを次に渡すか、そこで
 消費するのかを指定できます。
 button.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
showToast(v);
return false;
}
   });

 このように、onTouch の戻り値は boolean で、
 ここでイベントを消費するかどうかを表しています。
 つまり、 false を指定すると、イベントが次に渡され
 true を指定すると渡されません。

 手元では、上記のコードでToast を出しつつフリングできました。

# public void showToast(View v){
# Toast.makeText(this, "test", Toast.LENGTH_SHORT).show();
# }

2011年2月25日23:19 北上 <kitaka...@gmail.com>:

--
このメールは Google グループのグループ「日本Androidの会」の登録者に送られています。
このグループに投稿するには、android-g...@googlegroups.com にメールを送信してください。
このグループから退会するには、android-group-j...@googlegroups.com にメールを送信してください。
詳細については、http://groups.google.com/group/android-group-japan?hl=ja からこのグループにアクセスしてください。




--
あんざい ゆき
anzai...@gmail.com
twitter : @yanzm
Y.A.Mの雑記帳 http://y-anz-m.blogspot.com/

北上

unread,
Feb 27, 2011, 10:32:28 PM2/27/11
to 日本Androidの会
あんざい様

北上です。
返信ありがとうございます。

実は、onTouch()も試していました。
確かに、returnをfalseとすることで、Galleryのフリングは
することが出来ました。

但し、returnをfalseとすると、子ビューのACTION_DOWNは拾えるのですが、
それ以外(ACTION_MOVE,ACTION_UPなど)のイベントを拾うことは出来ません
でした。
#returnでtrueを返すと(ACTION_MOVE,ACTION_UPなど)も
#拾うことが出来ました。

ACTION_MOVE,ACTION_UPなどのイベントも検知したく、何か良い方法が
あれば教えて頂けると幸いです。

以上、宜しくお願いします。
> 2011年2月25日23:19 北上 <kitakami....@gmail.com>:
>
>
>
> --
> あんざい ゆき
> anzai.y...@gmail.com
> twitter : @yanzm
> Y.A.Mの雑記帳http://y-anz-m.blogspot.com/- 引用テキストを表示しない -
>
> - 引用テキストを表示 -

あんざいゆき

unread,
Feb 27, 2011, 10:54:54 PM2/27/11
to android-g...@googlegroups.com
ACTION_MOVE, ACTION_UP は
フリングを行うかどうかの判定に使われると
思うのですが、フリングしつつ、これも取得したい
という状況がよくわかりません。
フリングしているかどうかを取得するのでは
だめなのですか?

あんざい

2011年2月28日12:32 北上 <kitaka...@gmail.com>:

--
このメールは Google グループのグループ「日本Androidの会」の登録者に送られています。
このグループに投稿するには、android-g...@googlegroups.com にメールを送信してください。
このグループから退会するには、android-group-j...@googlegroups.com にメールを送信してください。
詳細については、http://groups.google.com/group/android-group-japan?hl=ja からこのグループにアクセスしてください。

北上

unread,
Feb 28, 2011, 12:28:42 AM2/28/11
to 日本Androidの会
あんざい様

北上です。

> ACTION_MOVE, ACTION_UP は
> フリングを行うかどうかの判定に使われると
> 思うのですが、フリングしつつ、これも取得したい
> という状況がよくわかりません。
> フリングしているかどうかを取得するのでは
> だめなのですか?
>
通常のGalleryでは、フリングも行えますし、Galleryにadapterを
介してセットするviewのクリックイベント(onItemClick)も
取得出来ます。

やりたいこととしては、このviewが複数の子viewを持つ場合、
それぞれのクリックイベントを取りたいと考えています。

ACTION_UPやACTION_CANCELが取得出来れば、クリックイベントの
代用が出来るのではと考えていました。

以上、宜しくお願いします。

On 2月28日, 午後12:54, あんざいゆき <anzai.y...@gmail.com> wrote:
> ACTION_MOVE, ACTION_UP は
> フリングを行うかどうかの判定に使われると
> 思うのですが、フリングしつつ、これも取得したい
> という状況がよくわかりません。
> フリングしているかどうかを取得するのでは
> だめなのですか?
>
> あんざい
>
> 2011年2月28日12:32 北上 <kitakami....@gmail.com>:

あんざいゆき

unread,
Feb 28, 2011, 1:08:53 AM2/28/11
to android-g...@googlegroups.com
Gallery の子要素に複数のView が含まれている場合、
それぞれの View に対して TouchListener を設定しては
という意味です。
Gallery のAdapter に対してどうこうする、という意味ではありません。

View で View.setOnTouchListener() で設定したリスナーの
onTouch() を呼んでいるところです
http://tools.oesf.biz/android-2.3_r1.0/xref/frameworks/base/core/java/android/view/View.java#3876

3876 public boolean dispatchTouchEvent(MotionEvent event) {
3877 if (!onFilterTouchEventForSecurity(event)) {
3878 return false;
3879 }
3880
3881 if (mOnTouchListener != null && (mViewFlags &
ENABLED_MASK) == ENABLED &&
3882 mOnTouchListener.onTouch(this, event)) {
3883 return true;
3884 }
3885 return onTouchEvent(event);
3886 }

mOnTouchListener.onTouch(this, event) の戻り値が true なら true を, false なら
onTouchEvent(event) の結果を返しています。

つまり、onTouch() の戻り値が true だとタッチイベントがその View で終わるというのは
最初のメールで書いたとおりです。

onTouch() の戻りが false の場合に呼ばれる onTouchEvent() を見ればわかりますが、
http://tools.oesf.biz/android-2.3_r1.0/xref/frameworks/base/core/java/android/view/View.java#onTouchEvent
ACTION_UP, ACTION_DOWN, ACTION_CANCEL, ACTION_MOVE
を処理しています。つまり、これより先に呼ばれる setOnTouchListener で設定
したリスナーの onTouch() メソッドにもこれらが渡されるということです。

# 家に帰ったらサンプルだせるんですけど、、、、すいませんが夜までお待ちください。

あんざい


2011年2月28日14:28 北上 <kitaka...@gmail.com>:

yuka2py girl

unread,
Feb 28, 2011, 7:54:36 AM2/28/11
to android-g...@googlegroups.com
ゆぅかです。こんばんわ。

同じようなところで、わたしもちょっと前に悩みました。
そのときは、結局、あまりうまく行かなくて、以下のようにしました。

1)Gallery に OnItemClickListener を実装する
2)Gallery の Item 上でクリックイベントを取りたい View に OnTouchListener を実装する
3)この onTouch では false を返すが、同時にどの View のイベントだったか記録する
4)Gallery の onItemClick で、onTouch で記録した View に応じて、処理させる

というような感じで、思ったような動作を実現できました。

より正しいやり方があるんだろうと思いますが、ご参考までですぅ。
ではー。

ゆぅか。


2011年2月28日14:28 北上 <kitaka...@gmail.com>:

Reply all
Reply to author
Forward
0 new messages