Categories
React Native

React Native — Status Bar and Image Styles

React Native is a mobile development that’s based on React that we can use to do mobile development.

In this article, we’ll look at how to use it to create an app with React Native.

StatusBar

The StatusBar lets us control the status bar with our app.

For example, we can write:

import React, { useState } from 'react';
import { Button, StyleSheet, StatusBar, View } from "react-native";
import Constants from "expo-constants";

export default function App() {
  const [visibleStatusBar, setVisibleStatusBar] = useState(false);
  const changeVisibilityStatusBar = () => {
    setVisibleStatusBar(!visibleStatusBar);
  };

  return (
    <View style={styles.container}>
      <StatusBar backgroundColor="blue" barStyle='dark-content' />
      <View>
        <StatusBar hidden={visibleStatusBar} />
      </View>
      <View style={styles.buttonContainer}>
        <Button title="Toggle StatusBar" onPress={() => changeVisibilityStatusBar()} />
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    marginTop: Constants.statusBarHeight,
  },
  scrollView: {
    flex: 1,
    backgroundColor: 'pink',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

We added a StatusBar that can be toggled with the hidden prop.

And we also added one that has the backgroundColor set to 'blue' .

The barStyle sets the status bar style, which is 'dark-content' .

It can also be set to 'default' and ‘light-content’ .

Image Style Props

We can set our image to display with the style we want.

For example, we can write:

import React from 'react';
import { View, Image } from "react-native";

export default function App() {
  return (
    <View>
      <Image
        style={{
          resizeMode: "cover",
          height: 100,
          width: 200
        }}
        source={{ uri: 'https://i.picsum.photos/id/23/200/300.jpg?hmac=NFze_vylqSEkX21kuRKSe8pp6Em-4ETfOE-oyLVCvJo' }}
      />
    </View>
  );
}

to set the width and height .

The resizeMode sets how the image is resized.

We can set it to 'cover' , 'contain' , 'stretch' , 'repeat' , or 'center' .

Also, we can set the tint color. For example, we can write:

import React from 'react';
import { View, Image } from "react-native";

export default function App() {
  return (
    <View>
      <Image
        style={{
          tintColor: "lightgreen",
          resizeMode: "contain",
          height: 100,
          width: 200
        }}
        source={{ uri: 'https://i.picsum.photos/id/23/200/300.jpg?hmac=NFze_vylqSEkX21kuRKSe8pp6Em-4ETfOE-oyLVCvJo' }}
      />
    </View>
  );
}

Then we can see that the image is a light green box instead of showing the original image.

Also, we can add a border around our image.

For example, we can write:

import React from 'react';
import { View, Image } from "react-native";

export default function App() {
  return (
    <View>
      <Image
        style={{
          borderColor: "red",
          borderWidth: 5,
          height: 100,
          width: 200
        }}
        source={{ uri: 'https://reactnative.dev/docs/assets/p_cat2.png' }}
      />
    </View>
  );
}

We set the borderColor to 'red' and borderWidth to 5 to add the border.

Also, we can add border-radius to an image by writing:

import React from 'react';
import { View, Image } from "react-native";

export default function App() {
  return (
    <View>
      <Image
        style={{
          borderTopLeftRadius: 10,
          borderTopRightRadius: 10,
          borderBottomLeftRadius: 10,
          borderBottomRightRadius: 10,
          height: 100,
          width: 200
        }}
        source={{ uri: 'https://i.picsum.photos/id/23/200/300.jpg?hmac=NFze_vylqSEkX21kuRKSe8pp6Em-4ETfOE-oyLVCvJo' }}
      />
    </View>
  );
}

We set the border-radius for the image for each corner with these properties.

Conclusion

We can control the status bar and manipulate images with React Native.

Categories
React Native

React Native — Modal, PixelRatio, and RefreshControl

React Native is a mobile development that’s based on React that we can use to do mobile development.

In this article, we’ll look at how to use it to create an app with React Native.

Modal

We can add a modal to present content above the enclosing view.

For example, we can write:

import React, { useState } from 'react';
import {
  Alert,
  Modal,
  StyleSheet,
  Text,
  TouchableHighlight,
  View
} from "react-native";

export default function App() {
  const [modalVisible, setModalVisible] = useState(false);
  return (
    <View style={styles.centeredView}>
      <Modal
        animationType="slide"
        transparent={true}
        visible={modalVisible}
        onRequestClose={() => {
          Alert.alert("Modal has been closed.");
        }}
      >
        <View style={styles.centeredView}>
          <View style={styles.modalView}>
            <Text style={styles.modalText}>Hello World!</Text>
            <TouchableHighlight
              style={styles.openButton}
              onPress={() => {
                setModalVisible(!modalVisible);
              }}
            >
              <Text style={styles.textStyle}>Hide Modal</Text>
            </TouchableHighlight>
          </View>
        </View>
      </Modal>
      <TouchableHighlight
        style={styles.openButton}
        onPress={() => {
          setModalVisible(true);
        }}
      >
        <Text style={styles.textStyle}>Show Modal</Text>
      </TouchableHighlight>
    </View>
  );
}

const styles = StyleSheet.create({
  centeredView: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
    marginTop: 22
  },
  modalView: {
    margin: 20,
    backgroundColor: "white",
    borderRadius: 20,
    padding: 35,
    alignItems: "center",
    shadowColor: "#000",
    shadowOffset: {
      width: 0,
      height: 2
    },
    shadowOpacity: 0.25,
    shadowRadius: 3.84,
    elevation: 5
  },
  openButton: {
    backgroundColor: "pink",
    borderRadius: 20,
    padding: 10,
    elevation: 2
  },
  textStyle: {
    color: "white",
    fontWeight: "bold",
    textAlign: "center"
  },
  modalText: {
    marginBottom: 15,
    textAlign: "center"
  }
});

We add the View to enclose a Modal component with the modal.

The modal has the View to hold the content.

The TouchableHighlight component is a button that lets us press it to close the modal.

The modal’s open state is opened by the modalVisible state.

The visible prop in the Modal sets the open state.

Below the Modal , we have another TouchableHighlight component to call setModalVisible with true to open it.

PixelRatio

The PixelRatio object gives us access to the device’s pixel density and the font scale.

We can use it to correctly size an image.

For example, we can write:

import React from 'react';
import { Image, PixelRatio, StyleSheet, View } from "react-native";

const size = 50;
const cat = {
  uri: "https://reactnative.dev/docs/assets/p_cat1.png",
  width: size,
  height: size
};

export default function App() {
  return (
    <View style={styles.container}>
      <Image
        source={cat}
        style={{
          width: PixelRatio.getPixelSizeForLayoutSize(size),
          height: PixelRatio.getPixelSizeForLayoutSize(size)
        }}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    justifyContent: "center",
    alignItems: "center"
  },
  value: {
    fontSize: 24,
    marginBottom: 12,
    marginTop: 4
  }
});

