React Native Tabs Kullanımı (Sekmeleme)

react-nativeyoutube

2 yıl önce 3 yorum

React nativede tabs kullanmak için güzel yöntemler var. Kendimiz animasyonlu şeklinde oluşturabiliriz veya topluluk tarafından geliştirilen elementleri kullanarak oluşturabiliriz. Ben tabii ki topluluğa güvenen birisi olarak karşıma çıkan iki tür tabs'dan bahsedeyim. bunlar :

react-native-elements

react-native-scrollable-tab-view

react-native-elements

Bu community çeşitli elementleri barındırıyor. Butonlar, side menu, list elementleri vb.  ve oluşturduğunuz bir issue cevaplanıyor ve yaklaşık 1,2 hafta içinde güncellenebiliyor. Ben örnek olarak SearchBar elementinin kapatma veya silme butonunun olmadığını bu adreste söyledim ve element özelliğini eklediler. Ben her zaman aktif toplulukları tercih ederim size de tavsiye ederim. Buradaki elemenler hakkında soru sormak istiyorsanız bir issue başlatıp ve beni @abdurrahmanekr şeklinde etiketleyerek haberdar etmeniz yeterli :).

Neyse, buradaki tabs özelliğinden bahsedelim. İlk önce react-native-elements'i kurmamız gerekiyor. toplam iki adımda iş tamamlanıyor.

// react native elements'in kullandığı icon gurubu
npm i react-native-vector-icons --save && react-native link react-native-vector-icons

// react native elements'in kendisi
npm i react-native-elements --save

Artık kurulum başarılı olduğuna göre tabs özelliğini react-native-login-uygulaması serisindeki yapıdaki gibi main-page.js'de kullanalım.

Basit bir örnek ise main-page.js

import React, { Component } from 'react';

import { Tabs, Tab, Icon } from 'react-native-elements' // kütüphane dahil edildi

import {
	Text,
	View
} from 'react-native';

export default class MainPage extends Component {

	constructor(props) {
		super(props);

		this.state = {
			selectedTab: 'news'
		};
	}

	changeTab (selectedTab) {
	  this.setState({selectedTab})
	}

	render() {
		const { selectedTab } = this.state
		return(

			<Tabs>
				<Tab
				titleStyle={{fontWeight: 'bold', fontSize: 10}}
				selectedTitleStyle={{marginTop: -1, marginBottom: 6}}
				selected={selectedTab === 'news'}
				title={selectedTab === 'news' ? 'Haber Kaynağı' : null}
				renderIcon={() => <Icon containerStyle={{justifyContent: 'center', alignItems: 'center', marginTop: 12}} color={'#5e6977'} name='whatshot' size={33} />}
    			renderSelectedIcon={() => <Icon color={'#6296f9'} name='whatshot' size={30} />}
				onPress={() => this.changeTab('news')}>
					<View>
						<Text>Burası haber kaynağı</Text>
					</View>
				</Tab>
				<Tab
				titleStyle={{fontWeight: 'bold', fontSize: 10}}
				selectedTitleStyle={{marginTop: -1, marginBottom: 6}}
				selected={selectedTab === 'profile'}
				title={selectedTab === 'profile' ? 'Profil' : null}
				renderIcon={() => <Icon containerStyle={{justifyContent: 'center', alignItems: 'center', marginTop: 12}} color={'#5e6977'} name='person' size={33} />}
    			renderSelectedIcon={() => <Icon color={'#6296f9'} name='person' size={30} />}
				onPress={() => this.changeTab('profile')}>
					<View>
						<Text>Burası profil	</Text>
					</View>
				</Tab>
			</Tabs>
		);
	}
}

Bu içindeki özelliklerden kısaca bahsedecek olursak. 

titleStyle: başlık sitili
selectedTitleStyle: seçili olduğu zaman başlık sitili
selected: seçili olması için gereken şart
title: başlık
renderIcon: eğer tablara ikon eklemek isterseniz içine eklenecek ikon
renderSelectedIcon: şeçili olduğunda değişecek ikon

