最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React Native - Animate width shrink - Stack Overflow

programmeradmin4浏览0评论

In the header of my React Native app, I have a conditional icon and a Searchbar.

static navigationOptions = ({ navigation }) => {
const { params = {} } = navigation.state;
return {
  headerTitle: (
    <View
      style={{
        flex: 1,
        backgroundColor: Platform.OS === 'ios' ? '#e54b4d' : '',
        alignItems: 'center',
        flexDirection: 'row',
        paddingHorizontal: 10,
        height: StatusBar.currentHeight,
      }}>
      {params.isIconTriggered && <Icon name="chevron-left" size={28} />}
      <SearchBar
        round
        platform={'default'}
        placeholder="Search"
        containerStyle={{
          flex: 1,
          backgroundColor: 'transparent',
        }}
      />
    </View>
  ),
  headerStyle: {
    backgroundColor: '#e54b4d',
  },
};
};

Normally the Searchbar will take the full width of the header which is what I want. If the condition isIconTriggered is true, an icon will appear in front of the Searchbar and the width of the SearchBar will shrink enough so that the icon is visible next to it.

However, there is no transition or animation when this happens and it does not feel nor look nice. I would like to add an animation to the Searchbar so the width shrinks gradually and smoothly when the condition is triggered and the icon appears.

Is that possible to achieve and how can I achieve this?

In the header of my React Native app, I have a conditional icon and a Searchbar.

static navigationOptions = ({ navigation }) => {
const { params = {} } = navigation.state;
return {
  headerTitle: (
    <View
      style={{
        flex: 1,
        backgroundColor: Platform.OS === 'ios' ? '#e54b4d' : '',
        alignItems: 'center',
        flexDirection: 'row',
        paddingHorizontal: 10,
        height: StatusBar.currentHeight,
      }}>
      {params.isIconTriggered && <Icon name="chevron-left" size={28} />}
      <SearchBar
        round
        platform={'default'}
        placeholder="Search"
        containerStyle={{
          flex: 1,
          backgroundColor: 'transparent',
        }}
      />
    </View>
  ),
  headerStyle: {
    backgroundColor: '#e54b4d',
  },
};
};

Normally the Searchbar will take the full width of the header which is what I want. If the condition isIconTriggered is true, an icon will appear in front of the Searchbar and the width of the SearchBar will shrink enough so that the icon is visible next to it.

However, there is no transition or animation when this happens and it does not feel nor look nice. I would like to add an animation to the Searchbar so the width shrinks gradually and smoothly when the condition is triggered and the icon appears.

Is that possible to achieve and how can I achieve this?

Share Improve this question asked Mar 12, 2019 at 14:32 EDJEDJ 1,0234 gold badges19 silver badges42 bronze badges 2
  • Are you using any style library like styled-components? – Sergio Escudero Commented Mar 14, 2019 at 15:14
  • @SergioEscudero I do not use any styling libraries. – EDJ Commented Mar 18, 2019 at 1:00
Add a comment  | 

3 Answers 3

Reset to default 17 +50

Try to learn Animated API of react native.

Here is how i done it with button trigger.

import React, {Component} from 'react';
import {StyleSheet, View, TextInput , Button, SafeAreaView, Animated} from 'react-native';
import FA from 'react-native-vector-icons/FontAwesome5'

const AnimatedIcon = Animated.createAnimatedComponent(FA)
// make your icon animatable using createAnimatedComponent method

export default class Application extends Component {

  animVal = new Animated.Value(0);
   // initialize animated value to use for animation, whereas initial value is zero

  interpolateIcon = this.animVal.interpolate({inputRange:[0,1], outputRange:[0,1]})
  interpolateBar = this.animVal.interpolate({inputRange:[0,1],outputRange:['100%','90%']})
  // initialize interpolation to control the output value that will be passed on styles
  // since we will animate both search bar and icon. we need to initialize both 
  // on icon we will animate the scale whereas outputRange starts at 0 end in 1
  // on search bar we will animate width. whereas outputRange starts at 100% end in 90%

  animatedTransition = Animated.spring(this.animVal,{toValue:1})
  // we use spring to make the animation bouncy . and it will animate to Value 1

  clickAnimate = () => {
    this.animatedTransition.start()
  }
  // button trigger for animation

  //Components that will use on Animation must be Animated eg. Animted.View
  render() {
    return (
      <SafeAreaView>
      <View style={styles.container}>
        <View style={styles.search}>
        {/* our icon */}

        <Animated.View style={{width: this.interpolateBar}}>
        <TextInput placeholder='search here' style={styles.input}/>
        </Animated.View>

        <AnimatedIcon name='search' size={28} style={{paddingLeft: 10,paddingRight:10, transform:[{scale: this.interpolateIcon}]}}/>
        </View>

          <Button title='animate icon' onPress={this.clickAnimate}/>
      </View>
      </SafeAreaView>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    backgroundColor:'#F79D42',
    // flex: 1,
    height:'100%',
    paddingTop:20,
    flexDirection: 'column',
    // justifyContent: 'center',
    alignItems:'center'
  },
  input:{
    width: '100%',
    height:40,
    backgroundColor:'gray',
    textAlign:'center'
  },
  search:{
    flexDirection:'row-reverse',
    width:'90%',
    height:40,
    alignItems:'center'
  }
});

Solution using react-native-elements SearchBar component. Wrapped the SearchBar Component inside Animated.View. to explicitly animate the search bar

Like This:

 <Animated.View style={{width: this.interpolateBar}}>
    <SearchBar
    placeholder="Type Here..."
    containerStyle={{width: '100%'}}
  />
    </Animated.View>

You can achieve this using Animated API of React Native.

You can check this tutorial for an overview of changing the size of elements with animation.

React-Native-Animatable is super cool! Try this one out:

  1. Create A custom animation object
import * as Animatable from 'react-native-animatable';

Animatable.initializeRegistryWithDefinitions({
   const myAnimation = {
      from: {
          width: 200 
      },
      to: {
          width: 100
      }
   }
})
  1. Use is as Animation value within a view or as a reference within a function call.

    Within a view:

   <Animatable.View useNativeDriver animation={myAnimation}/>

  1. As a reference variable:
   <Animatable.View useNativeDriver ref={ref=>(this.testAnimation = ref)}/>

Method:

   testMethod = () => {
       this.testAnimation.myAnimation();
   }
发布评论

评论列表(0)

  1. 暂无评论