کلونینگ Tinder با استفاده از عناصر بومی React و Expo


Making pixel-perfect layouts on mobile is hard. Even though React Native makes it easier than its native counterparts, it still requires a lot of work to get a mobile app to perfection.

In this tutorial, we’ll be cloning the most famous dating app, Tinder. We’ll then learn about a UI framework called React Native Elements, which makes styling React Native apps easy.

Since this is just going to be a layout tutorial, we’ll be using Expo, as it makes setting things up much easier than plain old react-native-cli. We’ll also be making use of a lot of dummy data to make our app.

We’ll be making a total of four screens—Home, Top Picks, Profile, and Messages.

Want to learn React Native from the ground up? This article is an extract from our Premium library. Get an entire collection of React Native books covering fundamentals, projects, tips and tools & more with SitePoint Premium. Join now for just $9/month.


For this tutorial, you need a basic knowledge of React Native and some familiarity with Expo. You’ll also need the Expo client installed on your mobile device or a compatible simulator installed on your computer. Instructions on how to do this can be found here.

You also need to have a basic knowledge of styles in React Native. Styles in React Native are basically an abstraction similar to that of CSS, with just a few differences. You can get a list of all the properties in the styling cheatsheet.

Throughout the course of this tutorial we’ll be using yarn. If you don’t have yarn already installed, install it from here.

Also make sure you’ve already installed expo-cli on your computer.

If it’s not installed already, then go ahead and install it:

$ yarn global add expo-cli  

To make sure we’re on the same page, these are the versions used in this tutorial:

  • Node 11.14.0
  • npm 6.4.1
  • yarn 1.15.2
  • expo 2.16.1

Make sure to update expo-cli if you haven’t updated in a while, since expo releases are quickly out of date.

We’re going to build something that looks like this:

Tinder Demo in Expo

If you just want to clone the repo, the whole code can be found on GitHub.

Getting Started

Let’s set up a new Expo project using expo-cli:

$ expo init expo-tinder  

It will then ask you to choose a template. You should choose tabs and hit Enter.

Expo Init - Choose A Template

Then it will ask you to name the project. Type expo-tinder and hit Enter again.

Expo Init - Name the Project

Lastly, it will ask you to press y to install dependencies with yarn or n to install dependencies with npm. Press y.

Expo Init - Install the dependencies

This bootstraps a brand new React Native app using expo-cli.

React Native Elements

React Native Elements is a cross-platform UI Toolkit for React Native with consistent design across Android, iOS and Web.

It’s easy to use and completely built with JavaScript. It’s also the first UI kit ever made for React Native.

It allows us to fully customize styles of any of our components the way we want so every app has its own unique look and feel.

It’s also open source and backed by a community of awesome developers.

You can build beautiful applications easily.

React Native Elements Demo

Cloning Tinder UI

We’ve already created a project named expo-tinder.

To run the project, type this:

$ yarn start  

Press i to run the iOS Simulator. This will automatically run the iOS Simulator even if it’s not opened.

Press a to run the Android Emulator. Note that the emulator must be installed and started already before typing a. Otherwise it will throw an error in the terminal.

It should look like this:

Expo Tabs App

The initial setup has already installed react-navigation for us. The bottom tab navigation also works by default because we chose tabs in the second step of expo init. You can check it by tapping on Links and Settings.

The screens/ folder is responsible for the content displayed when the tabs are changed.

Now, completely remove the contents of HomeScreen.js and replace them with the following:

import React from 'react'  import { Text, View } from 'react-native'    class HomeScreen extends React.Component {    render() {      return (        Home Screen      )    }  }    export default HomeScreen  

You should see the updated UI now:

The empty Home screen

Now we’ll adapt the tabs according to the application we’re going to build. For our Tinder clone, we’re going to have four screens: Home, Top Picks, Profile, and Messages.

We can completely delete LinksScreen.js and SettingsScreen.js from the screens/ folder. Notice our app breaks, with a red screen full of errors.

This is because we’ve linked to it in the navigation/ folder. Open MainTabNavigator.js in the navigation/ folder. It currently looks like this:

