View自体を拡大縮小する

3,861 views
Skip to first unread message

yuka2py

unread,
Mar 14, 2011, 3:51:04 AM3/14/11
to android-g...@googlegroups.com
ゆぅかともうします。こんにちわ。

現在、View を拡大縮小する方法を探しています。

下記のことなど、色々と試していますが、少々行き詰まり気味です。。。
ヒント等だけでも結構ですので、どなたかご存知の方いらっしゃいましたら、
ご教示いただけましたら幸いです。


まず、目的としては、カスタムの ScrollView の中に配置した View を、
任意のサイズに拡大縮小できるようにしたいと思っています。
対象は API Level 7 です。

現状、ScrollVew の drawChild を下記のように オーバーライドして、
mScale のサイズで画面を拡大・縮小して表示することは出来ています。
-----------------------
public boolean drawChild(Canvas canvas, View child, long drawingTime) {
canvas.save();
canvas.scale(mScale, mScale);
boolean res = super.drawChild(canvas, child, drawingTime);
canvas.restore();
return res;
}
--------------------

ただ、この方法では、実際の View の配置は変更されません。
例えば、View の中にボタンなどを配置して、拡大縮小すると、
ボタンそのものは小さく描画されますが、そのボタンの実態(?)は
拡大縮小される前の場所にあり、その本来の位置へのタッチでしか
反応しません。

そもそも canvas を scale するというアイデアが、
今回の目的に対して間違ったアプローチだったかな?と思いつつ、
フレームワークのソースなども追って見ていますが、
なかなか難しそうな気がしています。

ちょっと無理やりにでもと思ってイベント周りをイジッてみたりもしたのですが、
MotionEvent に API 11 から使える transform というメソッドを見つけたりもして、
もしかして、Honeycomb からなら出来るのかしら?
(API 7 ではやっぱり無理なの?)と思ったりもしています。

# そもそも View 自体を拡大・縮小することは可能なのでしょうか?


つたない文章で大変恐縮ですが、
どうぞよろしくお願いいたします。

-- ゆぅか

yuka2py

unread,
Jun 15, 2011, 6:43:26 PM6/15/11
to android-g...@googlegroups.com
おはようございます。ゆぅかです。

だいぶ以前の質問になりますが、事後報告です。

まず、やりたかったのは、カスタムの ScrollView の中に配置した View の、
任意のサイズへの拡大・縮小です。
困っていたのは、canvas を利用して拡大・縮小は出来たものの、View の
中に配置した子孫 View でのイベント処理の座標が、拡大・縮小された後の
見かけの位置と異なり、本来の位置で処理されてしまうことでした。
拡大・縮小すると、見えているボタンとは違う位置で、イベントが検知されます。

色々と模索したのですが、そのときは、結局思った方向での解決はあきらめまして、
別のアプローチとしました。

具体的には、
機能のホストとなるカスタムの ScrollView に、次の仕様のカスタムイベントリスナを
作成し、組み込みました。

public static interface TapEventListener {
public void onDoubleTap(MotionEvent e, View child, float cx, float cy);
public void onLongPress(MotionEvent e, View child, float cx, float cy);
public void onSingleTap(MotionEvent e, View child, float cx, float cy);
}

ここで、cx/cy は、ScrollView 直下の(唯一)の子 View 上の座標が入ります
この座標は拡大・縮小の状態に影響されず、常にView 上の本来の座標となります。
この値をもとに、子ビュー内のどの位置がタップされたかを判断し、
その後の必要な処理を行いました。

この方法の課題は以下のとおり:
1)子 View へのイベントリスナの設定が普通の方法で出来なくなってしまいます。
 広範に利用できるライブラリにしたかったので、ちょっと残念です。
2)子 View のボタン等に、Selector 等によって視覚効果を加えようとすると、
 依然として画面表示がズレて反映されてしまいます。うむむ。

結局、あまり汎用的なものにはなりませんでしたが、このときの要件はなんとか
満たせたために、この仕様で回避したい次第です。


§

引き続き、View の拡大・縮小については何か情報がありましたら、ご教示いただけ
るとうれしいです。

