skip to Main Content

I have To-Do list elements which can expand and collapse by pressing the associated button.

Android Emulator. Same behavior on my physical Android device

By pressing on the EXPAND Button the height of the Animated ScrollView gets adjusted. From 0 to 100 when expanding and from 100 to 0 when collapsing. When we expand two list-objects at the same time, the screen begins to flicker.

Here the code of one single todo-element (it is abbreviated, means the DONE button is not in it):


import React, { useState, useRef, memo } from 'react';
import { Animated, Text, View, Button, ScrollView } from 'react-native';
import longText from '../data/data';

const ListObject = (props) => {
    
    //Object Expand and Collapse feature
    const expandValue = useRef(new Animated.Value(0)).current;
    const [expandState, setExpand] = useState(false);

    const expandAnimation = () => {
        Animated.timing(expandValue, {toValue: 100, duration: 1000, useNativeDriver: false}).start();
        setExpand(true);
    }
    
    const collapseAnimation = () => {
        Animated.timing(expandValue, {toValue: 0, duration: 1000, useNativeDriver: false}).start();
        setExpand(false);
    }


    return (
        <View style={{ margin: props.margin }}>
            <View style={{
               flexDirection: 'row',
               backgroundColor: 'grey',
               borderRadius: 10, 
            }}>

                <Button title='EXPAND' style={{
                    flex: 1,
                    backgroundColor: 'blue',
                }}
                onPress={ expandState ? collapseAnimation : expandAnimation }
                />
            </View>

            <Animated.ScrollView style={{ 
                flex: 1,
                paddingHorizontal: 40,
                backgroundColor: 'grey',
                borderRadius: 10,
                maxHeight: expandValue
             }}>
                <Text>{ props.text }</Text>              
            </Animated.ScrollView>

        </View>
    );


}


export default memo(ListObject);

Here is the code for the App. To make a collection of all todo-elements, I map over a list and assign a key to each element:

mport React, { useRef, useState } from 'react';
import { Animated, StyleSheet, ScrollView, Text, View, SafeAreaView, Button } from 'react-native';
import longText from './src/data/data';
import ListObject from './src/components/list-object'

const styles = StyleSheet.create({
  safeContainer: {
    flex: 1.2
  },
  headerContainer: {
    flex: 0.2,
    flexDirection: 'column',
    justifyContent: 'center',
    backgroundColor: 'lightblue',
  },
  headerFont: {
    fontSize: 50,
    textAlign: 'center',
  },
  scrollContainer: {
    flex: 1 
  }
});


const App = () => {


    const numbers = [1,2,3,4,5,6,7,8,9];
    const listItems = numbers.map((number) => 
      <ListObject key={number.toString()} margin={10} headerText='I am the header of the to-do element' text={longText} />
    )



  return (

    <SafeAreaView style={ styles.safeContainer } >
      
      <View style={ styles.headerContainer }>
          <Text style={ [styles.headerFont] }>LIST MAKER</Text>
      </View>

      <ScrollView style={ styles.scrollContainer }>

      {listItems}

      </ScrollView>
    </SafeAreaView>
  
  
  );

};

export default App;

I expected no flickering. The flickering appears also on my physical Android device. I have searched for similar problems and checked other libraries how they implement it.

2

Answers


  1. Chosen as BEST ANSWER

    I found the mistake by myself, it's a beginner's mistake.

    Instead of managing the state of the component in the component itself, I had to lift the state up to the parent.

    Here the link to the ReactJS learning doc.


  2. For this, you can use react-native-collapsible

    import Accordion from 'react-native-collapsible/Accordion';
    
    const [activeSections, setActiveSessions] = useState([])
    
    const _updateSections = (activeSections) => {
        setActiveSessions(activeSections.includes(undefined) ? [] : activeSections)
      }
    
    <Accordion
            sections={data}
            activeSections={activeSections}
            duration={400}
            renderHeader={_renderHeader}
            renderContent={_renderContent}
            onChange={_updateSections}
            touchableComponent={TouchableOpacity}
            renderAsFlatList={true}
            expandMultiple={true}
          />
    

    For better performance and a smooth experience use this one.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search