2016年7月27日水曜日

Android CoordinatorLayoutのAnchor機能のまとめ

Android Design Support Library が提供する CoordinatorLayout は Google が推進している Material Design を実装するために、これまでの Layout と比べると幾つかの新しい機能を実装している。

その1つに Anchor 機能がある。これは CoordinatorLayout 内に配置される複数の子View の相対的な位置関係を指定する機能である。

幾つかの単語を定義する。

Anchor View

基準となるView。CoordinatorLayoutの子View、更にその下の階層のView等任意のViewがなれる。
但し、以下に定義する Anchored View 自身やその子、子孫Viewは Anchor View にはなれない。またCoordinatorLayout自身も Anchor View にはなれない。(Design Support Library 23.1 では CoordinatorLayout は Anchor View になれたが、23.2 又はそれ以上で確認したところ、IllegalStateException が発生するようになっていた。)

Anchored View

基準となるAnchor View に対し、相対的に位置関係を指定して配置される View。CoordinatorLayoutの直接の子Viewのみがなれる。これは Layout は一般的に自分の子Viewの配置のみを決めるためである。さらに下の階層での配置はその階層で決められる。

Design Support Library 以外のこれまでの View も Anchor View 及び Anchored View になれる。
また Anchor機能 は CoordinatorLayout が提供するもう1つの機能 Behavior とは無関係である。 但し Behavior にもレイアウト機能があるので、Behaviorが設定されていて、それがレイアウトを行う場合(より正確には Behavior#onLayoutChild が true を返した時)は Anchor での配置よりそちらが優先される。Behavoior の実装で Anchor を使用している場合もある。

Anchor View と Anchored View の指定はレイアウトファイルでおこなう。
以下は AndroidStudio で New Project を Scrolling Activity をテンプレートとして作成したファイル activity_scrolling.xml を一部抜粋、修正したものである。FloatingActionButton の代わりに普通の ImageButton を使用している。これは従来の普通の View で Anchor が設定できることを示すため。(なおコンパイルできるようにjavaソースコードも適当に変更している。)

<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    <!-- 省略 -->
>

    <android.support.design.widget.AppBarLayout
        android:id="@+id/app_bar"
        <!-- 省略 -->
    >
    </android.support.design.widget.AppBarLayout>

    <ImageButton
        <!-- 省略 -->
        app:layout_anchor="@id/app_bar"
        app:layout_anchorGravity="center_horizontal|bottom"
        android:layout_gravity="start|bottom"/>
</android.support.design.widget.CoordinatorLayout>

まず基準となる Anchor View には id をふっておく(android:id="@+id/app_bar")。
そして Anchored View となるViewで app:layout_anchor="@id/app_bar" と Anchor View を指定する。

次に Anchor View のどの場所を配置の基準とするかを app:layout_anchorGravity で決める。

left
基準点を Anchor View の左辺上にする。
right
基準点を Anchor View の右辺上にする。
center_horizontal
基準点を Anchor View の左右の中央にする。
top
基準点を Anchor View の上辺上にする。(指定しない場合のデフォルト値)
bottom
基準点を Anchor View の下辺上にする。
center_vertical
基準点を Anchor View の上下の中央にする。
start
配置の方向が左から右か、その逆かで基準点を Anchor View の左辺上または右辺上にする。(指定しない場合のデフォルト値)
end
配置の方向が左から右か、その逆かで基準点を Anchor View の右辺上または左辺上にする。
center
基準点を Anchor View の上下左右の中心にする。

この例だと app:layout_anchorGravity="center_horizontal|bottom" で基準点を Anchor View の左右中央で下辺上に設定している。

さらにこの基準点に対しどのように View を配置するかを android:layout_gravity で指定する。

left
基準点の左側に配置する。(上下の指定はあるが左右は指定しない場合のデフォルト値)
right
基準点の右側に配置する。
center_horizontal
基準点が View の左右の中心に来るように配置する。
top
基準点の上側に配置する。(左右の指定はあるが上下は指定しない場合のデフォルト値)
bottom
基準点の下側に配置する。
center_vertical
基準点が View の上下の中心に来るように配置する。
start
配置の方向が左から右か、その逆かで View を基準点の左側または右側に配置する。
end
配置の方向が左から右か、その逆かで View を基準点の右側または左側に配置する。
center
基準点が View の上下左右の中心に来るように配置する。(指定しない場合のデフォルト値)

この例では android:layout_gravity="start|bottom" で、基準点に対し左下側(左から右配置を仮定)に View を配置している。
但し、padding や margin も含めた範囲内から View がはみ出る場合はその分移動させられ、強制的に枠内に収まるように配置される。

以下は例に上げたレイアウトファイルの場合の画面。

2016年3月19日土曜日

Linux Mint CinnamonでSystem TrayのDropboxアイコンが無反応になった時の対処法

Linux Mint CinnamonでSystem TrayのDropboxアイコンをクリックしてもコンテクストメニューが出ず無反応になった場合には、以下の設定を試してみましょう。

画面下部のパネルのメニューからシステム設定を立ち上げ、一般を選び、 Enable support for indicators をオフ。

一度ログアウトし、再度ログインする。

副作用があるかどうかは分かりませんので自己責任で。

オリジナルの情報はここ

2015年8月20日木曜日

Javaのアクセス修飾子の使い分け

Javaではアクセス修飾子として可視性の低い順から
  • private: そのクラスからしか見えない
  • package-private(default): 何も指定しない場合。パッケージ内のクラスからしか見えない
  • protected: パッケージ内のクラスと子クラスから見える
  • public: どこからでも見える
がある。これらをどのように使い分けるか個人的な考えを纏めておく。あくまで個人的な指針で正しい考えとは限らない。

その前にアクセス修飾子のことから離れて、継承について考えを纏めてみる。
継承はなるべく使わない方が良い。継承を乱用するとちょっと機能を追加するのに新しいサブクラスを作成したりして、多くのクラスに機能が分散してしまう。
継承が無用と言うわけではない。使う場合は予め継承を前提とした設計を行い計画的に使う必要があるということ。心構えとしては「使わない」程度でちょうど良い。

継承を使う場合としては
  • フレームワークを使用する場合。AndroidでActivityを継承するなど。
に限ったほうが良い。もちろんinterfaceを実装する場合は別である。

このようにクラスは継承しないという前提。
また可視性は最低限に抑えたほうが良いという原則。
 Javaでは継承したクラスのメソッドをオーバライドする場合、またはinterfaceのメソッドを実装する場合には元の可視性より低い可視性は指定できないというルール。
以上をもとに各アクセス修飾子を検討する。

まずトップレベルのクラスまたはインターフェイスに付くアクセス修飾子はpackage-private(つまり何も指定しない)かpublicのどちらかである。
基本的にはpackage-privateで良い。 他のパッケージに見せる、つまり外部パッケージへのインターフェイスとなるクラスにのみpublicを付けるようにする。これは慎重に最低限に抑えるべきである。一度他のパッケージに公開したクラスは削除したり、メソッドを変えたりすると多大な影響を他に及ぼすため非常にやっかいなことになる。
つまりトップレベルのクラスの宣言は
class some_class {
...
}
とアクセス修飾子は付けなくて良い。

以下にクラス内のメンバに対するアクセス修飾子について考える。

private

private指定されたメンバはそのクラスからしか見えない。
クラス外に公開するメンバ以外は全てprivateを指定する。

package-private(default)

アクセス修飾子を付けないとこの可視性になる。これはパッケージ内のクラスからしか見えない。
クラス外に公開するメンバは基本的にこれにすること。
但しinterfaceを実装した場合は例外である。interfaceのメソッドは全てpublicでなければならない。Javaでは親の可視性より低い可視性は指定できないので、interfaceを実装した場合はそのメソッドはpublicとなる。
また継承した場合、package-privateより大きい可視性をもつメソッドをオーバーライドする場合も同様である。

protected

protected指定されたメンバはpackage-privateの可視性に加えてサブクラス(子クラス)からも見えるようになる。
継承を使用しないという前提に立つと、この修飾子を使用することは殆ど無い。例外としてフレームワークからの親クラスのメソッドをオーバーライドする場合、親クラスでの可視性がprotectedであった場合ぐらいである。

public

public指定されたメンバはどこからでも見える。
上述したようにinterfaceを実装した場合はそのメソッドにpublicを指定する。また親クラスのメソッドをオーバーライドする場合、親クラスでの可視性がpublicであった場合もpublicを指定する。
その他、複数のパッケージを使用するような比較的大きい規模のプログラムでは他のパッケージに対してのインターフェイスとなるメソッドにはpublicを指定する(クラス自体もpublicとする)。これは他のパッケージとの依存関係を作るので慎重に最低限に抑えるべきである。安易にpublic指定したメソッドを変更すると他のパッケージなど広範囲の影響を及ぼしてしまう。
mainメソッドは以下のようにpublicにする必要がある。
public static void main(String argv[])

2015年7月8日水曜日

LinuxでのAndroid Emulator使用時のHardware Accelerationの設定

LinuxでAndroid Emulatorを使用する場合、Hardware Accelerationを設定すると起動にかかる時間やレスポンスが改善する。Hardware AccelerationにはGraphics AccelerationとVM(Virtual Machine) Accelerationがある。ここではVM Accelerationの設定方法を示す。
基本的には http://developer.android.com/tools/devices/emulator.html#acceleration に載っていることと同じ。

VM Accelerationを行うには
  • CPUがhardware virtualizationをサポートしていること。
egrep -c '(vmx|svm)' /proc/cpuinfo
とし1以上が返ってくればCPUは対応している。
  • BIOSでhardware virtualization supportがイネーブルになっていること。

が条件となる。

LinuxではKVMをインストールすることでVM Accelerationが可能になる。インストール方法は https://help.ubuntu.com/community/KVM/Installation を参考に行った。

インストールするモジュールは(Ubuntuの場合)
qemu-kvm, libvirt-bin, ubuntu-vm-builder, bridge-utils

sudo apt-get install qemu-kvm libvirt-bin ubuntu-vm-builder bridge-utils
等でインストールする。

インストール後libvirtdのグループに自分を加える。
sudo adduser `id -un` libvirtd
その後一度ログアウトし、再びログインする。

端末で
virsh -c qemu:///system list
とし
 Id    名前                         状態
----------------------------------------------------

と表示されれば、インストールは成功。

EmulatorでVM Accelerationを行うには更に
  • Android SDK ToolsがRevision17以上
  • AVDがx86ベースのシステムイメージで作成されている
である必要がある。
この条件を満たすことを確認したらAndroid Studioのメニューの「Run」-「Edit Configurations...」で表示されたダイアログで「Emulator」タブの「Additional command line options」をチェックし、右側に
-qemu -m 512 -enable-kvm
と記述する。
後はこのx86ベースのEmulatorを立ちあげれば良い。

Emulatorが立ち上がるまで(ロック画面が表示されるまで)の時間を計測してみると

x86ベース、VM Acceleration無し 28秒
x86ベース、VM Acceleration有り 18秒
armベース 6分30秒

となった。
armベースは桁外れに遅い。

2015年7月6日月曜日

Android StudioでEmulatorが立ち上がらない時

LinuxでAndroid Studioを使用している時、Emulatorを立ち上げようとすると

NAND: could not write file /tmp/android-***/emulator-***

などというメッセージがでてEmulatorが立ち上がらない場合がある。

そのような時は /tmp ディレクトリがどうなっているか確かめる。

df -h で

Filesystem              Size  Used Avail Use% Mounted on
...
tmpfs                   256M  110M  147M  43% /tmp
...

等と出た場合はtmpfsでメモリ上に/tmpディレクトリがマウントされている。

Emulatorは500Mバイト以上のファイルサイズを/tmp/android-***ディレクトリ上に要求するので、上のようにサイズが256Mバイトだと容量が足りずあのようなエラーメッセージがでる。

解決方法としては/etc/fstabを編集して

tmpfs /tmp tmpfs rw,size=1024m 0 0

等とし、/tmpのサイズを1Gバイト以上にする。または上記をコメントアウトしてディスク上に/tmpディレクトリが存在するようにする。

ちなみに私は、/tmpは一時的なファイルが頻繁に書き込まれるディレクトリなので、SSDになるべく書き込みが少なくなるようにこの設定を行っていました。LinuxでSSDを使っている人は同じ罠にはまるかも?


Android Studioインストール時のエラー

Androidの新しい開発環境Android StudioをLinux(Linux Mint)にインストールしたら、以下のメッセージがでて進まない。

The following SDK components were not installed:
sys-img-x86-addon-google_apis-google-22 and
addon-google_apis-google-22

何度かリトライしてみたがダメ。
結局


  • ホームディレクトリの.AndroidStudio1.2を.AndroidStudio1.2.oldとリネーム
  • ホームディレクトリの.androidを.android.oldとリネーム
  • 念の為インストールしたandroid-studio以下のファイルも全部削除
  • AndroidStudioを再インストール。今度はインストールできた!

これでOK。
恐らく以前Eclipseで開発していた時から存在していた.androidがなにか悪さをしていた模様だが、何がダメだったのかはっきり分からず気持ち悪い。

2015年4月2日木曜日

国立 大学通りの桜の風景

画像を入れるテストを兼ねて国立の大学通りの桜の写真をアップ。


いい感じの時計と桜。駅から見て紀伊國屋の先のタバコ屋さんと瀬戸物屋さんの前辺りにあります。


あっという間に満開ですな。


国立高校近くの歩道橋の上から。


国立駅のホームから。