Bu tab'ın basit bir özelliği var eğer siz her sayfa için sürekli tab oluşturmak istemiyorsanız. pages/main-page/tabs diye bir klasör oluşturup bu klasörün içine eklemek istediğiniz sayfaları barındırabilirsiniz. Örneğin haber kaynağı sayfasını tabs altından isteyelim. pages/main-page/tabs/news-tab.js

import React, { Component } from 'react';

import {
	Text,
	View
} from 'react-native';

export default class NewsTab extends Component {

	constructor(props) {
		super(props);
	}

	render() {
		return (
			<View>
				<Text>Burası news</Text>
			</View>
		);
	}
}

main-page.js'e dahil etmek için ise yapmam gereken:

...
import NewsTab from './tabs/news-tab'; // dahil edip
...

renderSelectedIcon={() => <Icon color={'#6296f9'} name='whatshot' size={30} />}
onPress={() => this.changeTab('news')}>
	<NewsTab/> // buraya ekliyoruz
</Tab>
...

react-native-scrollable-tab-view

Bu kütüphane yine topluluk tarafından yazıldı ve desteği fazla. İlk önce react-native-scrollable-tab-view'i kurmamız gerekiyor. Bunda toplam 1 adımda iş tamamlanıyor.

npm install react-native-scrollable-tab-view --save

Kütüphane kuruldu ve uyguladığımızda main-page.js

import React, { Component } from 'react';

import ScrollableTabView from 'react-native-scrollable-tab-view'; // dahil ediyoruz

import {
	Text,
	View,
	TouchableOpacity
} from 'react-native';

import NewsTab from './tabs/news-tab';

export default class MainPage extends Component {

	constructor(props) {
		super(props);
	}

	render() {
		return(
			<ScrollableTabView>
				<Text tabLabel='Haber Kaynağı'>Haber Kaynağı</Text>
				<Text tabLabel='Profil'>Profil</Text>
			</ScrollableTabView>
		);
	}
}

Bunu diğerinden ayıran en önemli özellik animasyonlu bir şekilde değişmesi ve ekranı kaydırarak değişmesi. Eğer önceki gibi bunu da NewsTab şeklinde çağırmak istersek. Aynı şekilde dahil ederek yaparız ör:

...
import NewsTab from './tabs/news-tab'; // dahil edip
...
<ScrollableTabView>
	<NewsTab tabLabel='Haber kaynağı'/>
	<Text tabLabel='Profil'>Profil</Text>
</ScrollableTabView>
...

Yalnız burada dikkat edilmesi gereken konu herhangi bir tab değişiktiğinde farkedemiyoruz, bunu önlemek için onChangeTab kullanmalıyız. ör:

...
<ScrollableTabView
	onChangeTab={() => {
		Alert.alert('değişti')
	}}>
	<NewsTab tabLabel='Haber kaynağı'/>
	<Text tabLabel='Profil'>Profil</Text>
</ScrollableTabView>
...

Değiştiğinde otomatik çalışır. Bu tür işlemleri sayfalarındaki dokümanlarda bulabilirsiniz. Eğer biz yazı yerine ikon eklemek istersek ? zurnanın zırt dediği yer :D. Kendisi için yaptığı DefaultTabBar diye bir yapısı var siz bunu şekillendirerek renderTabBar propery'sine eklemeniz gerekiyor. Ben facebook için yaptıkları örneğin ismini değiştirerek CustomTabBar şeklinde pages/main-page/tabs/custom-tab-bar.js diye kaydediyorum oda şöyle : 

import React from 'react';
import {
	StyleSheet,
	Text,
	View,
	TouchableOpacity,
} from 'react-native';
import Icon from 'react-native-vector-icons/Ionicons'; // icon kütüphanesi