import React from 'react';  import { Platform } from 'react-native';  import { createStackNavigator, createBottomTabNavigator } from 'react-navigation';    import TabBarIcon from '../components/TabBarIcon';  import HomeScreen from '../screens/HomeScreen';  import LinksScreen from '../screens/LinksScreen';  import SettingsScreen from '../screens/SettingsScreen';    const HomeStack = createStackNavigator({    Home: HomeScreen,  });    HomeStack.navigationOptions = {    tabBarLabel: 'Home',    tabBarIcon: ({ focused }) => (          ),  };    const LinksStack = createStackNavigator({    Links: LinksScreen,  });    LinksStack.navigationOptions = {    tabBarLabel: 'Links',    tabBarIcon: ({ focused }) => (          ),  };    const SettingsStack = createStackNavigator({    Settings: SettingsScreen,  });    SettingsStack.navigationOptions = {    tabBarLabel: 'Settings',    tabBarIcon: ({ focused }) => (          ),  };    export default createBottomTabNavigator({    HomeStack,    LinksStack,    SettingsStack,  });  

Remove references to LinksStack and SettingsStack completely, because we don’t need these screens in our app. It should look like this:

import React from 'react'  import { Platform } from 'react-native'  import {    createBottomTabNavigator,    createStackNavigator,  } from 'react-navigation'  import TabBarIcon from '../components/TabBarIcon'  import HomeScreen from '../screens/HomeScreen'    const HomeStack = createStackNavigator({    Home: HomeScreen,  })    HomeStack.navigationOptions = {    tabBarLabel: 'Home',    tabBarIcon: ({ focused }) => (          ),  }    export default createBottomTabNavigator({    HomeStack,  })  

Go ahead and create TopPicksScreen.js, ProfileScreen.js and MessagesScreen.js inside the screens/ folder.

Add the following inside TopPicksScreen.js:

import React from 'react'  import { Text, View } from 'react-native'    class TopPicksScreen extends React.Component {    render() {      return (        Top Picks Screen      )    }  }    export default TopPicksScreen  

Add the following inside ProfileScreen.js:

import React from 'react'  import { Text, View } from 'react-native'    class ProfileScreen extends React.Component {    render() {      return (        Profile Screen      )    }  }    export default ProfileScreen  

Add the following inside MessagesScreen.js:

import React from 'react'  import { Text, View } from 'react-native'    class MessagesScreen extends React.Component {    render() {      return (        Messages Screen      )    }  }    export default MessagesScreen  

Let’s go ahead and change components/TabBarIcon.js, since we’ll be needing custom icons on our bottom tab navigation. It currently looks like this:

import React from 'react';  import { Icon } from 'expo';    import Colors from '../constants/Colors';    export default class TabBarIcon extends React.Component {    render() {      return (              );    }  }  

The only thing we’re doing here is adding an Icon prop so we can have different types of Icon instead of just Ionicons. Currently, the different supported types are AntDesign, Entypo, EvilIcons, Feather, FontAwesome, FontAwesome5, FontAwesome5Brands, Foundation, Ionicons, MaterialCommunityIcons, MaterialIcons, SimpleLineIcons, Octicons and Zocial.

You can choose a variety of different icons from the @expo/vector-icons directory. It adds a compatibility layer around @oblador/react-native-vector-icons to work with the Expo asset system.

TabBarIcon.js should now look like this:

import React from 'react'  import Colors from '../constants/Colors'    export default class TabBarIcon extends React.Component {    render() {      const { Icon, name, focused } = this.props      return (              )    }  }  

Now we can pass the Icon prop to the above TabBarIcon component to load different icons.

We need to change the implementation of HomeStack in the MainTabNavigator.js folder to incorporate with the new TabBarIcon component’s Icon prop.

Change the HomeStack variable implementation to this:

import { Icon } from 'expo'    const HomeStack = createStackNavigator({    Home: HomeScreen,  })    HomeStack.navigationOptions = {    tabBarLabel: 'Home',    tabBarIcon: ({ focused }) => (          ),  }  

The only change here is the addition of Icon={Icon.MaterialCommunityIcons}, since we changed the implementation of TabBarIcon to accept the icon source so we can use different types of icons from different providers.

Now these icons need to be loaded first. Otherwise, we’ll see a flash of empty screen before the icons show up. For that, we need to change App.js by adding the following:

