2013-11-24

[ブラウザ] ついにGoogle Chromeに引越し(レビュー)

最近、動きが遅くなり不安定になってしまったWindows 7からUbuntu へ引越しをし、 (プログラマーとして)快適な環境を手に入れて、以前よりサクサクAndroidアプリを開発しています。

ブラウザに関しても高速化ができたので嬉しい限りだったのですが、今回さらに高速な環境を実現すべく、以前から何度か挑戦しては挫折していた Firefox ⇒ Google Chrome への引越しに挑戦してみました。
今回は引越しをした結果のレビューをお送りします。




[結論] 多少Firefoxの方が使いやすい部分もありますが、それを補ってお釣りが来る「高速化」が実現できました。^^


引越しを決意したのは、ある海外のAndroid情報番組をYoutubeで見ていた時に、プログラマーさんが私と同じUbuntu を使っていたのにデフォルト搭載されているFirefox を使わず、わざわざGoogle Chromeをインストールしているのを見たからです。

あと、私はマウスジェスチャをフル活用してブラウザを操作するのですが、Ubuntu版のマウスジェスチャがうまく動作しないと聞いていたので引越しをためらっていました。
ですが、今回Smooth Gestures というLinux環境でも動作するChrome拡張があることを知り引越しをしてみました。


では、以下から個別のレビューになりますがまだChromeビギナーなので「こうやったらできるのに^^;」ということがあったらこっそり教えてください。m_ _m


[速度]

もしかすると、プラシーボ効果かもしれませんがとにかく速く感じます。
とくに起動や終了、そしてやはりGoogle検索をする際は「え、もう!?」と思うほどです。
ホントにたまーにFirefox(というかJavaScript?)のせいでUbuntuがとてつもなく重くなるということも今のところ全くなくなりました。


[使いやすさ]

正直まだ慣れていないせいもあって、Firefoxが懐かしく感じる部分もありますが全体的に快適に動作しています。
気のせいかもしれませんが、マウスを使ってスクロールする際Firefoxの方が少しだけ速く移動する気がしましたが、これもそこまで気になるほどではありません。

ちなみにデフォルトでホームボタンが表示されていないので、パソコンにあまり詳しくない人が使う際は少し戸惑うかもしれないな、と感じました。(実際私の母親にはホームボタンを表示してあげました。^^)
でも、トータルで合格点を大きく上回った感じです。


[Smooth Gesturesについて]

Smooth Gestures は正直 Fire Gestures にほどの使用感は実現できていない感触です。
例えば、ウィンドウの最小化はバグのせいなのかうまく作動しませんし、よく使っていた「キーワードを好きな検索エンジンで検索」といった便利な機能を失うことになりました。*1
また、Firefoxではほぼすべてのページで使用が可能でしたが、Chromeでは設定ページやChromeストアではうまく作動してくれませんし、ジェスチャを使って開きかけのタブへ移動することができない場合もあります。ToT
今後に期待ですね!

*1) ただし、Chromeには検索する際にキーワードを入力して個別の検索エンジンに切り替えるという機能がありますので、慣れればこちらで対応できそうです。


[アドオン(拡張)]

何度かChrome への引越しをすぐに断念していた大きな理由のひとつに「アドオンが充実していないから」というものがありました。
しかし、最近はGoogle Chrome のシェアが大きくなったこともあってかホントに拡張機能が充実してきています。
実際、Firefoxを同じ名前(おそらく同じ提供者)のアドオンも存在していて、特にこの点に関しては何の問題もありませんでした。
※ちなみに、MeasureIt や AdBlock、Collorzillaなどが上記に該当すると思われます。 いつもお世話になってます。m_ _m


[改善して欲しいと思った点]

たまにウェブ上の画像を右クリックして「画像をコピー」⇒画像ソフトに貼り付けという動作をするのですが、そのとき画像が透過gif や png だ透過部分が真っ黒になってしまうのが残念でした。
ドラッグアンドドロップするときちんと透過画像になるので、技術的には可能だと思うのですがどうなんでしょうか?

