Custom decimal rating bar React native

Hi Guys, In this article, we are going to create a Custom decimal rating bar React native, Nowadays a rating bar is most common in e-commerce application to give rating for products & in react native we have many libraries for rating bar but we have to manage versions of dependencies also if you want to customize these plugins then it’s very hard to do. the better way to create a custom component for the rating bar. so in this article, we are creating a custom rating bar that you can directly copy and use in your code. also, you can select decimal rating using this custom rating bar. so let’s start with an example

1. Create a new project

react-native init ProjectName

2. Import the following dependencies

// import React components
import React, {useState} from 'react';

// import react-native components
import {
  SafeAreaView,
  StyleSheet,
  View,
  Text,
  Image,
  TouchableOpacity,
} from 'react-native';

3. Create a custom rating bar component

Create a custom component and call it in the return method. The following component contains logic to display default Star icons and as per selection. I have rendered Stars using the map function and added onPress on it for selection rating and call method onStarClick which update selection star value in React Native hooks using setDefaultRating. As you can see I have used TouchableOpacity with position absolute.

We have use const with React-native hooks instead of class as you can see below

 // Set the default Ratings Selected
  const [defaultRating, setDefaultRating] = useState(3);
  // Set the max number of Ratings
  const [maxRating, setMaxRating] = useState([1, 2, 3, 4, 5]);

  // Filled Star
  const starImageFilled =
    'https://www.techup.co.in/wp-content/uploads/2020/11/ic_star_fill.png';
  // Empty Star
  const starImageCorner =
    'https://www.techup.co.in/wp-content/uploads/2020/11/ic_star.png';
  // Half Star
  const startHalfFilled =
    'https://www.techup.co.in/wp-content/uploads/2020/11/ic_star_half.png';

  const onStarClick = (item, bool) => {
    if (bool) {
      item = item - 1 + 0.5;
    }
    setDefaultRating(item);
  };

const CustomRatingBar = () => {
    return (
      <View style={styles.ratingBarStyle}>
        {maxRating.map((item, key) => {
          return (
            <View>
              <Image
                style={styles.imageStyle}
                source={
                  item <= defaultRating
                    ? {uri: starImageFilled}
                    : item >= defaultRating && item < defaultRating + 1
                    ? {uri: startHalfFilled}
                    : {uri: starImageCorner}
                }
              />
              <View
                style={{
                  flex: 1,
                  flexDirection: 'row',
                  position: 'absolute',
                }}>
                <TouchableOpacity
                  activeOpacity={0.7}
                  style={{
                    width: 20,
                    height: 40,
                  }}
                  onPress={() => onStarClick(item, true)}
                />

                <TouchableOpacity
                  activeOpacity={0.7}
                  style={{
                    width: 20,
                    height: 40,
                  }}
                  onPress={() => onStarClick(item, false)}
                />
              </View>
            </View>
          );
        })}
      </View>
    );
  };

4. Return method

In the return method, I have display CustomRatingBar component along with the selection Textview & button to display selected ratings on the alert box.

 return (
    <SafeAreaView style={styles.container}>
      <View style={styles.container}>
        <Text style={styles.titleText}>React-Native Custom Rating Bar</Text>
        {/* Custom Rating Bar component */}
        <CustomRatingBar />
        <Text style={styles.textStyle}>
          {/* Display selected Ratings */}
          {defaultRating} / {Math.max.apply(null, maxRating)}
        </Text>
        <TouchableOpacity
          activeOpacity={0.7}
          style={styles.buttonStyle}
          onPress={() => alert('Selected Ratings ' + defaultRating)}>
          {/* Button to display selected Ratings in alert box */}
          <Text style={styles.buttonTextStyle}>Get Selected Ratings</Text>
        </TouchableOpacity>
      </View>
    </SafeAreaView>
  );
};

5. Source code (App.js)

Check this full source code for CustomRatingBar. just copy the whole source code and then paste it into your javascript file

// import React components
import React, {useState} from 'react';