私に残っている疑問?は、
そもそも ScrollVew.drawChild() でCanvas を修正するアプローチが正しかったのか?
(つまり何かほかにやるべきことが足りなかったのか?)
あるいは、まったく別のアプローチがあったのか? といったことなどです。

この点が曖昧になっているので、今後近似のカスタム要件が出てきた時に、
はまた悩むのだろうなーと思っています。


以上です。
いつもありがとうございます!

-- ゆぅか。

2011年3月14日16:51 yuka2py <yuk...@gmail.com>:

大垣憲俊

unread,
Jun 23, 2011, 2:14:51 PM6/23/11
to 日本Androidの会
ゆぅかさん

おはようございます。大垣です。
これまでに分かったことをお知らせします。

> 現状、ScrollVew の drawChild を下記のように オーバーライドして、
> mScale のサイズで画面を拡大・縮小して表示することは出来ています。

これを実装して確かめました。


> 中に配置した子孫 View でのイベント処理の座標が、拡大・縮小された後の
> 見かけの位置と異なり、本来の位置で処理されてしまうことでした。

ボタンの場合でいうと、拡大縮小する前の、本来の位置でタップすると
その大きさだけ色が変わるので、言われている意味が分かりました。


> そもそも ScrollVew.drawChild() でCanvas を修正するアプローチが正しかったのか?
> (つまり何かほかにやるべきことが足りなかったのか?)
> あるいは、まったく別のアプローチがあったのか? といったことなどです。

Canvas#scale 後のViewGroup#drawChild のアプローチでは、
実際に描いた大きさと、View内部で保持している大きさとが一致しなくなります。
描いた大きさが取得できれば、View#layout で再設定できるのですが。

別のアプローチとして、View#layout で子孫Viewを個別に大きさを変更してみました。
http://ogakisoft.blogspot.com/2011/06/android-exam-re4-zooming-view.html

他の方法、たとえば、個別にではなく一律に拡大縮小する方法もありそうですが、
現時点ではここまでです。

大垣憲俊

unread,
Jul 3, 2011, 9:55:06 PM7/3/11
to android-g...@googlegroups.com
大垣です。

前回のものを修正して、子ビューのサイズと位置を一括して変更してみました。

サンプルの画面キャプチャーを私のサイトにアップしました。

ご参考まで。

yuka2py

unread,
Jul 6, 2011, 7:52:36 AM7/6/11
to android-g...@googlegroups.com

ゆぅかです。こんばんわ!

大垣さん、
ちゃんと見てから返信を…と思っておりましたが、まだちゃんと見れておりません!すみません!

頂いた作例ですが、私が実現したかったものとはやや方向性が異なるのですが、参考になります。
まだソースなど拝見できておりませんが改めて勉強させて頂きます!

ちなみに、わたしが作ろうとしてあたのは、ルーペで拡大したような感じのズームイン(アウト)です。

もともと電子カタログアプリ用の部品だったのですが、
拡大縮小の機能ををカスタムの ScrollView に組み込もう!と思ったとき、
ScrollView が任意の View を子にもてるなら、
何でも拡大縮小できる方が後々楽しそうだなー、
と言うことで取り組みました。

いい線まで行ったと思ったんですが、イベントの座標とかがずれるとは… (*´д`*)

もう少し楽しんでみたい題材なんで、また時間ができたらトライしたいなぁ、と思っています。

以上、とりいそぎトライして頂いたお礼まで。
ありがとうございます!
-- ゆぅか。

2011/07/04 10:55 "大垣憲俊" <noritos...@gmail.com>:
> --
> このメールは Google グループのグループ「日本Androidの会」の登録者に送られています。
> このディスカッションをウェブ上で閲覧するには、https://groups.google.com/d/msg/android-group-japan/-/1LCN__Rlon4J にアクセスしてください。
> このグループに投稿するには、android-g...@googlegroups.com にメールを送信してください。
> このグループから退会するには、android-group-j...@googlegroups.com にメールを送信してください。
> 詳細については、http://groups.google.com/group/android-group-japan?hl=ja からこのグループにアクセスしてください。
>
Reply all
Reply to author
Forward
0 new messages