あとは、表示履歴がデフォルトで保存しないようにできないことですね。
私は「履歴を見るぐらいなら、もっかい検索するよ^^」派なので、できたらこの機能を追加して欲しいですね。

また、JavaScript で表示する alert() や confirm() などのダイアログはFirefox のように新しいウィンドウでは開かずそのページ内に表示して欲しいです。
高速にマウスジェスチャでタブを閉じたいので。


[Greasemonkeyについて]

Firefox を使っている時、自分のブラウザだけで使うGreasemonkey のユーザースクリプトを4つほど搭載していましたが、これについてもなんなくGoogle Chromeにもインストールできました。
ある情報によると、完全互換ではないそうなので、今後もしかすると弊害が出てくる可能性もあるにはあります。


[Flash Playerについて]

AdobeはLinux用へのFlash Playerの開発をバージョン11.2で終了する予定ですが、Google Chromeではそれ以降のFlash player を『Pepper API』という技術を使って提供するらしいです。

※バージョン11.2でも5年間はセキュリティ・サポートはされるようです。


[引越しして良かった点]

繰り返しになりますが、ネット環境が高速になるというのはホントにありがたいものです。また、それにともなって同時に使っている多少エネルギーが必要なソフト(Eclipseとか)が快適に動くようになった気がします。

あと、今Bloggerでこの記事を快適に書けるようになりました。^^
Saveなんてほんとに一瞬です。Mozcと親和性が高いからかな??
改行がおかしくなることもないみたいですし。

そして、個人的にですが Ctrl + F を押した時にでてくる検索ボックスが右上にでてくるのが好きですね。^-^


・・・と、いうことでもう少しGoogle Chrome を楽しんでみようと思います。
もし、またFirefox に出戻りになったら、、、その時はいろんな意味でゴメンネ(笑)

とにかく、Firefox今までありがとう!!


[追記]
引越しをしてからはや約一ヶ月が経ちます。
まだ Chrome を使い続けていますよ。^-^
そして、おそらくこのまま安住しそうな気配です。
不便な部分もありますが、せっかく Ubuntu の高速環境なのでやはり Chrome を使ってより高速なウェブサーフをしていきたいですね。
Firefox は今や元カノと同じような位置づけです。(笑)




2013-11-19

[Android, Java] ビットマップを円、丸角などに切り抜くクラス『BitmapTrim』を公開(ダウンロード可)

今回もゲームアプリ制作に必要となったので、ビットマップを簡単に切り抜くクラスを作成しました。すぐに作成できるかと思いきや、いろんなやり方がありましたし、途中「え!じゃあ全部やり直し(xox)」なんてこともありましたので、多少時間がかかってしまいました。(笑)
GitHub で公開していますので、使ってみたい方はぜひやってみてください。




[何ができる?]
画像の一部分だけを切り取ることができます。(縮小ではありません。)簡単に言うと、自分が写っている写真の顔の部分だけハサミで切り取るイメージです。^-^


では、使い方を順を追って説明します。
まずはインスタンス&アンチエイリアスの設定です。

[インスタンス] 

BitmapTrim bitmapTrim = new BitmapTrim(width, height);


ここのwidth, height は今から作りたいビットマップ(画像)の大きさです。
つまり、以下のように角だけ丸くしたい場合は、元の画像のサイズを設定してください。
イメージは「今から絵を書くけど、紙はどの大きさにするの?」です。 



[アンチエイリアス] 

bitmapTrim.setAntiAlias(true); 

これはオプションなので、アンチエイリアスが必要ない場合はこの行も必要ありません。


では次に、切り取る方法を決めます。
4つの方法があるので、お好きなものを選んでください。
つまり、円に切り取られたビットマップが欲しいなら「円」を見てください。