We set the width and height in the Image component by calling PixelRatio.getPixelSizeForLayoutSize .

The pixel size will be rounded when we specify size with arbitrary precision.

Therefore, we’ve to be careful with rounding errors.

RefreshControl

We can add a RefreshControl component inside a ScrollView or ListView to add pull to refresh functionality.

For example, we can write:

import React from 'react';
import {
  ScrollView,
  RefreshControl,
  StyleSheet,
  Text,
  SafeAreaView,
} from 'react-native';
import Constants from 'expo-constants';

const wait = (timeout) => {
  return new Promise(resolve => {
    setTimeout(resolve, timeout);
  });
}

export default function App() {
  const [refreshing, setRefreshing] = React.useState(false);

  const onRefresh = React.useCallback(() => {
    setRefreshing(true);

    wait(2000).then(() => setRefreshing(false));
  }, []);

  return (
    <SafeAreaView style={styles.container}>
      <ScrollView
        contentContainerStyle={styles.scrollView}
        refreshControl={
          <RefreshControl refreshing={refreshing} onRefresh={onRefresh} />
        }
      >
        <Text>Pull to Refresh</Text>
      </ScrollView>
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    marginTop: Constants.statusBarHeight,
  },
  scrollView: {
    flex: 1,
    backgroundColor: 'pink',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

We added the RefreshControl in the ScrollView to add the pull to refresh indicator that shows when we pull the screen down.

The refreshing prop controls when the RefreshControl is shown.

And onRefresh is run when we show the RefreshControl .

Conclusion

We can add a modal and refresh indicator into our React Native app.

Also, we can size image proportionally with the PixelRatio object.

Categories
Top React Libraries

Top React Libraries — Virtual Scrolling, Carousels, and Icons

To make developing React apps easier, we can add some libraries to make our lives easier.

In this article, we’ll look at some popular libraries for React apps.

react-virtualized

The react-virtualized package lets us display a virtualized list.

To install it, we run:

npm i react-virtualized

Then we can use it by writing:

import React from "react";
import { List } from "react-virtualized";

const list = Array(1000)
  .fill()
  .map((_, i) => i);

function rowRenderer({ key, index, isScrolling, isVisible, style }) {
  return (
    <div key={key} style={style}>
      {list[index]}
    </div>
  );
}

export default function App() {
  return (
    <div className="App">
      <List
        width={300}
        height={300}
        rowCount={list.length}
        rowHeight={20}
        rowRenderer={rowRenderer}
      />
    </div>
  );
}

We have the rowRenderer to display the list items.

It takes the following props.

key is the unique key in the array of rows.

index is the index of the row in the collection.

isScrolling is the list that’s currently being scrolled.

isVisible indicates whether the row is visible or not.

sytle is style object to be applied to position the row.

We can also use it to display a grid.

For example, we can write:

import React from "react";
import { Grid } from "react-virtualized";
import * as _ from "lodash";

const list = _.chunk(
  Array(1000)
    .fill()
    .map((_, i) => i),
  3
);

function cellRenderer({ columnIndex, key, rowIndex, style }) {
  return (
    <div key={key} style={style}>
      {list[rowIndex][columnIndex]}
    </div>
  );
}

export default function App() {
  return (
    <div className="App">
      <Grid
        cellRenderer={cellRenderer}
        columnCount={list[0].length}
        columnWidth={100}
        height={300}
        rowCount={list.length}
        rowHeight={30}
        width={300}
      />
    </div>
  );
}

We created a nested array with 3 items in each entry with the Lodash chunk method.

Then we created the cellRenderer to render the cells.

columnIndex has the index of the column.

key has the unique key of the entry.

rowIndex has the row index of the entry.

style has the styles to position the item.

Then in App , we use the Grid component that uses the cellRenderer and pass in the row and column counts.

The heights and width are also set.

This package also comes with components for tables and masonry grid.

react-icons

The react-icons package lets us add icons to our React app.

To install it, we can run:

npm i react-icons

Then we can import the icon and use it:

import React from "react";
import { FaBeer } from "react-icons/fa";

export default function App() {
  return (
    <div className="App">
      <h1>
        time for a <FaBeer />
      </h1>
    </div>
  );
}

It comes with icons for many libraries, including Bootstrap, Font Awesome, Github, and much more.

react-slick

The react-slick package lets us add a carousel to our React app.

To install it, we can run:

npm i react-slick slick-carousel

Then we can use it by writing:

import React from "react";
import "slick-carousel/slick/slick.css";
import "slick-carousel/slick/slick-theme.css";
import Slider from "react-slick";

const settings = {
  dots: true,
  infinite: true,
  speed: 500,
  slidesToShow: 1,
  slidesToScroll: 1
};

export default function App() {
  return (
    <div className="App">
      <Slider {...settings}>
        <div>
          <h3>1</h3>
        </div>
        <div>
          <h3>2</h3>
        </div>
        <div>
          <h3>3</h3>
        </div>
        <div>
          <h3>4</h3>
        </div>
        <div>
          <h3>5</h3>
        </div>
        <div>
          <h3>6</h3>
        </div>
      </Slider>
    </div>
  );
}

We used the Slider component to add some slides to our app.

The settings object has the props that we pass in to configure the carousel.

dots lets us choose whether to show the dots for navigation.

infinite sets whether it goes back to the first slide after the last one is reached.

speed is the speed of the slide.

slidesToShow is the number of slides to show at once.

slidesToScroll is the number of slides that we scroll through when we navigate.

There are many other props for styling the dots, slides, and many other parts of the carousel.

Conclusion

The react-virtualized package lets us create a virtual scroll list, table, or masonry grid.

react-icons lets us add icons from many sources.

react-slick is a library to let us add carousels to our app.

Categories
React Native

React Native — Dimensions and Web Views

React Native is a mobile development that’s based on React that we can use to do mobile development.

In this article, we’ll look at how to use it to create an app with React Native.

Dimensions

We can use the Dimensions object to get the window’s dimensions.

For example, we can write:

import React, { useEffect, useState } from 'react';
import { View, StyleSheet, Text, Dimensions } from "react-native";

const window = Dimensions.get("window");
const screen = Dimensions.get("screen");

export default function App() {
  const [dimensions, setDimensions] = useState({ window, screen });

  const onChange = ({ window, screen }) => {
    setDimensions({ window, screen });
  };

  useEffect(() => {
    Dimensions.addEventListener("change", onChange);
    return () => {
      Dimensions.removeEventListener("change", onChange);
    };
  });

  return (
    <View style={styles.container}>
      <Text>{`Window Dimensions: height - ${dimensions.window.height}, width - ${dimensions.window.width}`}</Text>
      <Text>{`Screen Dimensions: height - ${dimensions.screen.height}, width - ${dimensions.screen.width}`}</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center"
  }
});

We get the window’s and screen’s dimensions by listening to the change event.

We use the Dimensions.addEventListener to add a listener for the event.

We use the Dimensions.get method with different arguments to get the window and screen dimensions.

KeyboardAvoidingView

We can use the KeyboardAvoidingView component to add a container that moves away from the keyword when it’s present.

For example, we can write:

import React from 'react';
import { View, KeyboardAvoidingView, TextInput, StyleSheet, Text, Platform, TouchableWithoutFeedback, Button, Keyboard } from 'react-native';

export default function App() {
  return (
    <KeyboardAvoidingView
      behavior={Platform.OS == "ios" ? "padding" : "height"}
      style={styles.container}
    >
      <TouchableWithoutFeedback onPress={Keyboard.dismiss}>
        <View style={styles.inner}>
          <Text style={styles.header}>Header</Text>
          <TextInput placeholder="Username" style={styles.textInput} />
          <View style={styles.btnContainer}>
            <Button title="Submit" onPress={() => null} />
          </View>
        </View>
      </TouchableWithoutFeedback>
    </KeyboardAvoidingView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1
  },
  inner: {
    padding: 24,
    flex: 1,
    justifyContent: "space-around"
  },
  header: {
    fontSize: 36,
    marginBottom: 48
  },
  textInput: {
    height: 40,
    borderColor: "black",
    borderBottomWidth: 1,
    marginBottom: 36
  },
  btnContainer: {
    backgroundColor: "white",
    marginTop: 12
  }
});

