ページ

2013/04/24

Android 単一項目を選択させるListViewの設定

|
今さら書くものでもないですが、AndroidのListViewにおけるonClickやonItemClick、さらに項目にラジオボタンや チェックボックスがついていた時など毎回混乱するので「この仕様ならこれで動く」というパターンをメモします。
以下は
  • ListViewにラジオボタンつき項目を表示
  • 項目は1つだけ選択可能
  • 項目が選択されたら(タップされたら)何かする
というパターンです。(以下のイメージ)



リスナーの設定はsetOnItemSelectedListener()ではなくsetOnItemClickListener()であること、 項目を初期選択させるのはsetSelection()ではなくsetItemChecked()であることが注意する点でしょうか。

2013/04/21

iOS ステータスバーの扱い

|
EverForm for iOS」をiPad対応にした際に躓いたポイントです。

iPhoneでは起動画面(Default.png)にステータスバーの高さが含まれています。
(320 x 480 / 640 x 960 / 640 x 1136)

しかし、iPadでは含まれていません。(768 x 1004 / 1536 x 2008)

これは画像のサイズだけの問題ではなく表示位置にも影響します。

iPhoneではスクリーンサイズの起動画面画像を用意しますがステータスバーの分は隠れてしまいます。
一方でiPadはステータスバーの高さを除いた画像なので、ステータスバーの下から画像が表示されます。
単に起動画面を表示する場合は問題になりませんが、その後の画面とうまく繋げようとすると この差が重要になります。

実際やろうとしたことは以下の二つです。
[1] 起動画面の後、画像の一部を重ねてログイン画面を表示する。
[2] ログインした場合は起動画面をフェードアウトして別画面へ遷移させる。

[1]を実現するには起動画面の画像と、ログイン画面に表示させる画像で、重ねたい部分を同じ位置に描画すれば良いと考えると思います。
iPhoneではうまくいくのですが、前述の通りステータスバーの高さが含まれないiPadではうまく行きません。 合わせるためには、iPad用起動画面(Default-Portrait~ipad.pngなど)の重ねたい部分をステータスバーの高さだけ下にずらします。
(iPad mini用画像(Default-Portrait~ipad.png)なら20px、iPad(Retina)用(Default-Portrait@2x~ipad.png)なら40px)
ログイン画面の画像を修正する方法もありますが、こちらは特に合わせようとしなくてもiPhone/iPad同じレイアウトになるので変更しない方が良いでしょう。

[2]を実現する場合には、単に起動画面の画像をアルファ値を0にするようなアニメーションで表示すれば良いですが、やはりiPadの場合は画像の表示位置をステータスバーの分だけずらす必要があります。

ということで、まとめると以下のような感じです。
  • iPad用起動画面(Default.png)はステータスバーの高さが含まれないので、iPhone用の画像を基準にするなら上の20px(Retina用は40px)が欠けたような画像にする。
  • 起動画面を別の箇所で表示させる場合は、iPhone/iPadで表示開始位置(frame.origin.y)をステータスバーの分だけずらす。

iOS ローカライズが失敗してNSLocalizedStringのキーが表示される

|
致命的なミスです。
先日リリースした「EverForm for iOS」ですが、英語のローカライズに失敗した状態でリリースしてしまいました。
アップデート版は先ほど申請しました。

何が問題かというと、NSLocalizedStringの第1引数に与えたキーがそのまま表示されてしまいます。 同じ問題にぶつかった人が検索しやすいように、キーワードを挙げておくと… NSLocalizedStringのkeyが表示される、ラベルのまま表示される、使われない、といったところでしょうか。

EverForm for iOSの場合、言語をEnglishにしてビルド、実行すると発生しました。

最初はAppStore用のプロビジョニングプロファイルを使用した場合でのみ発生する事象なのかと疑ったのですが、通常のビルドでも発生しました。
実は開発中にローカライズの確認をしていたときも何度か発生していたのですが、 2回ビルドして実行すると解消されたため、Cleanするだけでは前回の結果が消えないものがあるのだと思いあまり気にしていませんでした。 結果的に、原因はLocalizable.stringsがプロジェクト内に複数あったことでした。

原因が分かったきっかけは、あれこれ調べた結果以下のコメントを見つけたことです。

Check if you have more than one Localizable.strings in your project. Merging them into one solved it for me.
http://stackoverflow.com/questions/6709350/xcode-localized-string-not-loaded