Font.loadAsync({    // This is the font that we're using for our tab bar    ...Icon.MaterialIcons.font,    ...Icon.MaterialCommunityIcons.font,    ...Icon.FontAwesome.font,    ...Icon.Feather.font,  }),  

These font types are used at some points in our application. That’s why we’ve included only four fonts. For example, MaterialCommunityIcons is used in the HomeStack variable in the MainTabNavigator.js file, as shown above.

We’ll also be hiding our StatusBar in App.js with this:

We’ll also replace the assets used in App.js:

Asset.loadAsync([    require('./assets/images/splash.png'),    require('./assets/images/icon.png'),  ]),  

The App.js file should now look like this:

import { AppLoading, Asset, Font, Icon } from 'expo'  import React from 'react'  import { StatusBar, StyleSheet, View } from 'react-native'  import AppNavigator from './navigation/AppNavigator'    export default class App extends React.Component {    state = {      isLoadingComplete: false,    }      render() {      if (!this.state.isLoadingComplete && !this.props.skipLoadingScreen) {        return (                  )      } else {        return (                  )      }    }      _loadResourcesAsync = async () => {      return Promise.all([        Asset.loadAsync([          require('./assets/images/splash.png'),          require('./assets/images/icon.png'),        ]),        Font.loadAsync({          // This is the font we're using for our tab bar          ...Icon.MaterialIcons.font,          ...Icon.MaterialCommunityIcons.font,          ...Icon.FontAwesome.font,          ...Icon.Feather.font,        }),      ])    }      _handleLoadingError = error => {      // In this case, you might want to report the error to your error      // reporting service, such as Sentry      console.warn(error)    }      _handleFinishLoading = () => {      this.setState({ isLoadingComplete: true })    }  }    const styles = StyleSheet.create({    container: {      flex: 1,      backgroundColor: '#fff',    },  })  

We also need to link all of the above screens—TopPicksScreen.js, ProfileScreen.js and MessagesScreen.js—inside screens/ in MainTabNavigator.js inside the navigation/ folder, as shown in the following flowchart:

Flowchart Demo

Also add the following in MainTabNavigator.js:

import MessagesScreen from '../screens/MessagesScreen'  import ProfileScreen from '../screens/ProfileScreen'  import TopPicksScreen from '../screens/TopPicksScreen'    const TopPicksStack = createStackNavigator({    TopPicks: TopPicksScreen,  })    TopPicksStack.navigationOptions = {    tabBarLabel: 'TopPicks',    tabBarIcon: ({ focused }) => (          ),  }    const MessagesStack = createStackNavigator({    Messages: MessagesScreen,  })    MessagesStack.navigationOptions = {    tabBarLabel: 'Messages',    tabBarIcon: ({ focused }) => (          ),  }    const ProfileStack = createStackNavigator({    Profile: ProfileScreen,  })    ProfileStack.navigationOptions = {    tabBarLabel: 'Profile',    tabBarIcon: ({ focused }) => (          ),  }  

The above code creates three stack navigators—TopPicksStack, MessagesStack and ProfileStack. The static property navigationOptions lets us add our own label and icon to the bottom tab.

Also, change createBottomTabNavigator to make sure TopPicksStack, MessagesStack and ProfileStack show up in the bottom tab navigation:

export default createBottomTabNavigator({    HomeStack,    TopPicksStack,    MessagesStack,    ProfileStack,  })  

Now you should be able to see different icons in the bottom tab navigation with different screens as follows:

Different icons in the bottom tab navigation

We now need to get rid of the header that’s showing on each screen, taking up some top space. To get rid of it, we need to add headerMode: 'none' in the createStackNavigator config.

We need to add it on HomeStack, TopPicksStack, MessagesStack and ProfileStack.

HomeStack should look like this:

const HomeStack = createStackNavigator(    {      Home: HomeScreen,    },    {      headerMode: 'none',    },  )  

Do the same for the rest of them. Now if you check, the text goes up to the top left, right above the clock.

Different icons in the bottom tab navigation

There’s an easy fix for this. We need to use SafeAreaView. SafeAreaView renders content within the safe area boundaries of a device. Let’s go into the screens/ directory and change HomeScreen.js to use SafeAreaView, so that it looks like this:

import React from 'react'  import { SafeAreaView, Text } from 'react-native'    class HomeScreen extends React.Component {    render() {      return (        Home Screen      )    }  }    export default HomeScreen  

It now renders the content inside the boundaries of the device.

SafeAreaView added to the app

Go ahead and change the rest of them to do the same.

It’s repetitive to wrap SafeAreaView inside every component instead of setting it up on a root component like App.js. But be aware that this won’t work if you try doing it on App.js.

Remember, SafeAreaView should always be set up on screen components or any content in them, and not wrap entire navigators. You can read more about it on this blog post.


Now that our navigation is taken care of, we can start working on the layout.

We’re going to be using a UI toolkit called React Native Elements, so go ahead and install it:

$ yarn add react-native-elements  

Before starting anything, make sure to copy the assets/ directory from the GitHub repo entirely for dummy images.

Now we’ll start working on the Home screen.

Home Screen

Before starting to work on HomeScreen.js, let’s delete unnecessary files. Go to the components/ folder and delete StyledText.js and the __tests__ folder.

Now let’s start working on our Home screen.

Firstly, create Card.js in the components/ folder. We’re going to display a profile card with the person’s name, their age and how far away they live.

We’re going to use a Tile component from react-native-elements to display our User Card.

The Tile component from react-native-elements looks like this:

Tile component from react-native-elements

import React from 'react'  import { Platform, StyleSheet } from 'react-native'  import { Tile } from 'react-native-elements'  import Layout from '../constants/Layout'    const BOTTOM_BAR_HEIGHT = !Platform.isPad ? 29 : 49 // found from https://stackoverflow.com/a/50318831/6141587    export const Card = ({ pic, title, caption }) => (      )    const styles = StyleSheet.create({    container: {      flex: 1,      alignItems: 'center',    },    imageContainer: {      width: Layout.window.width - 30,      height: Layout.window.height - BOTTOM_BAR_HEIGHT * 6,      borderRadius: 20,      overflow: 'hidden', // this does magic    },    title: {      position: 'absolute',      left: 10,      bottom: 30,    },    caption: {      position: 'absolute',      left: 10,      bottom: 10,    },  })  

The Card component takes pic, title and caption, which in turn are passed on to the Tile component.

The Tile component has some additional properties. activeOpacity is a number passed to control opacity on pressing the Tile, which is optional, but the default value is 0.2, which makes it look transparent on press, so we pass a value close to 1 to keep it opaque. The featured prop changes the look of Tile. It keeps the text in title and a caption prop on the image rather than below when featured is not specified or is set to false.

The rest are styles applied to get the user card right. The container style centers the user card. imageContainer has a width and a height. The width is set to the total width of the device—30dp (device pixels)—and the height is set to the total height of the device—BOTTOM_BAR_HEIGHT * 6.

We get the BOTTOM_BAR_HEIGHT from stackoverflow.com.

We get the device width from the constants/Layout.js file, which basically contains the following:

import { Dimensions } from 'react-native'    const width = Dimensions.get('window').width  const height = Dimensions.get('window').height    export default {    window: {      width,      height,    },    isSmallDevice: width 

Then we add a border radius to the image. But the border radius won’t be applied. We also need overflow: hidden to make it work.

Then we position our title and caption to use absolute positioning and make them appear on the bottom-left corner, just above the image.

Next, create a utils/shuffleArray.js file and paste the following into it:

// found at https://stackoverflow.com/a/46545530/6141587  const shuffleArray = array =>    array      .map(a => ({ sort: Math.random(), value: a }))      .sort((a, b) => a.sort - b.sort)      .map(a => a.value)    export default shuffleArray  

This makes sure our array is randomized every time.

Now create a constants/Pics.js file and paste in the following:

import shuffleArray from '../utils/shuffleArray'    export const HomeScreenPics = shuffleArray([    {      pic: require('../assets/images/women/women1.jpg'),      title: 'Amelia, 27',      caption: '16 miles away',    },    {      pic: require('../assets/images/women/women2.jpg'),      title: 'Joanna, 19',      caption: '2 miles away',    },    {      pic: require('../assets/images/women/women3.jpg'),      title: 'Charlie, 32',      caption: '24 miles away',    },    {      pic: require('../assets/images/women/women4.jpg'),      title: 'Mary, 23',      caption: '45 miles away',    },    {      pic: require('../assets/images/women/women5.jpg'),      title: 'Lucy, 27',      caption: '32 miles away',    },    {      pic: require('../assets/images/women/women6.jpg'),      title: 'Rachel, 29',      caption: '30 miles away',    },    {      pic: require('../assets/images/women/women7.jpg'),      title: 'Ava, 31',      caption: '14 miles away',    },    {      pic: require('../assets/images/women/women8.jpg'),      title: 'Monica, 35',      caption: '19 miles away',    },    {      pic: require('../assets/images/women/women9.jpg'),      title: 'Lisa, 25',      caption: '7 miles away',    },    {      pic: require('../assets/images/women/women10.jpg'),      title: 'Julia, 22',      caption: '9 miles away',    },    {      pic: require('../assets/images/men/men1.jpg'),      title: 'Aaron, 24',      caption: '3 miles away',    },    {      pic: require('../assets/images/men/men2.jpg'),      title: 'Novak, 27',      caption: '12 miles away',    },    {      pic: require('../assets/images/men/men3.jpg'),      title: 'Justin, 32',      caption: '20 miles away',    },    {      pic: require('../assets/images/men/men4.jpg'),      title: 'Tony, 21',      caption: '4 miles away',    },    {      pic: require('../assets/images/men/men5.jpg'),      title: 'Leo, 30',      caption: '22 miles away',    },    {      pic: require('../assets/images/men/men6.jpg'),      title: 'Ronald, 39',      caption: '35 miles away',    },    {      pic: require('../assets/images/men/men7.jpg'),      title: 'Johnny, 41',      caption: '44 miles away',    },    {      pic: require('../assets/images/men/men8.jpg'),      title: 'Chandler, 35',      caption: '29 miles away',    },    {      pic: require('../assets/images/men/men9.jpg'),      title: 'Joey, 29',      caption: '17 miles away',    },    {      pic: require('../assets/images/men/men10.jpg'),      title: 'Alfie, 37',      caption: '27 miles away',    },  ])  

This contains all the images required for our app. Notice every time we call shuffleArray to randomize our array.

Let’s install react-native-deck-swiper to make sure our cards get swiped like Tinder. The latest version (v1.6.7 at the time of writing) uses react-native-view-overflow, which doesn’t support Expo. Hence, we’re going to install v1.5.25:

$ yarn add react-native-deck-swiper@1.5.25  

Now go into the HomeScreen.js file and paste the following:

impo  RT از «واکنش» واکنش نشان دهد  وارد کردن {SafeAreaView ، StyleSheet} از "واکنش بومی"  وارد کردن Swiper از "واکنش بومی-عرشه-عرشه"  وارد کردن {کارت} از '../component/ کارت  وارد کردن {HomeScreenPics} از '../constants/Pics'    کلاس صفحه اصلی React.Component ends    رندر کردن - ارائه کردن - دادن() {      برگشت (                                )    }  }    const styles = StyleSheet.create ({    ظرف: {      فلکس: 1 ،      پس زمینه رنگ: "شفاف" ،    ،  })    صفحه اصلی پیش فرض صادرات  کد / 

اکنون کارتهای ما قابل جابجایی هستند و صفحه اصلی ما اینگونه به نظر می رسد:

نسخه ی نمایشی صفحه اصلی

اکنون انگشت خود را بکشید ، و باید به شرح زیر عمل کند:

اگر می خواهید نحوه ساخت این نوع انیمیشن های Tinder Swipe را یاد بگیرید ، باید Varun Nath را ببینید Tinder Swipe Series در YouTube.”

اکنون که صفحه اصلی ما به پایان رسید ، بیایید صفحه نمایشگر برتر را بسازیم.

صفحه نمایشگرهای انتخابی

اکنون بیایید صفحه نمایشگر برتر را طراحی کنیم.

در مرحله اول ، به ثابت / Pics.js بروید و در پایان بیت زیر را اضافه کنید:

  شرط صادرات TopPicksScreenPics = shuffleArray ([    {      عکس: نیاز ("../ دارایی ها / تصاویر / زنان / زنان 11.jpg") ،      عنوان: 'آنی 40 ساله      عنوان: '26 ساعت سمت چپ' ،    ،    {      عکس: نیاز ("../ دارایی / تصاویر / زنان / زنان12.jpg") ،      عنوان: 'لنا 31 ساله'      عنوان: '20h سمت چپ' ،    ،    {      عکس: نیاز ("../ دارایی / تصاویر / زنان / زنان13.jpg") ،      عنوان: 'Kendra، 19'،      عنوان: '15 ساعت سمت چپ' ،    ،    {      عکس: نیاز ("../ دارایی ها / تصاویر / زنان / زنان 14.jpg") ،      عنوان: 'Mia، 23'،      عنوان: '45 ساعت سمت چپ' ،    ،    {      عکس: نیاز ("../ دارایی ها / تصاویر / زنان / زنان15.jpg") ،      عنوان: 'جنی 27 ساله'      عنوان: '12 ساعت سمت چپ' ،    ،    {      عکس: نیاز ("../ دارایی / تصاویر / مردان / men11.jpg") ،      عنوان: 'دوین 34 ساله'      عنوان: '13h سمت چپ' ،    ،    {      عکس: نیاز ("../ دارایی / تصاویر / مردان / men12.jpg") ،      عنوان: 'Novak، 27'،      عنوان: '22h سمت چپ' ،    ،    {      عکس: نیاز ("../ دارایی / تصاویر / مردان / men13.jpg") ،      عنوان: 'Zikomo، 32'،      عنوان: '20h سمت چپ' ،    ،    {      عکس: نیاز ("../ دارایی / تصاویر / مردان / men14.jpg") ،      عنوان: 'سام ، 19' ،      عنوان: '42 ساعت سمت چپ' ،    ،    {      عکس: نیاز ("../ دارایی / تصاویر / مردان / men15.jpg") ،      عنوان: 'ریچارد ، 31' ،      عنوان: '21h سمت چپ' ،    ،  ])  کد / 

اینها تصاویری هستند که در صفحه Top Picks به آنها نیاز خواهیم داشت

اکنون کد زیر را در TopPicksScreen.js اضافه کنید:

  وارد کردن واکنش از "واکنش"  وارد کردن {ScrollView ، StyleSheet ، نمای از "واکنش بومی"  وارد کردن {متن ، کاشی} از "عناصر واکنش-بومی"  وارد کردن {SafeAreaView} از 'واکنش ناوبری'  وارد کردن {TopPicksScreenPics} از '../constants/Pics'    کلاس TopPicksScreen React.Component ends را گسترش می دهد    رندر کردن - ارائه کردن - دادن() {      برگشت (                                            عکسهای برتر                                      پروفایل های برجسته روز ، فقط برای شما انتخاب شده است                                      {TopPicksScreenPics.map (({عکس ، عنوان ، عنوان) ، i) => (                              ))}                                    )    }  }    const styles = StyleSheet.create ({    h2Style:      fontWeight: "bold" ،      textAlign: "مرکز" ،      رنگ: '# 000000'،    ،    h4Style:      textAlign: "مرکز" ،      رنگ: '# 757575'،    ،    توری: {      marginTop: 20 ،      حاشیه پایین: 20 ،    ،    عنوان: {      موقعیت: "مطلق" ،      سمت چپ: 10 ،      پایین: 50 ،      پس زمینه رنگ: "سیاه" ،      حاشیه پایین: -2 ،      بالشتک: 10 ،    ،    عنوان: {      موقعیت: "مطلق" ،      سمت چپ: 10 ،      پایین: 0 ،      پس زمینه رنگ: "سیاه" ،      marginTop: 10 ،      بالشتک: 10 ،    ،  })    صادرات پیش فرض TopPicksScreen  کد / 

در مرحله اول ، ما از مؤلفه اصلی Text موجود در عناصر واکنش-بومی با عنوان و زیر عنوان استفاده می کنیم.

سپس تمام تصاویری را که اخیراً در ثابت / Pics.js اضافه کرده ایم حلقه می کنیم و آنها را با استفاده از مؤلفه Tile نمایش می دهیم. p>

عنوان عنوان و عنوان cod> به طور پیش فرض در center قرار داده شده است ، اما ما آنها را با موقعیت به سمت چپ سمت چپ منتقل کرده ایم : "مطلق" .

نتیجه صفحه انتخاب برتر ما ، که بسیار ساده بود نتیجه می گیرد

به نظر می رسد:

نسخه نمایشی صفحه نمایشگرهای برتر

صفحه پیام ها

اکنون بیایید با صفحه پیام ها شروع کنیم. در مرحله اول ، ما به برخی از داده های ساختگی برای نمایش در لیست ها نیاز داریم

Messages.js را در پوشه ثابت / ایجاد کنید و در شکل زیر جای گذاری کنید:

  shuffleArray import از "../utils/shuffleArray"    ارسال پیام const = shuffleArray ([    {      عکس: نیاز ("../ دارایی / تصاویر / زنان / زنان1.jpg") ،      عنوان: 'آملیا ، 27' ،      پیام: "بیایید به رستوران مورد علاقه خود برسیم."،    ،    {      عکس: نیاز ("../ دارایی / تصاویر / زنان / زنان2.jpg") ،      عنوان: 'جانانا 19 ساله'      پیام: "بهترین راه برای بردن شما چیست؟" ،    ،    {      عکس: نیاز ("../ دارایی / تصاویر / مردان / men2.jpg") ،      عنوان: 'Novak، 27'،      پیام: "بعداً با شما درگیر خواهد شد." ،    ،    {      عکس: نیاز ("../ دارایی / تصاویر / مردان / men3.jpg") ،      عنوان: "جاستین ، 32" ،      پیام: "احتمالاً کار نمی کند :(" ،    ،    {      عکس: نیاز ("../ دارایی / تصاویر / زنان / زنان3.jpg") ،      عنوان: 'Charlie، 32'،      پیام: "چگونه می توانیم یکشنبه برای قهوه برویم؟" ،    ،      {      عکس: نیاز ("../ دارایی / تصاویر / زنان / زنان5.jpg") ،      عنوان: 'لوسی ، 27' ،      پیام: 'اکنون بخوابید.'،    ،    {      عکس: نیاز ("../ دارایی / تصاویر / مردان / men1.jpg") ،      عنوان: 'آرون ، 24' ،      پیام: "به زودی می بینیم" ،    ،    {      عکس: نیاز ("../ دارایی / تصاویر / مردان / men4.jpg") ،      عنوان: 'تونی ، 21' ،      پیام: "جدی ، به موقع بیای."،    ،    {      عکس: نیاز ("../ دارایی / تصاویر / مردان / men5.jpg") ،      عنوان: 'Leo، 30'،      پیام: "چی دوست داری؟" ،    ،    {      عکس: نیاز ("../ دارایی / تصاویر / زنان / زنان4.jpg") ،      عنوان: 'مریم 23'      پیام: "سلام ، چه خبر است؟" ،    ،    {      عکس: نیاز ("../ دارایی ها / تصاویر / زنان / زنان 14.jpg") ،      عنوان: 'میشل ، 45' ،      پیام: "Howdy !!!" ،    ،    {      عکس: نیاز ("../ دارایی / تصاویر / زنان / زنان12.jpg") ،      عنوان: 'Arya، 18'،      پیام: "امروز نیست!" ،    ،  ])  کد / 

بعدی ، MessagesScreen.js را در پوشه مؤلفه ها / ایجاد کنید و در شکل زیر بچسبانید:

  وارد کردن واکنش از "واکنش"  وارد کردن "SafeAreaView" ، "ScrollView" ، "StyleSheet" از "واکنش بومی"  وارد کردن {ListItem} از "عناصر واکنش-بومی"  وارد کردن {پیام} از '../constants/Messages'    پیام های کلاس صفحه نمایش React.Component    رندر کردن - ارائه کردن - دادن() {      برگشت (                              {Messages.map ((کاربر ، من) => (                          ))}                        )    }  }    const styles = StyleSheet.create ({    عنوان: {      fontSize: 24 ،      رنگ: "# 3F3F3F" ،    ،    عنوان فرعی: {      رنگ: '# A5A5A5'،    ،  })    صفحه پیام پیش فرض صادرات  کد / 

ما از داده های ساختگی پیام ها می گیریم و روی آن نقشه می کنیم و آن را در یک ListItem صادر شده از عناصر واکنش دهنده بومی قرار می دهیم. مؤلفه ListItem لیستی از موارد را یکی پس از دیگری نمایش می دهد ، دقیقاً مانند آنچه در هر برنامه پیام مشاهده می کنیم — با نماد بزرگ ، نام کاربر و پیام. عناصر واکنش دهنده بومی همه دردسرهای نوشتن فهرست خود را برای پیام ها از بین می برد تا ما فقط بتوانیم از پنج خط کد برای ایجاد یک لیست زیبا استفاده کنیم.

در حال حاضر به نظر می رسد:

نسخه نمایشی صفحه نمایش پیام

صفحه نمایه

بیایید صفحه نمایه نهایی را بسازیم.

ابتدا یک پرونده utils / randomNo.js ایجاد کنید و در شکل زیر جایگذاری کنید:

  const exportNet randomNo = (min، max) =>    Math.floor (Math.random () * (حداکثر - دقیقه)   دقیقه)  کد / 

تابع randomNo یک عدد تصادفی را بین دقیقه و حداکثر برمی گرداند.

اکنون کامپوننت ها / ProfileScreen.js را باز کنید و در شکل زیر جای گذاری کنید:

  وارد کردن واکنش از "واکنش"  وارد کردن {تصویر ، SafeAreaView ، StyleSheet ، نمای از "واکنش بومی"  وارد کردن {تقسیم ، نماد ، متن} از "عناصر واکنش-بومی"  طرح بندی را از "../constants/Layout" وارد کنید  وارد کردن {HomeScreenPics} از '../constants/Pics'  وارد کردن {تصادفی نه} از '../utils/randomNo'    const {pic، عنوان} = صفحه اصلی صفحه [تصادفی No (1 ، صفحه اصلی صفحه اصلی)    const Social = ({name}) => (      )    کلاس ProfileScreen React.Component ends    رندر کردن - ارائه کردن - دادن() {      برگشت (                                                              {عنوان}                     طراح مد در شرکت آملیا و شرکت  متن>                                من عاشق سفرم. من یک گربه به نام ترشی دارم. اگر او شما را دوست دارد ، من            احتمالاً همینطور                                    )    }  }    const styles = StyleSheet.create ({    ظرف: {      فلکس: 1 ،      alignItems: "مرکز" ،    ،    imageContainer: {      حاشیه: 20 ،    ،    تصویر: {      عرض: Layout.window.width - 60 ، // عرض دستگاه - حاشیه      ارتفاع: Layout.window.height / 2 - 60 ، // ارتفاع دستگاه / 2 - مقداری حاشیه      borderRadius: 20 ،    ،    نام: {      رنگ: "# 5E5E5E" ،      alignSelf: "flex-start" ،      marginLeft: 30،    ،    نزول: {      رنگ: "# 5E5E5E" ،      alignSelf: "flex-start" ،      marginTop: 5 ،      حاشیه افقی: 30،      fontSize: 14 ،    ،    تقسیم کننده: {      پس زمینه رنگ: '# C0C0C0' ،      عرض: Layout.window.width - 60 ،      حاشیه: 20 ،    ،    لینک های اجتماعی: {      فلکس: 1 ،      alignItems: "flex-start" ،      flexDirection: 'row'،      عرض: Layout.window.width ،      marginLeft: 40،    ،    iconContainer: {      paddingHorizontal: 8،      paddingVertical: 15،    ،  })    صادر کردن نمایه پیش فرض ProfileScreen  کد / 

اجازه دهید کمی کد را رمزگشایی کنیم

در مرحله اول ، از آرایه HomeScreenPics ، عنوان pic و عنوان را می گیریم ، که اولین تصویر نیست بلکه می تواند یکی از بقیه تصاویر از آن آرایه. p>

سپس ما یک جزء اجتماعی را ایجاد کرده ایم ، به نظر می رسد:

  const Social = ({name}) => (      )  کد / 

این یک نام را به عنوان پروانه در نظر می گیرد. ما از این روش در روش رندر استفاده می کنیم. روش رندر کردن / کدگذاری "حاوی روش معمول SafeAreaView ، متن ، مشاهده ، و اجتماعی" / کد > کامپوننت — با کمی سبک که قبلاً در بالا پوشانده ایم

تنها مؤلفه منحصر به فرد در اینجا یک جزء تقسیم کننده است. تقسیم کننده strong> ها جداکننده بصری محتوا هستند. ما از آنها استفاده می کنیم تا بین بخش های مختلف محتوا تمایز قائل شویم. p>

در آخر ، ما یک ظاهر طراحی اضافه می کنیم. این است. p>

در حال حاضر به نظر می رسد:

نسخه نمایشی صفحه نمایش

من همچنین می خواهید یک کلون بزنید ، یک repo درست کردم. می توانید اینجا را در GitHub پیدا کنید.

نتیجه گیری

ما با یک ظاهر طراحی سفارشی و با کمک های زیادی که از React Native Elements انجام دادیم ، با موفقیت یک TI UI را کلون کردیم.

عناصر بومی React تمام دردسرها را هنگام ساختن یک UI زیبا با استفاده از کتابخانه مؤلفه های ساخته شده از پیش ساخته ، از بین می برد.

ما همچنین می توانیم همه چیز را به طور کامل از ابتدا بدون استفاده از کتابخانه UI ایجاد کنیم ، اما ما نیاز به نوشتن کد زیادی داریم - بیشتر یک ظاهر طراحی شده. با استفاده از یک کتابخانه UI ، می توانیم کد کمتری بنویسیم و برنامه خود را سریعتر تحویل دهیم.

اکنون می توانید با استفاده از کوچکترین قسمت UI و ساختن آن ، از هر رابط کاربری تقلید کنید. از چارچوب های UI برای نوشتن کد کمتر و ارسال سریعتر استفاده کنید. p>       



Akshay خالق ، هنرمند رایانه و ریزگرد از بمبئی است.



٪٪ مورد_read_more_button ٪٪