We add the KeyboardAvoidingView with the TouchableWithoutFeedback component that has the onPress prop.

We pass in the Keyboard.dismiss method to it to let us remove the keyboard from the screen.

Now when we tap on the TextInput , the keyboard shows, and the view will shrink to accommodate the keyboard.

Links

We call the Linking.openURL method to open a web view with the URL we want.

For example, we can write:

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

export default function App() {
  const handlePress = () => {
    Linking.openURL('https://google.com');
  };

  return (
    <View
      style={styles.container}
    >
      <Text onPress={handlePress}>Google</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
});

to add a piece of text that goes to Google when we tap on it.

Conclusion

We can get the dimensions of the window and screen with React Native.

Also, we can open web views to load a web page with the Linking.openURL method.

Categories
React Native

React Native — Alert and Animations

React Native is a mobile development that’s based on React that we can use to do mobile development.

In this article, we’ll look at how to use it to create an app with React Native.

Alert

We can add alerts with the Alert.alert method.

For example, we can write:

import React from 'react';
import { View, StyleSheet, Button, Alert } from "react-native";

const createTwoButtonAlert = () =>
  Alert.alert(
    "Alert Title",
    "My Alert Msg",
    [
      {
        text: "Cancel",
        onPress: () => console.log("Cancel Pressed"),
        style: "cancel"
      },
      { text: "OK", onPress: () => console.log("OK Pressed") }
    ],
    { cancelable: false }
  );