const CustomTabBar = React.createClass({
	tabIcons: [],

	propTypes: {
		goToPage: React.PropTypes.func,
		activeTab: React.PropTypes.number,
		tabs: React.PropTypes.array,
	},

	componentDidMount() {
		this._listener = this.props.scrollValue.addListener(this.setAnimationValue);
	},

	setAnimationValue({ value, }) {
		this.tabIcons.forEach((icon, i) => {
			const progress = Math.min(1, Math.abs(value - i))
			icon.setNativeProps({
				style: {
					color: this.iconColor(progress),
				},
			});
		});
	},

	//color between rgb(59,89,152) and rgb(204,204,204)
	iconColor(progress) {
		const red = 59 + (204 - 59) * progress;
		const green = 89 + (204 - 89) * progress;
		const blue = 152 + (204 - 152) * progress;
		return `rgb(${red}, ${green}, ${blue})`;
	},

	render() {
		return <View style={[styles.tabs, this.props.style, ]}>
			{this.props.tabs.map((tab, i) => {
				return <TouchableOpacity key={tab} onPress={() => this.props.goToPage(i)} style={styles.tab}>
					<Icon
						name={tab}
						size={30}
						color={this.props.activeTab === i ? 'rgb(59,89,152)' : 'rgb(204,204,204)'}
						ref={(icon) => { this.tabIcons[i] = icon; }}
					/>
				</TouchableOpacity>;
			})}
		</View>;
	},
});

const styles = StyleSheet.create({
	tab: {
		flex: 1,
		alignItems: 'center',
		justifyContent: 'center',
		paddingBottom: 10,
	},
	tabs: {
		height: 45,
		flexDirection: 'row',
		paddingTop: 5,
		borderWidth: 1,
		borderTopWidth: 0,
		borderLeftWidth: 0,
		borderRightWidth: 0,
		borderBottomColor: 'rgba(0,0,0,0.05)',
	},
});

export default CustomTabBar;

Böyle size kod yazdırmak zorunda kalıyor ama topluluk bu konuyla ilglili ne yapar bilmiyorum. İsterseniz bir issue oluşturup bunu sorabilirsiniz. Şimdi oluşturduğumuz tabBar'ı main-page.js' e dahil edelim kısaca: 

...
import NewsTab from './tabs/news-tab';
import CustomTabBar from './tabs/custom-tab-bar';
...
<ScrollableTabView
	renderTabBar={() => <CustomTabBar/>}>
	<NewsTab tabLabel='ios-paper'/>
	<Text tabLabel='ios-person'>Profil</Text>
</ScrollableTabView>
...

Artık ikonlu bir şekilde kullanabiliyoruz. topLabel içinde yazdığımız değer ikonlarımızın ismi oluyor.

Bugün anlatacaklarım bu kadardı aklınıza takılan bir soru olursa çekinmeyin. Eğer bu konu hakkında veya konu dışı olarak bana soru sormak istiyorsanız https://github.com/abdurrahmanekr/bana-istedigini-sor repository'sinde bir issue açabilirsiniz. Youtube kanalıma abone olarak ve yayınladığım bu makaleyi paylaşarak bana destek olabilirsiniz. Diğer makalelerde görüşmek üzere :)

Yorumlar ({{totalCommentCount}})

  • RN-HelloWorld

    {{commentLike68Count}} beğenme 1 yıl önce

    Gayet faydalı bir paylaşım olmuş. İşime yaradı açıkcası. Seçim yapmak için iki güzel library i önerisi .
    Beğen Beğendin
  • Anonim

    {{commentLike78Count}} beğenme 1 yıl önce

    Makale icin teşekkürler. React native ile ilgili nice yazilariniz olması temennisiyle.
    Beğen Beğendin
  • dev11

    {{commentLike88Count}} beğenme 8 ay önce

    Merhaba, react-native-elements kütüphanesinde Tabs ve Tab componentleri bulunmuyor. Bunların yerine ne kullanabiliriz?
    Beğen Beğendin
  • Düşündüklerin nedir ?

    Abdurrahman Eker

    (1010 Eylül 11111001100)

  • Full Stack Developer at Detaysoft Turkey/Sivas
  • İnternette Avare Kodcu
  • github
  • linkedin
  • youtube
  • Yeni içeriklerden haberdar olmak ister misin ?