[切り取る方法]

(円)
bitmapTrim.setTrimCircle(cx, cy, radius);


cx: 中心点のX座標
cy: 中心点のY座標
radius: 半径の長さ


(楕円形)
bitmapTrim.setTrimOval(new RectF(0, 0, width, height);

作りたい楕円のRectFを設定するだけです。
上の例は、画像いっぱいの楕円形ができあがります。


(丸角)
bitmapTrim.setTrimRoundRect(
    new RectF(0, 0, width, height), 
    rx, 
    ry
);


1つ目は範囲を示すRectF。 rx, ry は丸角の半径XとYになります。
(簡単に言うと、rxとryが大きいほど丸に近づきます。)


 (長方形&正方形)
bitmapTrim.setTrimRect(new RectF(0, 0, width, height);
 

これも RectF を設定するだけです。 
つまり、width と height が同じなら正方形になります。


はい!
では次にビットマップを書き込みましょう。
(イメージは切り取った紙に絵を描いていく作業です。)


 [ビットマップの書き込み]
   
bitmapTrim.drawBitmap(bitmap1, left, top);
bitmapTrim.drawBitmap(bitmap2, left, top);
bitmapTrim.drawBitmap(bitmap3, left, top);


left と top は書き込む基準になるXY座標です。
以下の画像を参考にしてください。
ビットマップは、何回でも上から重ねて書き込めます。




つまり、通常でしたらどちらもゼロでOKですね。 


さあ、最後にビットマップの取得です。


[ビットマップの取得]

Bitmap bitmap = bitmapTrim.getBitmap();


使い方は以上です。^-^


[ダウンロードURL]
以下のGitHubページから『BitmapTrim』をダウンロードできます。

https://github.com/SUKOHI/BitmapTrim


[ちなみに]
はじめは clipPath() を使って完成させようとしましたが、これだとアンチエイリアスが効かない(切り口がきれいにならない)ので、違う方法を採用しました。


[参考URL]
Cropping Circular Area from bitmap in android
Your brainstorming also helped me.
Thank you, Altaf.

それにしても僕が参考にしてるページって Stack Overflow率が高いです。
いつも助けていただいて、本当にありがとうございます。^-^

2013-11-09

GalleryAdapter をバージョンアップ(ダウンロード可)

昨日の今日でなんとも言いがたいですが、アプリ制作をすすめる上で前回『GridView を画像ギャラリーにする独自のGalleryAdapterを公開』で公開したGalleryAdapter をバージョンアップしました。-_-;

と、いうのも前回バージョンはリソースIDからのみ画像を設定できていたのですが、どうしてもビットマップからでも追加できるようにしないといけなくなったためです。

今回大幅に修正をしたので、(ほぼ全部の)メソッド名やコンストラクタの引数などが変更になりました。。スミマセンm_ _m
新しいメソッドも追加しております。

[テスト動画は前回と一緒です。^-^]


[変更箇所] Bitmapからでもギャラリーに画像を追加できるようになり、リソースIDとビットマップが混在することができるようになっています。また、一気に全てを削除できる removeAll()や画像を入れ替えるreplace()メソッドも追加しました。



では、使い方です。
メソッド名が変更になっていますが、基本的には前回バージョンと変わりません。

まず、インスタンスの部分。
コンストラクタの引数が2つから1つに変更になっています。

GalleryAdapter galleryAdapter = new GalleryAdapter(this);

これは、リソースIDとビットマップの追加をするための措置で、追加にはそれぞれ専用のメソッドを用意しました。

[リソースID]

ArrayList<Integer> resourceIds = new ArrayList<Integer>();
resourceIds.add(R.drawable.drawable0);
resourceIds.add(R.drawable.drawable1);
resourceIds.add(R.drawable.drawable2);
galleryAdapter.addImageResourceIds(resourceIds);
   
[ビットマップ]
   
ArrayList<Bitmap> bitmaps = new ArrayList<Bitmap>();
resourceIds.add(bitmap0);
resourceIds.add(bitmap1);
resourceIds.add(bitmap2);
galleryAdapter.addImageBitmaps(bitmaps);


また、リソースIDやビットマップをひとつずつ追加するメソッドが(動的にも)使えます。

galleryAdapter.addImageResourceId(R.drawable.new_drawable);
galleryAdapter.addImageResourceId(R.drawable.new_drawable, position);
galleryAdapter.addImageBitmap(bitmap);
galleryAdapter.addImageBitmap(bitmap, position);


上から、

リソースIDを使って画像を最後に追加
リソースIDを使って好きな位置に画像を追加
ビットマップを使って画像を最後に追加
ビットマップを使って好きな位置に画像を追加


となります。
あとは、これをGridView にセットすればOKです。

GridView gridView = (GridView) findViewById(R.id.gridview);
gridView.setAdapter(galleryAdapter);


では、今回新しく追加したメソッドの紹介をします。


[新メソッド]


・removeAll()

一気にすべての画像をギャラリーから消します。


・replaceImageResourceId(int resourceId, int index)
・replaceImageBitmap(Bitmap bitmap, int index)

画像を入れ替えます。
上がリソースIDで下がビットマップ。indexが位置になります。


以上、「はじめからそうしとけよ(# ゚Д゚)」というお話でした。
ダウンロードはGitHubをアップデートしておきましたので以下からどうぞ。

[GitHub]
https://github.com/SUKOHI/GalleryAdapter


では、お疲れ様です。
良い週末をおすごしください。^-^



GridView を画像ギャラリーにする独自のGalleryAdapterを公開(ダウンロード可)

前回このブログで公開したZoomImageViewと同じく、現在つくっているアプリに必要になったので、独自にプログラムをつくりました。
これは、GridViewをギャラリー化するものなので、『GalleryAdapter』という名前にしました。
今回はこれの使い方をお届けします。

※このGalleryAdapterは現在バージョンアップされ、メソッド名等が変更されています。使い方につきましては基本的には同じですが、変更部分は GalleryAdapter をバージョンアップをご覧ください。

[実行テストの動画]



[出来ること] GridView を使って画像のサムネイルを統一したサイズで表示。さらに画像を読み込んでいる間はくるくる回るローディング画像を表示し、しかも非同期で実行。そして、メモリーが不足しないように読み込みも縮小して画像を取得する。



つまり、「できるだけ使うのが快適に^-^」というコンセプトです。

では、使い方です。
まずは、以下のようにレイアウトxmlの中に<GridView>を作成します。

[Xml]

<GridView
    android:id="@+id/gridview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="10dp"
    android:verticalSpacing="10dp"
    android:horizontalSpacing="10dp"
    android:numColumns="auto_fit"
    android:columnWidth="32dp"
    android:stretchMode="columnWidth"
    android:gravity="center" />





そして、次にActivity の中に以下のようにGridViewとGalleryAdapterのメンバ変数を作成してください。(これは後で書きますが、onItemClickイベント内からでも参照できるようにするためです。)


[Activity]

public class YourActivity extends Activity {

    private GridView gridView;
    private GalleryAdapter galleryAdapter;

   
    @Override
    protected void onCreate(Bundle savedInstanceState) {}

    //以下省略

}


そして、次にonCreate()内で以下の3つの作業をします。

1.表示したい画像IDをArrayList<Integer>にセット。
2.それを使って GalleryAdapter のインスタンスをつくる。
3.さらにそれをGridViewにセット。


[onCreate]


// 1.表示したい画像IDをArrayList<Integer>にセット。

ArrayList<Integer> resourceIds = new ArrayList<Integer>();
resourceIds.add(R.drawable.example0);
resourceIds.add(R.drawable.example1);
resourceIds.add(R.drawable.example2);


// 2.それを使って GalleryAdapter のインスタンスをつくる。

galleryAdapter = new GalleryAdapter(this, resourceIds);


// 3.さらにそれをGridViewにセット。

gridView = (GridView) findViewById(R.id.gridview);
gridView.setAdapter(galleryAdapter);



これでオッケーです。
では、後の細かいところは以下の3つのメソッドで紹介しましょう。


[メソッド]

・setProgressBarStyle(int style)

画像が読み込まれるまでの間に表示するくるくる回るローディング画像を大きさを設定します。
パラメータは、以下の4つの定数を使ってください。

GalleryAdapter.PROGRESS_STYLE_NONE ・・・画像なし
GalleryAdapter.PROGRESS_STYLE_SMALL ・・・画像小GalleryAdapter.PROGRESS_STYLE_MEDIUM ・・・画像中
GalleryAdapter.PROGRESS_STYLE_LARGE ・・・画像大


・add(int resourceId)
・add(int resourceId, int index)

ギャラリーに画像を追加します。画像のIDを使います。
上のものはギャラリーの最後に、下は好きな位置に追加ができます。


・remove(index)

ギャラリーから画像を削除します。
注:ここは画像IDではなく、何番目の画像かを指定してください。


メソッドは以上です。

では、 onItemClickイベント時(ギャラリーの中の画像をタッチした時)の注意点を最後にサンプルを使って説明します。


[onItemClick]

gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

        galleryAdapter.add(R.drawable.select_player_rabbit_unavailable, position);    //(1)
        galleryAdapter.remove(position);    //(2)
        gridView.invalidateViews();    //(3)
               
    }
           
});