const createThreeButtonAlert = () =>
  Alert.alert(
    "Alert Title",
    "My Alert Msg",
    [
      {
        text: "Ask me later",
        onPress: () => console.log("Ask me later pressed")
      },
      {
        text: "Cancel",
        onPress: () => console.log("Cancel Pressed"),
        style: "cancel"
      },
      { text: "OK", onPress: () => console.log("OK Pressed") }
    ],
    { cancelable: false }
  );

export default function App() {
  return (
    <View style={styles.container}>
      <Button title="2-Button Alert" onPress={createTwoButtonAlert} />
      <Button title="3-Button Alert" onPress={createThreeButtonAlert} />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center"
  },
});

We call the Alert.alert method with the alert title, alert message, and an array of objects to render the buttons.

The text property has the button text.

onPress is a function that’s run when we press the button.

style has the style name of the button.

cancelable sets whether we can cancel the button press.

Animated

The Animated library lets us make animations fluid and painless to build.

For example, we can write:

import React, { useRef } from 'react';
import { Animated, Text, View, StyleSheet, Button } from "react-native";

export default function App() {
  const fadeAnim = useRef(new Animated.Value(0)).current;
  const fadeIn = () => {
    Animated.timing(fadeAnim, {
      toValue: 1,
      duration: 5000
    }).start();
  };

  const fadeOut = () => {
    Animated.timing(fadeAnim, {
      toValue: 0,
      duration: 5000
    }).start();
  };

  return (
    <View style={styles.container}>
      <Animated.View
        style={[
          styles.fadingContainer,
          {
            opacity: fadeAnim
          }
        ]}
      >
        <Text style={styles.fadingText}>Fading View!</Text>
      </Animated.View>
      <View style={styles.buttonRow}>
        <Button title="Fade In" onPress={fadeIn} />
        <Button title="Fade Out" onPress={fadeOut} />
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: "center",
    justifyContent: "center"
  },
  fadingContainer: {
    paddingVertical: 8,
    paddingHorizontal: 16,
    backgroundColor: "lightblue"
  },
  fadingText: {
    fontSize: 28,
    textAlign: "center",
    margin: 10
  },
  buttonRow: {
    flexDirection: "row",
    marginVertical: 16
  }
});

