2013-11-09

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) { 


    // ここに追加。


}



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


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

2013-10-17

[Ubuntu 13.04] サスペンド復帰時、ネットに接続できなくなる問題を解決する

Ubuntu がとても快適です。DropBox をいれてから多少速度が落ちた気がしますが、それでもWin7と比べるとサクサク動いてくれますね。

さて、そんな中今回のタイトルにもある「サスペンドから復帰した時にインターネットにつながらなくなる」という問題が起こりました。これはUbuntu 13.04 をインストールしてからずっとです。

そこで、いろいろ調べて解決法を見つけたのでここに紹介したいと思います。


[最終結論] /etc/pm/config.d/unload_modules に設定をする


今回やることはたった2点です。

1.ワイヤレスドライバーを調べる
2.設定を追加する



ではまず1の「ワイヤレスドライバーを調べる」から見ていきましょう。
端末(terminal)を開いて以下のコマンドを実行してください。


nm-tool


すると、次のような情報が表示されます。



他にもたくさんの情報がでてきますが、画像にあるように Device: wlan0 [**********] という部分を探してください。
(おそらく wlan* が無線で eth* が有線?有線でインターネット接続してる方はこちらでeth0 と読みかえて試してみてください。)

そして、 Device: wlan0 のすぐ下にある


Driver :              *******


これがあなたのパソコンが使っている無線LANのドライバー名です。
次の手順で使いますので覚えておいてください。


では、2の「設定を追加する」です。
同じく端末から以下のコマンドを実行してください。


gksu gedit /etc/pm/config.d/unload_modules


パスワードを求められると思いますので、ログイン用のパスワードを入力してください。

すると、テキストエディタが開きますので、以下の文字列を追加してください。
******の部分はさっき確認した無線 or 有線LANのドライバー名に変更してください。
(ちなみに私の場合では元々このファイルは存在していませんでしたので、新規にファイルを作成するという形になりました。)



SUSPEND_MODULES="$SUSPEND_MODULES ******"


では、保存をして終了して作業は完了です。
お疲れ様でした。
これでサスペンドから帰ってきても自動でインターネット接続を再開してくれると思います。


[参考URL]
1. Wireless doesn't connect after suspend on an Asus K52F
2. Fix Wireless Or Wired Network Not Working After Resume From Suspend In Ubuntu
Thanks a lot Ryan, Marco and WebUpd8!

2013-10-16

[Ubuntu 13.04] 起動時の明るさを設定する方法

先日から使っているUbuntu。
Windows7 と比べるとかなりいいパフォーマンスをしてくれていて嬉しい限りです。

ただ、小さな部分ではまだほんの少し自分自身で設定をしなければならない部分もあるので、そこは今後の課題ですね。

ということで、今回はそんな中の「起動時には必ず画面の明るさが最大になってしまう」という問題を解決する方法をご紹介します。 




[最終結論]
/etc/rc.local に設定を追加する。


まず、実際のファイルに設定を追加する前にあなたのパソコン内では「画面の明るさの最大値」がいくつなのかを知っておく必要があります。
これがわかっていなかったので私は少しつまずきました。^-^;


では、実際に確認しておきましょう。
ターミナル(端末)を起動して以下のコマンドを実行してください。


cat /sys/class/backlight/acpi_video0/max_brightness


すると数字がでてくるはずです。
これが明るさの最大値になります。
(ちなみに私の場合は15でした。)


では、ついでに今の明るさがどんなものかも確認しておきましょう。


cat /sys/class/backlight/acpi_video0/brightness


今回も数字が表示されたと思います。
これが現在の明るさですね。
つまり、この値がさっき確認した最大値とおんなじだったら今最大に明るい画面を見ているということになります。(光が強いのはストレスです。気をつけて。)


さて、ではここからが今回の作業の本番になります。
同様に端末から以下のコマンドを実行してください。


sudo gedit /etc/rc.local


※もしパスワードを聞かれたら、ログインに使っているパスワードを入力してください。
(ちなみに端末のパスワードはタイプしても何も表示されませんが、実際は入力されています)

すると、以下のようなファイルがオープンされると思います。


#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

exit 0




で、この「exit 0」 の前に以下の2行を挿入します。

sleep 2
echo [あなたが設定したい明るさの数字] > /sys/class/backlight/acpi_video0/brightness 


 [あなたが設定したい明るさの数字] ⇒ あなたが設定したい明るさの数字を入力してください。
つまり、私のパソコンの例としては、以下のようになります。


#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

sleep 2

echo 12 > /sys/class/backlight/acpi_video0/brightness


exit 0



で、あとは「ファイル」 > 「保存」でデータを保存すれば今回の作業は終了です。

今やってる作業が一段落したら再起動してみてください。
きっと明るさがうまく設定されているはずです。

お疲れ様でした。



[参考URL]
Set Screen Brightness when Booting Ubuntu 13.04 - Fix Laptop Screen Brightness Falling to Minimum After Every Reboot

I appreciate usuful information of you, Chamitha!!:)))