まず、(1)(2)(3) で使われている galleryAdapter と gridView はActivityのメンバ変数にすることでイベント内からでも参照ができます。

そして、(3)の gridView.invalidateViews();。
これを呼ぶことで追加 or 削除した後の GridView をリフレッシュすることができます。


以上になります。
今後はBitmap からでも追加できるようにしたいと考えています。
では、ダウンロードはいつものごとくGitHubからどうぞ♪

[GitHub]
https://github.com/SUKOHI/GalleryAdapter


お疲れ様でした。


2013-11-08

移動&ズームができる ImageView を独自に作成してみました。(ダウンロード可)

先日からとりかかっているアプリの中で、画像を移動したり2本の指で拡大・縮小ができるようにしたかったので、いろいろとインターネット上を探してみましたが、あまり数も少なくまたあってもファイル数が多いなど超高機能なものばかりだったので今後のことも考えて独自にシンプルなものを作成しました。
今回の記事は使い方の覚え書きになります。
(ダウンロードは最後にGitHubのURLを記載しています。)

 [実際の見本]


[概要] 2本の指で画像をピンチ・ズームイン、ズームアウト(拡大縮小)、またダブルタップで画像を最小、最大、元の大きさにそれぞれ変更することができます。たったひとつのファイルで340行(2013年11月8日現在)だけのシンプルなプログラムで書かれています。