We call the Animate.timing method to show our animation.

The first argument is the ref for the animation we want to show.

Then we used the fadeAnim object as the value of the opacity property in the Animated.View component.

Whatever is inside Animated.View is animated.

Other methods for show animations include Animated.decay to create an animation that starts with an initial velocity and slows to a stop gradually.

Animated.spring provides us with spring physical model animation.

They take the same arguments as Animation.timing .

We can also compose animations.

Animated.delay starts an animation with a delay.

Animated.parallel starts a number of animations at the same time.

Animated.sequence starts animation in order.

Animated.stagger starts animation in order and in parallel with successive delays.

Combining Animated Values

We can combine 2 animated values with the following methods:

  • Animated.add()
  • Animated.subtract()
  • Animated.divide()
  • Animated.modulo()
  • Animated.multiply()

We can compose animations by writing:

import React, { useRef } from 'react';
import { Animated, Text, View, StyleSheet, Button } from "react-native";

export default function App() {
  const fadeAnim = useRef(new Animated.Value(0)).current;
  const fadeIn = () => {
    Animated.sequence([
      Animated.delay(3000),
      Animated.timing(fadeAnim, {
        toValue: 1,
        duration: 5000,
        useNativeDriver: true
      })
    ]).start()
  };

  const fadeOut = () => {
    Animated.timing(fadeAnim, {
      toValue: 0,
      duration: 5000,
      useNativeDriver: true
    }).start();
  };

  return (
    <View style={styles.container}>
      <Animated.View
        style={[
          styles.fadingContainer,
          {
            opacity: fadeAnim
          }
        ]}
      >
        <Text style={styles.fadingText}>Fading View!</Text>
      </Animated.View>
      <View style={styles.buttonRow}>
        <Button title="Fade In" onPress={fadeIn} />
        <Button title="Fade Out" onPress={fadeOut} />
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: "center",
    justifyContent: "center"
  },
  fadingContainer: {
    paddingVertical: 8,
    paddingHorizontal: 16,
    backgroundColor: "lightblue"
  },
  fadingText: {
    fontSize: 28,
    textAlign: "center",
    margin: 10
  },
  buttonRow: {
    flexDirection: "row",
    marginVertical: 16
  }
});

In the fadeIn function, we have the Animated.sequence method called with 3000ms.

Then we call Animated.timing to run our fade-in animation.

Conclusion

We can show alerts and animations with React Native.