それから「2回ビルドすると解決する」という事実、
JapaneseとEnglishのローカライズされたファイル数が違う、
ということでした。
ローカライズされたファイル数はプロジェクト(XXX.xcodeproj)の「PROJECT」>「INFO」>「Localizations」で確認できますが、英語の方が1つ多かったのでした。
それが何かというと、使用しているEvernote SDKのライブラリ内に存在している英語のLocalaizable.stringsです。
ビルドすると、このファイルとメインの(元々自分で用意した)en.lproj/Localizable.stringsが交互で適用されるようで、マージはされません。
そのため、ビルドした1回目はNSLocalizedStringのキーがそのまま表示され、2回目は正常に表示されます。
開発中は日本語でデバッグし、英語ではローカライズ文字列の確認をする程度だったため、同じコードのまま3回以上ビルドすることがなく気付かなかったのですが、試しに3回以上ビルドしてみると、ローカライズ失敗、成功、失敗、…と繰り返されました(つまり確かに二つのLocalizable.stringsが交互に適用されています)。

ちなみにXcodeのバージョンは4.6(4H127)です。

国際化のための常識なのかもしれませんが、普通に書籍を数冊読んだだけでは知らない知識でした。。。

もしかするとこういった状態になるのはさらに条件があるのかもしれませんが、
同じような事象に遭遇された方の参考になれば幸いです。

2013/04/13

EverForm for iOS

|
iPhoneアプリ『EverForm for iOS』をリリースしました。
https://itunes.apple.com/jp/app/id630680690
Android版を既にリリースしていますが、今回はそのiOS版です。

EverFormは、Evernoteでよく使うノートの形式をフォームとして管理するアプリです。
Evernoteの使い方は様々だと思いますが、Webのクリップだけではなく、毎日何かの記録をするのに使っている人もいるのではないでしょうか。 EverFormは、そんな人におすすめできるアプリです。
  • ノートの書式(見出しなど)を保存しておく
  • ノートの作成時に作成日時を自動的に埋め込む
  • ノートの作成時の保存先ノートブックを指定しておく(*)
  • ノートの作成時に付けるタグを指定しておく(*)
  • チェックボックスを埋め込んでおく(*)
といったことができます。

(*)実は、前述のAndroid版ではまだ対応できていないのですが、近々対応する予定です。
なお、ご利用になるにはEvernoteのアカウントが必要です。

2013/04/06

Android XMLだけでできたボタン

|
画像でなくXMLのみで作ったボタンを集めたAndroid用のライブラリをGitHubに公開しました。
RichButtons
使い方は、RichButtons/libraryをプロジェクトとして取り込むか、中身にある実体のXMLを直接プロジェクトへコピーしていただき、 styleで定義済みのスタイルをButtonに適用します。

ライブラリ、とは言ってもグラデーションなどをlayerで重ねただけXMLを集めただけなのですが、、、 1から作ると意外に時間がかかると思うのでよろしければご利用ください。
通常の状態と「pressed」の状態の2種類が定義されているので、タップするとちゃんと見栄えは変わります。
ちなみに端末画像つきのスクリーンショットは以下で作成したものです。
http://developer.android.com/distribute/promote/device-art.html

2013/02/16

iOS UINavigationBarとステータスバーの高さを除いた画面サイズ

|
UINavigationBarの高さとステータスバーの高さを除いた、実際にコンテンツとして表示できる領域を取得する方法のメモです。 ViewControllerの中に書いています。
availableWidth, availableHeightがちゃんと取れているかどうか、確かめるために少し余白を加えて背景色をつけたUITextViewを表示してみました(iPhone4S)。

Android Fragmentを含む画面遷移のテスト方法(JUnit)

|
Androidの画面遷移の自動テストをする方法として、ActivityInstrumentationTestCase2を使うサンプルを紹介してくださっているブログなどは見かけるのですが、 Fragmentを使った場合のものが見つからなかったのでサンプルを作ってみました。

Fragmentインスタンスの取得方法

ActivityではActivityMonitor#getLastActivity()などでモニタしているActivityのインスタンスを取得できますが、 Fragmentのインスタンスを取得しようとすると、そういったテスト用のメソッドがなく FragmentManager#findFragmentByTag()などで取得するしかなさそうです。

Fragmentの画面遷移のチェック方法

Activityの場合はActivityMonitor#getHits()で呼び出されたかどうかを確認できますが、 Fragmentの場合で考えられるのは以下のようなものでしょうか。
・BackStackの数が期待通りに増減しているか
・findFragmentByTag()で取得できる(=前面にある)Fragmentが期待通りのクラスか