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-scrollable-tab-view
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>
...
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 :)
Düşündüklerin nedir ?
Yorumlar ({{totalCommentCount}})
{{commentLike68Count}} beğenme 6 yıl önce
{{commentLike78Count}} beğenme 6 yıl önce
{{commentLike88Count}} beğenme 5 yıl önce