こんにちは。エクセルソフトの田淵です。
Android でタブ的なページを表示するにはいくつかの方法があります。
今回はそのうちの最もベーシックでかつ古の技術の ActionBar の Tabbed Layouts を使ってみます。
ActionBar.Tab
クラスは API 21 から非推奨になっていますので、ご注意ください。代替はTabLayout
クラスです。(後日執筆予定)
サンプル:
https://developer.xamarin.com/samples/monodroid/UserInterface/ActionBarTabs/
前提
API 11(Android 3.0)以上。それ以下用には Support Library v7 で同様の機能が提供されています。
各タブのページは Fragment で実装されます。
ActionBar にタブを追加する
最初に書き換える元の空のレイアウトを用意します。
<?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:minWidth="25px" android:minHeight="25px"> <FrameLayout android:minWidth="25px" android:minHeight="25px" android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/container" /> </LinearLayout>
@+id/container
をコードで書き換えることになりますので、ID を覚えておきます。
続いて Activity の処理を追加します。
UI を初期化する前に、ActionBar
の NavigationMode
を設定しないといけません。
ActionBar.NavigationMode = ActionBarNavigationMode.Tabs; SetContentView(Resource.Layout.Main);
その上で、例えば次のように ActionBar.Tab
のインスタンスに ActionBar.NewTab()
メソッドでタブを追加します。
ActionBar.Tab tab = ActionBar.NewTab(); tab.SetText("Tab 1"); tab.SetIcon(Resource.Drawable.tab1_icon); tab.TabSelected += (sender, e) => { e.FragmentTransaction.Replace(Resource.Id.container, new FirstFragment()); }; ActionBar.AddTab(tab); tab = ActionBar.NewTab(); tab.SetText("Tab 2"); tab.SetIcon(Resource.Drawable.tab2_icon); tab.TabSelected += (sender, e) => { e.FragmentTransaction.Replace(Resource.Id.container, new SecondFragment()); }; ActionBar.AddTab(tab);
ここでは、ActionBar.Tab
クラスの TabSelected
イベントを使用して処理を書いていますが、その場合は FragmentTransaction.Replace(int containerViewId, Fragment fragment, string tag);
メソッドを使って Fragment を書き換えます。第一引数の containerViewId
が元の View(上記で container
で指定したやつ)で、第二引数は置き換える Fragment です。
Java での標準の書き方のように、クラスに ActionBar.ITabListener
の継承を追加することもできます。その場合は以下の 3つのメソッドのオーバーライドが必要です。
- OnTabSelected - このメソッドはユーザーがタブを選択したときに呼ばれます。Fragment を表示する処理が必要です。
- OnTabReselected - このメソッドはタブがすでに選択されているけど再度選択されたときに呼ばれます。このコールバックでは一般的に Fragment をリフレッシュやアップデートする処理を行います。
- OnTabUnselected - このメソッドはユーザーが他のタブを選択したときに呼ばれます。このコールバックでは表示されている Fragment が非表示になる前にステートを保存したりします。
複数のタブで同じような機能を利用する場合などはこちらの方が良いでしょう。
例えば次のような書き方になります。(Xamarin のドキュメントそのままですけど)
[Activity(Label = "@string/app_name", Theme = "@style/Theme.AppCompat", MainLauncher = true, Icon = "@drawable/ic_launcher")] public class MainActivity : ActionBarActivity, ActionBar.ITabListener { static readonly string Tag = "ActionBarTabsSupport"; public void OnTabReselected(ActionBar.Tab tab, FragmentTransaction ft) { // Optionally refresh/update the displayed tab. Log.Debug(Tag, "The tab {0} was re-selected.", tab.Text); } public void OnTabSelected(ActionBar.Tab tab, FragmentTransaction ft) { // Display the fragment the user should see Log.Debug(Tag, "The tab {0} has been selected.", tab.Text); } public void OnTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) { // Save any state in the displayed fragment. Log.Debug(Tag, "The tab {0} as been unselected.", tab.Text); } protected override void OnCreate(Bundle bundle) { base.OnCreate(bundle); SupportActionBar.NavigationMode = ActionBar.NavigationModeTabs; SetContentView(Resource.Layout.Main); } void AddTabToActionBar(int labelResourceId, int iconResourceId) { ActionBar.Tab tab = SupportActionBar.NewTab() .SetText(labelResourceId) .SetIcon(iconResourceId) .SetTabListener(this); SupportActionBar.AddTab(tab); } }
Fragment を用意する
Xamarin のサンプル では、「Fragments.cs」ファイルに Fragment の処理を纏めていますね。
Tab1 のレイアウトを用意してみます。Button が一個だけのシンプルなやつです。
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:text="Button" android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/tab1button" /> </LinearLayout>
前の章で最初のタブは Tab1 と指定していますので、以下の FirstFragment
クラスが呼ばれます。
public class FirstFragment : Fragment { public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.Inflate(Resource.Layout.Tab1, null); var button = view.FindViewById<Button>(Resource.Id.tab1button); button.Click += (sender, e) => { Toast.MakeText(inflater.Context, $"{button.Text} button is Clicked", ToastLength.Short).Show(); }; return view; } }
Activity の OnCreate
のように普通に記述すれば良いのですが、View を指定するのは inflater.Inflate
の引数に Resource Id を指定します。また、Context や Activity(古い書き方?)を指定する場合がある時は、inflater.Context
で取得する点に注意してください。
最後に view を return すればタブが表示されるはずです。
次のエントリーでは、Tab Layout を触ってみたいと思います。
Xamarin 気になった方は
Visual Studio 2017 をインストールして触ってみてください。手順書は こちらのエントリー をご覧ください。 学習用リソース や JXUG リンクページ に参考資料を纏めてますので併せてどうぞ。
Xamarin の導入支援サービスを始めました。ベースは基本的なアプリを一緒に作ることで Xamarin を使えるようになって頂く内容ですが、ご要望に応じて講習内容のカスタマイズも可能です。詳しくは田淵までお問い合わせください(^^)
Xamarin 有償トレーニング : XLsoft エクセルソフト
Xamarin の情報が欲しい方はこのブログも購読いただいたり、私のTwitterアカウントをフォローいただいたりすると嬉しいです。
私が所属している エクセルソフト の宣伝を少しさせてください。弊社は開発者向けの様々なソフトウェアを扱っています。おなじみの ReSharper (JetBrains)、 や Atlassian の JIRA, Confluence、Office/PDF ファイルを .NET/Java で操作するライブラリ Aspose(アスポーズ)、Windows アプリ、Web ページ、iOS/Android アプリの UI テストができる TestComplete などお勧めです(^^) また、Visual Studio Professional/Enterprise with MSDN も販売してますし、日本で売っていない海外のソフトウェア、開発ツールなどを弊社経由で日本円で購入頂くことも可能です。ご興味あれば 弊社ページ を覗いてみてください。
以上です。