ユーザーインターフェイス / コンポーネント / TabView

タブビュー

TabViewコンポーネントは、いくつかのタブをタップするか、ビュー間をスワイプすることにより、異なるビュー間をナビゲートする簡単な方法を提供します。 デフォルトでTabViewは、最初のタブのビューをロードしますが、コンポーネントのselectedIndexプロパティを設定することにより、 アプリの起動時に別のタブをロードすることが可能です。

const tabViewModule = require("tns-core-modules/ui/tab-view");
import { TabView, TabViewItem, SelectedIndexChangedEventData } from "tns-core-modules/ui/tab-view";

TabViewコンポーネントの一般的な動作は、オンデマンドでそのアイテムをロードすることです。 これは、表示されるときにすべてのTabViewItemビューがロードされ、表示されなくなるとアンロードされることを意味します。 それぞれ、ビュー間を移動するときにloadedunloadedイベントが発生します。 ただし、各プラットフォーム(iOS および Android)にはいくつかの仕様があり、以下の注釈で説明します。

注釈(iOS固有): iOS実装ではUITabBarControllerを使用します。 つまり、一度にTabViewItemに表示できるのは1つだけで、ロードする必要があるのは1つだけです。 ユーザーが新しいTabViewItemを選択すると、新しいアイテムがロードされ、前のアイテムがアンロードされます。

注釈(Android固有): Android実装ではViewPagerコントロールを使用します。 これにより、swipeジェスチャーを使用して次または前のタブに移動できます。 これは、TabViewItemを1つしか表示できないことを意味しますが、平行して複数のTabViewItemをロードする必要があります。 これを行わないと、スワイプ中に次のTabViewItemコンテンツを見ることができなくなります。 デフォルトでは、ViewPagerコントロールはTabViewItemの左側と右側をプリロードします。 アイテムの1つがすでにプリロードされている場合、それは再びロードされません。 NativeScriptでは、androidOffscreenTabLimitというプロパティを公開しました。 これにより、サイドにプリロードするコンポーネントの数を指定できます (Nativescript 5より前のバージョンを使用し、androidOffscreenTabLimitを0に設定すると、Androidの動作はiOSの動作に一致します)。

タブコントロールに関するiOSとAndroid UXのガイドラインは大きく異なります。違いは以下の点で説明されています。

基本

NativeScriptアプリケーションでTabViewは、XMLを介して配列TabViewItems (基本的にtitleviewiconSourceプロパティを持つオブジェクトの配列)に設定できるプロパティitemsを持ちます。 次の例は、ページにTabViewを追加する方法を示しています。

XML

<TabView id="tabViewContainer">
	<TabViewItem title="First Tab" iconSource="res://icon">
		<StackLayout>
			<Label text="First Tab" textWrap="true" class="m-15 h2 text-left" color="blue" />
		</StackLayout>
	</TabViewItem>
	<TabViewItem title="Second Tab" iconSource="res://icon">
		<StackLayout>
			<Label text="Second Tab" textWrap="true" class="m-15 h2 text-left" color="blue" />
		</StackLayout>
	</TabViewItem>
</TabView>
注釈: TabViewItemiconSourceプロパティを設定したのに、タイトルの横にアイコンが表示されない場合、 アイコンがApp_Resourcesフォルダーに存在しないことが原因である可能性があります。 リソース画像を追加および参照する方法については、画像の操作に関する記事を参照してください。

デモソース


コードビハインド

このサンプルは、コードを介してTabViewを作成する方法を示します

// creating TabView Item content body
const stackLayout0 = new StackLayout();
const label0 = new Label();
label0.text = "Tab 0";
stackLayout0.addChild(label0);

const stackLayout1 = new StackLayout();
const label1 = new Label();
label1.text = "Tab 1";
stackLayout1.addChild(label1);

const tabViewItem0 = new tabViewModule.TabViewItem();
tabViewItem0.title = "Tab 0";
tabViewItem0.view = stackLayout0;

const tabViewItem1 = new tabViewModule.TabViewItem();
tabViewItem1.title = "Tab 1";
tabViewItem1.view = stackLayout1;

// creating TabView
const tabView = new tabViewModule.TabView();
// setting up its items and the selected index
const items = [];
items.push(tabViewItem0);
items.push(tabViewItem1);
tabView.items = items;

tabView.selectedIndex = 1;
// handling selectedIndexChangedEvent
tabView.on(tabViewModule.TabView.selectedIndexChangedEvent, (args) => {
	dialogs.alert(`Selected index has changed ( Old index: ${args.oldIndex} New index: ${args.newIndex})`)
		.then(() => {
			console.log("Dialog closed!");
		});
});
// creating TabView Item content body
const stackLayout0 = new StackLayout();
const label0 = new Label();
label0.text = "Tab 0";
stackLayout0.addChild(label0);

