RubotoでActionBar上にTabが表示されるかを試してみたときのメモ。
■環境
Platform | JDK | ant | Ruby | ruboto | jruby-jars | Device | API level |
---|---|---|---|---|---|---|---|
Windows7 x64 | 1.7.0_25 | 1.9.1 | RubyInstaller 1.9.3-p448 | 0.13.0 | 1.7.4 | Nexus7 2012 | android-17 |
■注意
前回 同様、初回起動時にActionBar上にあるタブがうまく動作しません。
■アプリの動き
- ActionBar上に2つのタブが表示される
- 「TAB1」をタップすると、「Fragment1」が表示される
- 「TAB2」をタップすると、「Fragment2」が表示される
- 同じタブをタップすると、「tab reselected」とtoast表示される
■アプリの生成
以下のコマンドでJRubyを含めて生成します。また、前回同様、メモリサイズの変更などを行なっておきます。
ruboto gen app --package com.example.tab --target android-17 --with-jruby
■レイアウト用xmlの作成
メイン画面のレイアウト
tab\res\layout\main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_gravity="center"> <LinearLayout android:id="@+id/fragment_container" android:layout_width="match_parent" android:layout_height="match_parent" > </LinearLayout> </LinearLayout>
TAB1を選択した時に表示される、Fragment1のレイアウト
tab\res\layout\fragment1.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:id="@+id/textView1" android:text="Fragment A" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout>
TAB2を選択した時に表示される、Fragment2のレイアウト
tab\res\layout\fragment2.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:id="@+id/textView2" android:text="Fragment B" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout>
■Activityの修正
参考にしたサイト
以下のJavaでの実装例を参考にして、Rubyのコードを書きました。
- スマートフォン端末で、アクションバーにタブを表示する « Tech Booster
- [Android 4] ActionBar with Tabs example | Arvid's Blog
- android - Implementing action bar tabs with fragments - Stack Overflow
Web上では、fragmentを Fragment.instantiate というメソッドで生成する例をよく見かけました。
ただ、Rubotoでやろうとすると第二引数の指定がうまくいきませんでした(以下が試してみてうまくいかなかった例)。
Fragmentの onCreateView メソッド名
Activityの on_create のように、メソッド名をスネークケースにしたところ、エラーで動作しませんでした。
Javaと同じようにキャメルケースとしたところ、問題なく動作しました。
参考:JRubyで継承元のメソッドをオーバーライドする場合は、メソッド名をアンスコ区切りに変えてはいけない - k-yamadaのブログ
ソース
require 'ruboto/widget' require 'ruboto/util/toast' java_import 'android.app.ActionBar' java_import 'android.app.Fragment' class TabActivity def onCreate(bundle) super self.setContentView(Ruboto::R::layout::main) ab = getActionBar() ab.setNavigationMode(ActionBar::NAVIGATION_MODE_TABS) ab.addTab(ab.newTab().setText("tab1").setTabListener(TabListener.new(self, Fragment1.new()))) ab.addTab(ab.newTab().setText("tab2").setTabListener(TabListener.new(self, Fragment2.new()))) end end class TabListener # toastを使うため、activityを渡している def initialize(activity, fragment) @activity = activity @fragment = fragment end def onTabReselected(tab, fragment_transaction) @activity.toast "tab reselected" end def onTabSelected(tab, fragment_transaction) fragment_transaction.replace(Ruboto::R::id::fragment_container, @fragment) end def onTabUnselected(tab, fragment_transaction) fragment_transaction.remove(@fragment) end end class Fragment1 < Fragment def onCreateView(inflater, container, bundle) return inflater.inflate(Ruboto::R::layout::fragment1, container, false) end end class Fragment2 < Fragment def onCreateView(inflater, container, bundle) return inflater.inflate(Ruboto::R::layout::fragment2, container, false) end end