[サンプル・コード]
使い方は通常の ImageView とほぼ同じです。

// Xml に記述

<com.sukohi.lib.ZoomImageView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:src="@drawable/drawable"
    android:background="@color/black" />
  
// コード上でやる場合は以下のように。(メソッドについては後で書きます)

ZoomImageView zoomImageView = new ZoomImageView(this);
zoomImageView.setImageResourceId(R.drawable.drawable);
// もしくは setImageBitmap(bitmap);
zoomImageView.setMaxScale(5F);    // 省略可(デフォルト:2F)
zoomImageView.setMinScale(0.1F);    // 省略可(デフォルト:0.5F)
zoomImageView.setDoubleTapDuration(5F);    // 省略可(デフォルト:300)


[メソッド]

・setMaxScale(float scale)

表示する画像の最大サイズを設定できます。
つまり、2Fなら初期サイズの2倍が最大でそれ以上は大きくならない、ということになります。
デフォルト: 2F


・setMinScale(float scale)

表示する画像の最小サイズを設定できます。
つまり、0.5Fなら初期サイズの0.5倍(=1/2)が最小でそれ以上は小さくならない、ということになります。
デフォルト: 0.5F


・setDoubleTapDuration(int duration)

ダブルタップを検知する速さです。duration の値が少なければ少ないほど素早くダブルタップしないとイベントが起動しません。
デフォルト: 300