const stackLayout1 = new StackLayout();
const label1 = new Label();
label1.text = "Tab 1";
stackLayout1.addChild(label1);

const tabViewItem0 = new TabViewItem();
tabViewItem0.title = "Tab 0";
tabViewItem0.view = stackLayout0;

const tabViewItem1 = new TabViewItem();
tabViewItem1.title = "Tab 1";
tabViewItem1.view = stackLayout1;

// creating TabView
const tabView = new TabView();
// setting up its items and the selected index
const items = [];
items.push(tabViewItem0);
items.push(tabViewItem1);
tabView.items = items;

tabView.selectedIndex = 1;
// handling selectedIndexChangedEvent
tabView.on(TabView.selectedIndexChangedEvent, (argstv: SelectedIndexChangedEventData) => {
	dialogs.alert(`Selected index has changed ( Old index: ${argstv.oldIndex} New index: ${argstv.newIndex})`)
		.then(() => {
			console.log("Dialog closed!");
		});
});

デモソース


プログラムで異なるTabViewItemビュー間を移動するには、selectedIndexプロパティを使用します。 selectedIndexChangedイベントを使用してユーザー入力ナビゲーションを処理することもできます。 次の例は、実際のシナリオを示しています。

<TabView loaded="onLoaded" selectedIndex="{{tabSelectedIndex}}" selectedIndexChanged="onSelectedIndexChanged">
	<TabViewItem title="Profile">
		<StackLayout>
			<Label text="{{ tabSelectedIndexResult }}" class="h2 m-t-16 text-center" textWrap="true" />
			<Button text="Change Tab" tap="changeTab" class="btn btn-primary btn-active" />
		</StackLayout>
	</TabViewItem>
	<TabViewItem title="Stats">
		<StackLayout>
			<Label text="{{ tabSelectedIndexResult }}" class="h2 m-t-16 text-center" textWrap="true" />
			<Button text="Change Tab" tap="changeTab" class="btn btn-primary btn-active" />
		</StackLayout>
	</TabViewItem>
	<TabViewItem title="Settings">
		<StackLayout>
			<Label text="{{ tabSelectedIndexResult }}" class="h2 m-t-16 text-center" textWrap="true" />
			<Button text="Change Tab" tap="changeTab" class="btn btn-primary btn-active" />
		</StackLayout>
	</TabViewItem>
</TabView>
function onLoaded(args) {
	const tabView = args.object;
	const vm = new observableModule.Observable();
	vm.set("tabSelectedIndex", 0);
	vm.set("tabSelectedIndexResult", "Profile Tab (tabSelectedIndex = 0 )");

	tabView.bindingContext = vm;
}

function changeTab(args) {
	const vm = args.object.bindingContext;
	const tabSelectedIndex = vm.get("tabSelectedIndex");
	if (tabSelectedIndex === 0) {
		vm.set("tabSelectedIndex", 1);
	} else if (tabSelectedIndex === 1) {
		vm.set("tabSelectedIndex", 2);
	} else if (tabSelectedIndex === 2) {
		vm.set("tabSelectedIndex", 0);
	}
}
// displaying the old and new TabView selectedIndex
function onSelectedIndexChanged(args) {
	if (args.oldIndex !== -1) {
		const newIndex = args.newIndex;
		const vm = args.object.bindingContext;
		if (newIndex === 0) {
			vm.set("tabSelectedIndexResult", "Profile Tab (tabSelectedIndex = 0 )");
		} else if (newIndex === 1) {
			vm.set("tabSelectedIndexResult", "Stats Tab (tabSelectedIndex = 1 )");
		} else if (newIndex === 2) {
			vm.set("tabSelectedIndexResult", "Settings Tab (tabSelectedIndex = 2 )");
		}
		dialogs.alert(`Selected index has changed ( Old index: ${args.oldIndex} New index: ${args.newIndex} )`)
			.then(() => {
				console.log("Dialog closed!");
			});
	}
}
exports.onLoaded = onLoaded;
exports.changeTab = changeTab;
exports.onSelectedIndexChanged = onSelectedIndexChanged;
export function onLoaded(args) {
	const tabView: TabView = <TabView>args.object;
	const vm = new Observable();
	vm.set("tabSelectedIndex", 0);
	vm.set("tabSelectedIndexResult", "Profile Tab (tabSelectedIndex = 0 )");

	tabView.bindingContext = vm;
}

