Mobile is the land of small screens in portrait orientation, tall and narrow. This is a different environment from the desktop where screens are large and wide. Building mobile apps require developers to think differently to make applications that work in small spaces.
Touch interaction is also a different experience with it's own set of concerns and solutions.
Follow this lesson lecture in video form:
https://youtube.com/playlist?list=PLoN_ejT35AEhE6SyoGzrLHPISssRaM-a4
Watch Lesson 06 1 - 3
- Use ListView
- Differentiate ListView and scrollView
- Use a FlatList
2023
- 6.8 Billion smart phone users worldwide
- U.S. Spend 2:55 Hours per day on average
- 69% use mobile phones for product research
- 50.9% use mobile phones for shopping
- 6 out of 10 shop on mobile
- Mobile web traffic 54.8%
- Digital media 70% of time on mobile
- Digitial ad spending on mobile is two-thirds
https://www.oberlo.com/blog/mobile-usage-statistics
Some more statistics:
- 97% of americans own a cellphone 9 in 10 own a smartphone
- US adults spent nearly a third of their media time on mobile (31.5%)
- The average internet user checks their phone 58 times per day
- 56% of all internet traffic in 2019 was generated by mobile phones
- 66% of smartphone users are addicted to their phones
- We spend 90% of media time on mobile devices in apps and 10% on the mobile web
- There were 204 billion apps downloads in 2019 worldwide
https://www.pewresearch.org/internet/fact-sheet/mobile/
-
Screens are smaller
- text needs to be larger ands and easier to read
- Smaller space limits what you can show
-
Interaction
- Your finger is a large and awkward pointing device
- Your finger easily covers the thing you are interacting with
https://www.popsci.com/technology/article/2010-02/meat-iphone-sausage-stylus/
Mobile interfaces have their own UI elements and design systems.
https://developer.apple.com/design/human-interface-guidelines/
Mobile screens are small you'll always be scrolling. There are two ways to handle scrolling.
- Scrolling a small amount of content
- Scrolling a large amount of content
tl;dr For a small amount of content use a ScrollView. For a large amount of content use a ListView or FlatList.
ScrollView scrolls things when they take up more space than the ScrollView displays. This means that all of those things are rendered.
Why is there a ListView and why would you use that instead of scrollview?
The ListView manages a large amount of data.
Remember when Steve Jobs said you could have 10,000 songs in your pocket?
People thought it was great. There was a developer somewhere that needed to solve the problem of how to scroll through a list of 10,000 items!
Seriously, imagine creating 10,000 views and loading them in RAM. Sounds like we might have memory problem.
Heck! imagine rendering the pixels that made up a list of table cells where each cell is 40 pixels tall...
That's a 40,000 pixel tall images! If each cell were 320 pixels wide:
40 * 320 * 10,000 = 128,000,000 pixels
By comparison the iPhone SE screen is 320 x 568, thats:
320 * 568 = 181,760 pixels
So with 10,000 table cells listing all of your favorite songs on your iPhone SE you'd need more than 704 screens!
128,000,000 / 181,760 = 704.2253521127 screens
What does the ListView do differently?
The ListView generates enough views to fill the screen. It displays only a subset of data at any moment. As each row view scrolls off the screen it is recycled and populated with new data.
The ListView uses a limited set of views to scroll through an unlimited amount of data.
For these projects you will be using Expo. It is a tool used with React Native. Follow the Guide here: https://docs.expo.io
For these examples, you'll be using a data set that has information about cat and dog breeds.
Initialize a new React Native Project with expo.
npx create-expo-app@latest by-breed --template blank
Then run the project to test it.
cd by-breed
Navigate to the project directory in the terminal with:
Start the project:
npx expo start
The terminal should show a QR code and a list of commands you can run. To see the project live you can:
- Open it on your mobile phone by scanning the QR code with your camera. It will ask you to install the Expo Go app.
- You can press a, i, or w to open the app in the Android or iOS simulator, or open it on the web. To use the simulator you must install it!
Note! You may get a message that you need to install or update Xcode. Xcode is a large download and it may take a while!
Xocde is Apple's developer tool and is used to create apps for Apple devices. Xcode includes an iOS simulator, which allows you to simulate running an iOS app on your desktop.
What is Expo?
Expo is an app that runs on your phone that loads your React Native project. You'll use this for development. When you are ready to publish your app you'll do a build.
To work with Expo you need to install on an iOS or Android device.
After installing Expo on your mobile device open your phone and scan the QR code that opened in your browser.
After a moment you should see the app load on your phone. If you have problems connecting to your phone with Expo in the web page, just above the QR code, try switching from LAN to Tunnel.
Another way to run the project on your desktop is with the iOS or Android simulator. You need to have these installed. The iOS simulator comes with Xcode.
Take a look at the terminal you'll see:
› Press a │ open Android
› Press i │ open iOS simulator
› Press w │ open web
Pressing i should open the iOS simulator (provided you have it installed)
You maych to launch the simulator from Xcode first! Choose: Xcode > Open Developer Tool > Simulator
From here editing the code on your desktop should update on your phone!
Once you have created a project and can run it in Expo you're ready to start on the current class project. The goal of this project is to create an for people interested in owning a dog or cat. The app will list cats and dogs and provide information that rates each animal in different categories by breed.
Get the sample files here: https://github.com/Tech-at-DU/by-breed-starter
Copy these two files into your project folder.
breeds.jscat-and-dog-breeds.json
The cat-and-dog-breeds.json file contains all of the data as one larger object. The breeds.js has some helper code to turn this object into arrays of cats and dogs.
- Create a scrollView
- Add some content
- Scroll!
Make a new component Item.js.
Keep things simple at first. Use the View and Text component to display each breed.
import React from 'react'
import { View, Text } from 'react-native'
function Item({ title }) {
return (
<View>
<Text>{title}</Text>
</View>
);
}
export default ItemIn App.js import ScrollView component.
import { ScrollView, View, Text } from 'react-native'Then import the list of cats, or dogs if you prefer!
import { cats } from './breeds'The cats array contains a list of objects with information about a cat breed.
One record might look like:
{
"breed": "Abyssinian",
"Affectionate with Family": 3,
"Amount of Shedding": 3,
"Easy to Groom": 3,
"General Health": 2,
"Intelligence": 5,
"Kid Friendly": 5,
"Pet Friendly": 5,
"Potential for Playfulness": 5
}Import the Item component you created.
import Item from './Item'In your App.js component use the ScrollView and map the list of cats into Item components.
<ScrollView>
{cats.map((item, index) => {
return <Item title={`${index} ${item.breed}`} />
})}
</ScrollView>When you get this working you may see that it overlaps the status bar at the top or the 'notch' on newer iPhones.
You can take this into account by adjusting padding and margin on the ScrollView. This might prove problematic for the range of phones available. Luckily React Native Provides a SafeAreaView component that takes care of this for us!
import SafeAreaView
import { ..., SafeAreaView } from 'react-native'Wrap your ScrollView in the SafeAreaView.
<SafeAreaView>
<ScrollView>
...
</ScrollView>
</SafeAreaView>- Define data
- Create a FlatList
- Define props
- renderItem
- keyExtractor
The FlatFlist is a component that is used to display large amounts of data in a scrolling list.
The FlatList takes data as a prop. Rather than assigning it child components to render you'll give it the data instead.
Why data?
FlatList needs to know how many rows you have to work with. Only a subset of the data will be displayed in the list. FlatList keeps track of the starting and ending indexes that are currently displayed.
FlatList also takes a prop called renderItem. This is a function that returns an item to render.
Why renderItem?
This function returns an object with the data and returns a React Native Component which displays as the list cell. FlatList will ask us for the cells it needs, we supply the cell from the data and index.
The Object passed to renderItem includes three keys:
item: Thedataitem for this rowindex: theindexof this row indataseparators: An object with properties that can be used to render separators between rows
What is keyExtractor?
Each cell needs a unique id, keyExtractor is used for this. keyExtractor is a prop that you assign a function to. This function receives the data item and index for the current row from which you will extract the key.
item: Thedataitem for this rowindex: Theindexof the row indata
Use this function to generate unique row ids.
- Create ScrollView
- Fill with objects
- Set styles
- Options
- Look at the data source
- Import FlatList
- Render a FlatList
- Set props
- data
- renderItem
- keyExtractor
- Define a Row Component
The data source includes a list of cats and a list of dogs. Each record is an object that inlcudes a breed property, and a list of other properties that rate the breed in different areas such as friendliness, Affection, Shedding, Health, etc. Each of these fields is rated with a value of 0 to 5.
NOTE! Not all properties appear with every animal. Only breed is guaranteed to appear with each object.
Create the FlatList component. Add set its props.
data- Set the data source to an array.renderItem- A function that returns a Component- The
renderItemfunction takes an object with the following properties: item- An item from dataindex- the index of the item in dataseparators- An object with properties used for customizing custom separator Components (not used in this example)
- The
Set data to an array:
<FlatList
data={cats}
/>Here the array contains data items that rendered into rows in the FlatList.
Set renderItem:
<FlatList
...
renderItem={({ item, index }) => {
return <Item title={`${index} ${item.breed}`} />
}}
/>The renderItem function returns a component to display for each row. The function receives an object with the item and the index.
The item is an element from the data array and index is its position in the array. In this example, item would be one of the values from the data array.
When you get this working you may see a warning telling you that your list is missing keys. Fix this by defining a key extractor.
Define keyExtractor. React requires all children of a JSX list to have a unique key. FlatList handles this with keyExtractor a function that receives the item from data and returns a unique key.
All of the breeds are unique. You can use that as a key.
<FlatList
...
keyExtractor={item => item.breed}
/>The keyExtractor function generates a unique key for each cell. Here the cell was generated from the contents of the row plus the index. If your data had unique ids you could use those.
https://reactnative.dev/docs/flatlist#docsNav
Your goal is to display a list of Cats or dogs. Your list should include all of the properties supplied for each animal breed.
Note! animals share some properties but each animal's list of properties is unique, that is, each animal does not have the same list of properties!
Each property has a value associated with it. Display that next to the property name.
- Use FlatList to display a list of animals
- Create a component for List item
- Display the breed name for each
- Display all of the properties and values supplied for each animal!
- Style your component
- Style the text so the breed name is larger than the property names.
- Use some margin to add space around each Item
- Add a border on the bottom of each item to act as a separator.
Stretch Goals!
Calculate an average rating for each animal. Add up all of the value from it's properties, other than 'breed' and divide by the number of properties.
Round off the average rating to 1 or 2 decimals.
Display the rating as stars. Use the emoji star in a Text component.
Style the names and values so the names are on the left and the values are on the right. You can do this with Flex. You may need to add more Text and View components to make this work!
Imagine this was one property and value row.
<View style={styles.propertyRow}>
<Text>Affectionate with Family</Text>
<Text>3</Text>
</View>You arrange these with flex like this:
const styles = {
propertyRow: {
display: flex,
justifyContent: 'space-between'
}
}Follow the tutorial videos and create the By Breed app. Your app should do the following:
- Display all cats or dogs
- Display the name of each breed
Complete the challenges in the By Breed project.