Closed vinhnvfabbi closed 5 years ago
@vinhnvfabbi you can custom renderIndicator
to make exactly the same what you want.
If you need a tab width, you can use this function to get it getTabWidth
I'm trying to custom indicator like the picture below but I have a problem is the indicator lose animation and it doesn't work when I press on the second tab :'( , what should I do now ? please help
can you share your code,really like it
I'm trying to custom indicator like the picture below but I have a problem is the indicator lose animation and it doesn't work when I press on the second tab :'( , what should I do now ? please help
can you share your code,really like it
you can check this https://github.com/BunHouth/RNTabExample/blob/feature/indicator-gradient/Home.js#L41
it similar to that images
I'm trying to custom indicator like the picture below but I have a problem is the indicator lose animation and it doesn't work when I press on the second tab :'( , what should I do now ? please help
can you share your code,really like it
you can check this https://github.com/BunHouth/RNTabExample/blob/feature/indicator-gradient/Home.js#L41
it similar to that images
thanks very much!
I'm trying to custom indicator like the picture below but I have a problem is the indicator lose animation and it doesn't work when I press on the second tab :'( , what should I do now ? please help
can you share your code,really like it
you can check this https://github.com/BunHouth/RNTabExample/blob/feature/indicator-gradient/Home.js#L41
it similar to that images
import React, { Component, useEffect, useRef } from 'react'; import { StyleSheet, Dimensions, Animated, Text, View } from 'react-native'; import { TabView, SceneMap, TabBar } from 'react-native-tab-view'; import Icon from 'react-native-vector-icons/MaterialCommunityIcons'; import LinearGradient from "react-native-linear-gradient"; import MyApplication from '../../components/MyApplication'; import Shop from '../../components/Shop'; import _ from "lodash"; import { ButtonGroup } from 'react-native-elements'
const styles = StyleSheet.create({ tabView: { backgroundColor: 'white', }, tabbar: { backgroundColor: 'white', overflow: 'hidden', // height: 50, marginBottom: 10, elevation: 0, shadowColor: 'white', shadowOpacity: 0, shadowRadius: StyleSheet.hairlineWidth, shadowOffset: { height: 0, width: 0, }, marginLeft: 10 }, tabStyle: { flexDirection: 'row', color: '#263238', width: 'auto', // borderWidth: 1, // borderColor: 'black', // borderRadius: 50, // paddingLeft: 20, // paddingRight: 20, }, labelStyle: { color: '#263238', fontSize: 16, }, // indicatorStyle: { // backgroundColor: 'black' // }, fn: { position: 'absolute', right: 0, top: 0, flexDirection: 'row' } });
const TabIndicator = props => { const { width, tabWidth, index } = props; const marginLeftRef = useRef(new Animated.Value(index ? tabWidth : 0)) .current; useEffect(() => { Animated.timing(marginLeftRef, { toValue: tabWidth, duration: 400 }).start(); }, [tabWidth]);
return (
<Animated.View
style={{
justifyContent: "flex-end",
alignItems: "center",
flex: 1,
width: width,
marginLeft: marginLeftRef
}}
>
<LinearGradient
start={{ x: 0, y: 0 }}
end={{ x: 1, y: 0 }}
colors={["#50b0ea", "#80a2ed", "#a797f2", "#e981f4"]}
style={{ height: 2, width: "100%" }}
/>
</Animated.View>
);
}
class Application extends Component {
constructor(props) {
super(props)
this.state = {
index: 0,
routes: [
{
key: 'MyApplication',
title: 'My App',
icon: 'view-compact-outline',
color: [244, 67, 54]
},
{
key: 'Shop',
title: 'Store',
icon: 'store',
color: [244, 67, 54]
},
],
}
}
renderIndicator = ({ getTabWidth }) => {
const tabWidth = _.sum([...Array(this.state.index).keys()].map(i => getTabWidth(i)));
return (
<TabIndicator
width={getTabWidth(this.state.index)}
tabWidth={tabWidth}
index={this.state.index}
/>
);
}
renderScene = SceneMap({
MyApplication,
Shop
});
renderIcon = ({ route, color, size }) => (
<Icon
type='material-community'
name={route.icon}
size={25}
color='#263238'
/>
);
renderLabel = ({ route, focused, color }) => (
<Text
style={styles.labelStyle}>
{route.title}
</Text>
)
renderTabBar = props => (
<TabBar
{...props}
renderIcon={this.renderIcon}
style={styles.tabbar}
labelStyle={styles.labelStyle}
tabStyle={styles.tabStyle}
indicatorStyle={styles.indicatorStyle}
/>
);
render() {
const { selectedIndex } = this.state
return (
<TabView
style={styles.tabView}
lazy
navigationState={this.state}
renderScene={this.renderScene}
renderTabBar={this.renderTabBar}
renderIndicator={this.renderIndicator}
onIndexChange={index => this.setState({ index })}
// initialLayout={{ width: Dimensions.get('window').width }}
/>
);
}
}
export default Application;
not work ,is any mistake?
I'm trying to custom indicator like the picture below but I have a problem is the indicator lose animation and it doesn't work when I press on the second tab :'( , what should I do now ? please help
can you share your code,really like it
you can check this https://github.com/BunHouth/RNTabExample/blob/feature/indicator-gradient/Home.js#L41 it similar to that images
import React, { Component, useEffect, useRef } from 'react'; import { StyleSheet, Dimensions, Animated, Text, View } from 'react-native'; import { TabView, SceneMap, TabBar } from 'react-native-tab-view'; import Icon from 'react-native-vector-icons/MaterialCommunityIcons'; import LinearGradient from "react-native-linear-gradient"; import MyApplication from '../../components/MyApplication'; import Shop from '../../components/Shop'; import _ from "lodash"; import { ButtonGroup } from 'react-native-elements'
const styles = StyleSheet.create({ tabView: { backgroundColor: 'white', }, tabbar: { backgroundColor: 'white', overflow: 'hidden', // height: 50, marginBottom: 10, elevation: 0, shadowColor: 'white', shadowOpacity: 0, shadowRadius: StyleSheet.hairlineWidth, shadowOffset: { height: 0, width: 0, }, marginLeft: 10 }, tabStyle: { flexDirection: 'row', color: '#263238', width: 'auto', // borderWidth: 1, // borderColor: 'black', // borderRadius: 50, // paddingLeft: 20, // paddingRight: 20, }, labelStyle: { color: '#263238', fontSize: 16, }, // indicatorStyle: { // backgroundColor: 'black' // }, fn: { position: 'absolute', right: 0, top: 0, flexDirection: 'row' } });
const TabIndicator = props => { const { width, tabWidth, index } = props; const marginLeftRef = useRef(new Animated.Value(index ? tabWidth : 0)) .current; useEffect(() => { Animated.timing(marginLeftRef, { toValue: tabWidth, duration: 400 }).start(); }, [tabWidth]);
return ( <Animated.View style={{ justifyContent: "flex-end", alignItems: "center", flex: 1, width: width, marginLeft: marginLeftRef }} > <LinearGradient start={{ x: 0, y: 0 }} end={{ x: 1, y: 0 }} colors={["#50b0ea", "#80a2ed", "#a797f2", "#e981f4"]} style={{ height: 2, width: "100%" }} /> </Animated.View> );
}
class Application extends Component {
constructor(props) { super(props) this.state = { index: 0, routes: [ { key: 'MyApplication', title: 'My App', icon: 'view-compact-outline', color: [244, 67, 54] }, { key: 'Shop', title: 'Store', icon: 'store', color: [244, 67, 54] }, ], } } renderIndicator = ({ getTabWidth }) => { const tabWidth = _.sum([...Array(this.state.index).keys()].map(i => getTabWidth(i))); return ( <TabIndicator width={getTabWidth(this.state.index)} tabWidth={tabWidth} index={this.state.index} /> ); } renderScene = SceneMap({ MyApplication, Shop }); renderIcon = ({ route, color, size }) => ( <Icon type='material-community' name={route.icon} size={25} color='#263238' /> ); renderLabel = ({ route, focused, color }) => ( <Text style={styles.labelStyle}> {route.title} </Text> ) renderTabBar = props => ( <TabBar {...props} renderIcon={this.renderIcon} style={styles.tabbar} labelStyle={styles.labelStyle} tabStyle={styles.tabStyle} indicatorStyle={styles.indicatorStyle} /> ); render() { const { selectedIndex } = this.state return ( <TabView style={styles.tabView} lazy navigationState={this.state} renderScene={this.renderScene} renderTabBar={this.renderTabBar} renderIndicator={this.renderIndicator} onIndexChange={index => this.setState({ index })} // initialLayout={{ width: Dimensions.get('window').width }} /> ); }
}
export default Application;
not work ,is any mistake?
can you just show the error? did you able to run my example?
I'm trying to custom indicator like the picture below but I have a problem is the indicator lose animation and it doesn't work when I press on the second tab :'( , what should I do now ? please help
can you share your code,really like it
you can check this https://github.com/BunHouth/RNTabExample/blob/feature/indicator-gradient/Home.js#L41 it similar to that images
import React, { Component, useEffect, useRef } from 'react'; import { StyleSheet, Dimensions, Animated, Text, View } from 'react-native'; import { TabView, SceneMap, TabBar } from 'react-native-tab-view'; import Icon from 'react-native-vector-icons/MaterialCommunityIcons'; import LinearGradient from "react-native-linear-gradient"; import MyApplication from '../../components/MyApplication'; import Shop from '../../components/Shop'; import _ from "lodash"; import { ButtonGroup } from 'react-native-elements' const styles = StyleSheet.create({ tabView: { backgroundColor: 'white', }, tabbar: { backgroundColor: 'white', overflow: 'hidden', // height: 50, marginBottom: 10, elevation: 0, shadowColor: 'white', shadowOpacity: 0, shadowRadius: StyleSheet.hairlineWidth, shadowOffset: { height: 0, width: 0, }, marginLeft: 10 }, tabStyle: { flexDirection: 'row', color: '#263238', width: 'auto', // borderWidth: 1, // borderColor: 'black', // borderRadius: 50, // paddingLeft: 20, // paddingRight: 20, }, labelStyle: { color: '#263238', fontSize: 16, }, // indicatorStyle: { // backgroundColor: 'black' // }, fn: { position: 'absolute', right: 0, top: 0, flexDirection: 'row' } }); const TabIndicator = props => { const { width, tabWidth, index } = props; const marginLeftRef = useRef(new Animated.Value(index ? tabWidth : 0)) .current; useEffect(() => { Animated.timing(marginLeftRef, { toValue: tabWidth, duration: 400 }).start(); }, [tabWidth]);
return ( <Animated.View style={{ justifyContent: "flex-end", alignItems: "center", flex: 1, width: width, marginLeft: marginLeftRef }} > <LinearGradient start={{ x: 0, y: 0 }} end={{ x: 1, y: 0 }} colors={["#50b0ea", "#80a2ed", "#a797f2", "#e981f4"]} style={{ height: 2, width: "100%" }} /> </Animated.View> );
} class Application extends Component {
constructor(props) { super(props) this.state = { index: 0, routes: [ { key: 'MyApplication', title: 'My App', icon: 'view-compact-outline', color: [244, 67, 54] }, { key: 'Shop', title: 'Store', icon: 'store', color: [244, 67, 54] }, ], } } renderIndicator = ({ getTabWidth }) => { const tabWidth = _.sum([...Array(this.state.index).keys()].map(i => getTabWidth(i))); return ( <TabIndicator width={getTabWidth(this.state.index)} tabWidth={tabWidth} index={this.state.index} /> ); } renderScene = SceneMap({ MyApplication, Shop }); renderIcon = ({ route, color, size }) => ( <Icon type='material-community' name={route.icon} size={25} color='#263238' /> ); renderLabel = ({ route, focused, color }) => ( <Text style={styles.labelStyle}> {route.title} </Text> ) renderTabBar = props => ( <TabBar {...props} renderIcon={this.renderIcon} style={styles.tabbar} labelStyle={styles.labelStyle} tabStyle={styles.tabStyle} indicatorStyle={styles.indicatorStyle} /> ); render() { const { selectedIndex } = this.state return ( <TabView style={styles.tabView} lazy navigationState={this.state} renderScene={this.renderScene} renderTabBar={this.renderTabBar} renderIndicator={this.renderIndicator} onIndexChange={index => this.setState({ index })} // initialLayout={{ width: Dimensions.get('window').width }} /> ); }
} export default Application; not work ,is any mistake?
can you just show the error? did you able to run my example?
no effect ,the final view is default effect,i can't find where wrong
renderIndicator
is a prop on TabBar
. You're passing it to TabView
renderIndicator
is a prop onTabBar
. You're passing it toTabView
it worked,thanks boss
I'm trying to custom indicator like the picture below but I have a problem is the indicator lose animation and it doesn't work when I press on the second tab :'( , what should I do now ? please help