以上です。
今後もアプリ開発に関連して拡張をしていこうと思っています。
次は画像の回転もいいかな、なんておもっています。
では、最後にダウンロードURLを。


<追記>
メソッドを3つ追加しました。
どれも画像の状態がどうなっているか?を取得するためのものです。

・getImageRect();

表示されている画像のRect を取得します。


・getImageScale();

 表示されている画像のスケールを取得します。


・getImagePoint();

 表示されている画像のXY座標を取得します。


[ダウンロードURL(次のページの右下からDLできます。)]
https://github.com/SUKOHI/ZoomImageView

Have a good day!

2013-11-07

[GitHub] ブラウザでGitHubにコードをアップロード

GitHubにはwindowsやmac用のクライアント・ソフトがありますが、先日から僕が使っているUbuntuなどのLinuxにはそういったソフトはありません。
GitHubの環境をUbuntuにも組み込んでもいいのですが、単なるバージョン管理程度でしかGitHubを使っていないので、より簡単にブラウザだけでコードをアップする方法を調べてみました。
意外と簡単にできました!




[最終結論] 実際にはファイルをアップロードするわけではないので、たくさんのコードをアップするには手間がかかります。でも、バージョン管理程度の使い方なら手軽でおすすめ。


まずやり方としては、

1.プロジェクトを作成
2.プログラム・コードを登録

の2つになります。


では、1番の「プロジェクトを作成」から見て行きましょう。

GitHubにログインをすると、画面右上に”本のアイコン”があるので、そこをクリックします。




すると以下のようなプロジェクト作成画面になりますので、

 1.プロジェクトの名前を入力
2.説明文(任意)を入力
3.チェックを入れる

の3つの作業を完了させて「Create repository」ボタンをクリックをしてください。

(※ここからは、僕が実際に公開しているAndroid用のJavaコード「ZoomImageView」を使って説明していきます。)


プロジェクトが作成できたら以下のファイル・アイコンをクリックして、プログラム・コード本体を登録します。




ここでは、

1.ファイル名の入力
2.プログラム・コード本体の入力
3.変更点などの説明

の3つの作業を完了させて「Commit New File」ボタンをクリックしてください。
(ちなみに、ファイル名は「.java」や「.php」などの拡張子を入れないといけないようです。)



はい!以上で作業は終了です。
この方法だと、プログラム・コードをコピペしないといけないのでたくさんのファイルアップには向きませんが、ライトな使い方でしたら問題なく使えると思います。


<追記>
バージョンアップしたとき、登録したプログラムを更新する方法を追記します。
まず変更したいファイルを選びます。



Editをクリックします。




以下の画像のように、コードを変更して変更点などを入力。
後はクリックするだけで終了です。





お疲れ様でした。^-^



[参考ページ]
How To Upload GitHub Project Using Browser Web Interface
Thank you for a useful tip of you, Abhishek.

2013-11-03

[インク詰め替え] ダイソーの詰替え用インクを使ってみました。(成功)

その昔Amazonで激安購入したヒューレットパッカードのプリンタを押し入れから出してきて使おうとすると、青(シアン)がインク切れでした。
普通にインクを購入してもいいのですが、このパソコンは本体が安い代わりにインクがべらぼうに高かった記憶がありましたし、 一度インクの詰替えというものを体験してみたかったので、実際にダイソー商品でやってみました。
今回はその作業内容を公開したいと思います。