export function changeTab(args) {
	const vm = args.object.bindingContext;
	const tabSelectedIndex = vm.get("tabSelectedIndex");
	if (tabSelectedIndex === 0) {
		vm.set("tabSelectedIndex", 1);
	} else if (tabSelectedIndex === 1) {
		vm.set("tabSelectedIndex", 2);
	} else if (tabSelectedIndex === 2) {
		vm.set("tabSelectedIndex", 0);
	}
}
// displaying the old and new TabView selectedIndex
export function onSelectedIndexChanged(args: SelectedIndexChangedEventData) {
	if (args.oldIndex !== -1) {
		const newIndex = args.newIndex;
		const vm = (<TabView>args.object).bindingContext;
		if (newIndex === 0) {
			vm.set("tabSelectedIndexResult", "Profile Tab (tabSelectedIndex = 0 )");
		} else if (newIndex === 1) {
			vm.set("tabSelectedIndexResult", "Stats Tab (tabSelectedIndex = 1 )");
		} else if (newIndex === 2) {
			vm.set("tabSelectedIndexResult", "Settings Tab (tabSelectedIndex = 2 )");
		}
		dialogs.alert(`Selected index has changed ( Old index: ${args.oldIndex} New index: ${args.newIndex} )`)
			.then(() => {
				console.log("Dialog closed!");
			});
	}
}

デモソース


Androidにおけるオフスクリーンタブ制限

androidOffscreenTabLimitプロパティを使用して、Androidでプリロードされるサイドタブの数を設定します。デフォルト値は1です。

XML

<TabView id="tabViewContainer" androidOffscreenTabLimit="0">
	<TabViewItem title="First Tab" iconSource="res://icon">
		<StackLayout>
			<Label text="First Tab" textWrap="true" class="m-15 h2 text-left" color="blue" />
		</StackLayout>
	</TabViewItem>
	<TabViewItem title="Second Tab" iconSource="res://icon">
		<StackLayout>
			<Label text="Second Tab" textWrap="true" class="m-15 h2 text-left" color="blue" />
		</StackLayout>
	</TabViewItem>
</TabView>

デモソース


スタイリング

TabViewコンポーネントには、次のユニークなスタイリングのプロパティがあります。

XML

<TabView selectedTabTextColor="white"
		 tabBackgroundColor="orangered"
		 tabTextFontSize="16"
		 androidSelectedTabHighlightColor="green">
	<TabViewItem title="First tab" iconSource="res://icon" textTransform="capitalize">
		<StackLayout>
			<Label text="First Tab" textWrap="true" class="m-15 h2 text-center" color="blue" />
		</StackLayout>
	</TabViewItem>
	<TabViewItem title="Second tab" iconSource="res://icon" textTransform="capitalize">
		<StackLayout>
			<Label text="Second Tab" textWrap="true" class="m-15 h2 text-center" color="blue" />
		</StackLayout>
	</TabViewItem>
</TabView>

デモソース


Androidにおけるタブの位置

androidTabsPositionプロパティを使用して、Androidのタブの位置を変更します。デフォルト値はtopです。

XML

<TabView id="tabViewContainer" androidTabsPosition="bottom">
	<TabViewItem title="First Tab" iconSource="res://icon">
		<StackLayout>
			<Label text="First Tab" textWrap="true" class="m-15 h2 text-left" color="blue" />
		</StackLayout>
	</TabViewItem>
	<TabViewItem title="Second Tab" iconSource="res://icon">
		<StackLayout>
			<Label text="Second Tab" textWrap="true" class="m-15 h2 text-left" color="blue" />
		</StackLayout>
	</TabViewItem>
</TabView>

デモソース


タイトルアイコンフォント

この例は、TabViewアイテムのタイトルにアイコンフォントを使用する方法を示しています。 アプリでアイコンフォントを追加および使用する方法の詳細については、アイコンフォントの記事を参照してください。

XML

<TabView id="tabViewContainer" class="icon">
<TabViewItem title="&#xe913;">
	<StackLayout>
		<Label text="First TabView item with Icon Font" textAlignment="center" textWrap="true" class="h2 m-x-auto" color="blue" />
		<Label text="&#xe913;" textWrap="true" class="h2 m-x-auto" color="blue" />
	</StackLayout>
</TabViewItem>
<TabViewItem title="&#xe908;">
	<StackLayout>
		<Label text="Second TabView item with Icon Font" textAlignment="center" textWrap="true" class="h2 m-x-auto" color="green" />
		<Label text="&#xe908;" textWrap="true" class="h2 m-x-auto" color="green" />
	</StackLayout>
</TabViewItem>
</TabView>

CSS

.icon{
	font-family: 'icomoon';
}

デモソース


APIリファレンス

名前タイプ
TabViewClass

ネイティブコンポーネント

ANDROIDIOS
androidx.viewpager.widget.ViewPager UITabBarController
入門

コアコンセプト

ユーザーインターフェース

ツール

ハードウェアアクセス

プラグインの開発

リリース

アプリテンプレート

パフォーマンスの最適化

フレームワークモジュール

ガイド

サポートを受ける

トラブルシューティング

Siedkick