// import react-native components
import {
  SafeAreaView,
  StyleSheet,
  View,
  Text,
  Image,
  TouchableOpacity,
} from 'react-native';

const App = () => {
  // Set the default Ratings Selected
  const [defaultRating, setDefaultRating] = useState(3);
  // Set the max number of Ratings
  const [maxRating, setMaxRating] = useState([1, 2, 3, 4, 5]);

  // Filled Star
  const starImageFilled =
    'https://www.techup.co.in/wp-content/uploads/2020/11/ic_star_fill.png';
  // Empty Star
  const starImageCorner =
    'https://www.techup.co.in/wp-content/uploads/2020/11/ic_star.png';
  // Half Star
  const startHalfFilled =
    'https://www.techup.co.in/wp-content/uploads/2020/11/ic_star_half.png';

  const onStarClick = (item, bool) => {
    if (bool) {
      item = item - 1 + 0.5;
    }
    setDefaultRating(item);
  };

  const CustomRatingBar = () => {
    return (
      <View style={styles.ratingBarStyle}>
        {maxRating.map((item, key) => {
          return (
            <View>
              <Image
                style={styles.imageStyle}
                source={
                  item <= defaultRating
                    ? {uri: starImageFilled}
                    : item >= defaultRating && item < defaultRating + 1
                    ? {uri: startHalfFilled}
                    : {uri: starImageCorner}
                }
              />
              <View
                style={{
                  flex: 1,
                  flexDirection: 'row',
                  position: 'absolute',
                }}>
                <TouchableOpacity
                  activeOpacity={0.7}
                  style={{
                    width: 20,
                    height: 40,
                  }}
                  onPress={() => onStarClick(item, true)}
                />

                <TouchableOpacity
                  activeOpacity={0.7}
                  style={{
                    width: 20,
                    height: 40,
                  }}
                  onPress={() => onStarClick(item, false)}
                />
              </View>
            </View>
          );
        })}
      </View>
    );
  };

  return (
    <SafeAreaView style={styles.container}>
      <View style={styles.container}>
        <Text style={styles.titleText}>React-Native Custom Rating Bar</Text>
        {/* Custom Rating Bar component */}
        <CustomRatingBar />
        <Text style={styles.textStyle}>
          {/* Display selected Ratings */}
          {defaultRating} / {Math.max.apply(null, maxRating)}
        </Text>
        <TouchableOpacity
          activeOpacity={0.7}
          style={styles.buttonStyle}
          onPress={() => alert('Selected Ratings ' + defaultRating)}>
          {/* Button to display selected Ratings in alert box */}
          <Text style={styles.buttonTextStyle}>Get Selected Ratings</Text>
        </TouchableOpacity>
      </View>
    </SafeAreaView>
  );
};

export default App;

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: 'white',
    padding: 10,
    justifyContent: 'center',
    textAlign: 'center',
  },
  titleText: {
    padding: 8,
    fontSize: 16,
    textAlign: 'center',
    fontWeight: 'bold',
  },
  textStyle: {
    textAlign: 'center',
    fontSize: 23,
    color: '#000',
    marginTop: 15,
  },
  textStyleSmall: {
    textAlign: 'center',
    fontSize: 16,
    color: '#000',
    marginTop: 15,
  },
  buttonStyle: {
    justifyContent: 'center',
    flexDirection: 'row',
    marginTop: 30,
    padding: 15,
    backgroundColor: '#080566',
  },
  buttonTextStyle: {
    color: '#FFFFFF',
    textAlign: 'center',
  },
  ratingBarStyle: {
    justifyContent: 'center',
    flexDirection: 'row',
    marginTop: 30,
  },
  imageStyle: {
    width: 40,
    height: 40,
    resizeMode: 'cover',
  },
});

6. Output:

We are not using other dependencies to create this rating bar, we are just using React native core component and you can see the result. you will ready to use this Custom Decimal rating bar in React Native

React native custom rating bar

Thank you 🙂

Leave a Reply

Your email address will not be published.