[最終結果] とても簡単にできました。しかも、僕のプリンタ(HP Photosmart Wireless B110a) のインクカートリッジは噴出口にインクを垂らして注入するだけでOKとのことでしたので、難しい作業もなくすぐに完了しました。


では、まずはダイソーで購入した詰め替えインクの紹介から。



売り場には数種類の詰め替えインクが売っていました。もちろんHP用は置いていなかった(っていったらHPに怒られますね^^;)ので、キャノン用を購入しました。
なぜなら、このタイプは穴をあける小さな道具も同梱されているということだったので、最悪は穴を開けようと思っていましたが、結局いっさい使いませんでした。^^


驚くことに、これがたった100円(税別)で売られています。
しかも丁寧なことに、ビニール手袋までついている親切設計。
さすがはダイソーです。


では、次に中身。


説明書とインク本体、穴あけ道具、ビニール手袋、そしてその他もろもろのシールが入っていましたが僕には関係なかったのでほぼスルーしました。



右が取り外したインクカートリッジで、左が購入した詰替え用インク。
このインクカートリッジの丸い部分からインクを垂らして補充します。
では実際に。


写真を撮りながらやったので、多少こぼしてしまいましたがなんの問題もなく補充できました。
ただ、注意してほしいのは「どうせ100円なんだからいっぱいつめちゃえ!」ってやってしまうと逆側からもれてきます。
目安としては1/3減らないぐらいがちょうどいいと思います。


これで作業は終了。
後はプリンターにカートリッジを戻してヘッドクリーニングを行なってください。
僕のケースではインクを入れすぎたためかスジが出てしまいましたので2回ヘッドクリーニングを行いましたが、その後はとても好調です。


と、いうことで。
できました〜!!
青が復活です。



こういった久しぶりだったのでとても楽しかったです。
今度は穴あけもやってみたいです。
お疲れ様でした。


[Android開発] タップした位置にビューを移動する方法

Android開発をする際に必ず必要となるのがレイアウトの知識です。
ですが、Androidのレイアウト表示は多少クセのある部分があります。
ということで、今回は「タップした位置にビューを移動する方法(注意点)」をお届けしたいと思います。


[最終結論] getLocationOnScreen() にはステータスバーの高さも含まれているので、setY() を使うときは注意が必要。


まず、「タップした位置にビューを移動する」というのはどういうことかというと、


このように、タッチしたビューを基準にして他のビューを移動させることです。
「今ココを選択してますよ〜」、みたいなやつですね。


では、これを実現するための順序を。

1. タッチイベントをつくる。
2. タッチされたビューの位置を取得。
3. その位置を基準にして移動させたいビューの位置を設定。

という流れです。
※ちなみにレイアウトのxml には<RelativeLayout> を使った例になります。

では、まず1番の「タッチイベントをつくる」から。
と言っても、これは簡単ですね。
該当する xml に <ImageView>を書き込んで、onCreate() の中で


ImageView imageView = (ImageView) findViewById(R.id.image_view);
imageView.setOnClickListener(new View.OnClickListener() {
           
    @Override
    public void onClick(View v) {

        // ここに2番、3番の処理を書きます。      

         
    }
           
});



とやればオッケーです。

では、次に2番「タッチされたビューの位置を取得」にうつりましょう。
まずタッチされたビュー(ここではR.id.image_view)の位置を取得します。
つまり、以下のようなことですね。


この部分を追加したコードは以下。
ImageView imageView = (ImageView) findViewById(R.id.image_view);
imageView.setOnClickListener(new View.OnClickListener() {
           
    @Override
    public void onClick(View v) {

        ImageView touchImageView = (ImageView) findViewById(R.id.image_view);
        int[] locations = new int[2];
        touchImageView.getLocationOnScreen(
locations); //ここで位置が格納される。

         
    }
           
});


※この例ではタッチイベントを使わない場合も考慮して findViewById を使っていますが、単純に引数のView v を使ってもOKです。ちょっと複雑な場合は無視してオッケーです。^-^


はい。
これで、タッチされたビューの「画面の左上からの」位置がlocations の中に取得できました。
ちなみに、、、

locations[0] がX軸(Left位置で使用)
locations[1] がY軸(Top位置で使用)

になります。


では、最後の3番「その位置を基準にして移動させたいビューの位置を設定」です。

まず移動させたいビューを findViewById で取得して、setX()とsetY() で位置を設定します。
この部分はのコードは、、、


ImageView imageView = (ImageView) findViewById(R.id.image_view);
imageView.setOnClickListener(new View.OnClickListener() {
           
    @Override
    public void onClick(View v) {

        ImageView touchImageView = (ImageView) findViewById(R.id.image_view);
        int[] locations = new int[2];
        touchImageView.getLocationOnScreen(
locations); //ここで位置が格納される。


        int touchedImageX = locations[0];
        int touchedImageY = locations[1];


        // ↓↓↓ここから移動させたいビュー の設定

        ImageView moveImageView = (ImageView) findViewById(R.id.move_image_view);
        moveImageView.setX(touchedImageX); //取得した位置をセット
        moveImageView.setY(touchedImageY); //取得した位置をセット
         
    }
           
});


これでOK。
…ではないのです!!

なぜかというと、 どうやらsetX() と setY() は最初に位置を取得した getLocationOnScreen() とは開始点が違うようなので、これだと少しずれた場所に移動させられてしまうのです。

つまり、わかりやすく言うと

画面上部にあるステータスバーが含まれていない位置を指定しなければいけないのです。





なので、ステータスバーの影響をうけないLeftの位置は問題ありませんが、

設定するべきTopの位置 = getLocationOnScreen() で取得したY座標 - ステータスバーの高さ

となります。
ステータスバーの高さは

Rect rect = new Rect();
Window window = getWindow();
window.getDecorView().getWindowVisibleDisplayFrame(rect);
int statusBarHeight = rect.top;
// ステータスバーの高さ



で取得できるので、 最終的なコードは


ImageView imageView = (ImageView) findViewById(R.id.image_view);
imageView.setOnClickListener(new View.OnClickListener() {
           
    @Override
    public void onClick(View v) {

        ImageView touchImageView = (ImageView) findViewById(R.id.image_view);
        int[] locations = new int[2];
        touchImageView.getLocationOnScreen(
locations); //ここで位置が格納される。


        int touchedImageX = locations[0];
        int touchedImageY = locations[1];


        // ↓↓↓ここから移動させたいビュー の設定

        Rect rect = new Rect();
        Window window = getWindow();
        window.getDecorView().getWindowVisibleDisplayFrame(rect);
        int statusBarHeight = rect.top; // ステータスバーの高さ


        ImageView moveImageView = (ImageView) findViewById(R.id.move_image_view);
        moveImageView.setX(touchedImageX);
        moveImageView.setY(touchedImageY-statusBarHeight); // ←ココ
         
    }
           
});



でOKです。
ただし、これはタッチされた画像の左上の点にビューを移動させることになりますので、もしビューの真ん中だとかちょっとずらしたい場合は画像の幅をとって1/2にするなどして位置を調整する必要があります。

また、ビューをタッチした時ではなく、アプリ(アクティビティ)を起動した瞬間にこのテクニックを使う場合には以下のように onWindowFocusChanged() 内で行なってください。onCreate() では早すぎてビューの位置やサイズを取得できないようです。

@Override
public void onWindowFocusChanged(boolean hasFocus) { 


    // ここに追加。


}



以上になります。
お疲れ様でした。^-^


ちなみに記事中で使ってる画像は今作っているゲームアプリのサンプルです。
まだまだ時間がかかりそうです。^-^;