Quick Note – initialListSize property of ListView

In ListView, there’s a property initialListSize that specifies how many rows should be rendered on first load of list.

By default, it’s value is 10.

Now I’m making a photo sharing app, in which I’m displaying my ListView as a Grid using a stylesheet hack.

This property got me pulling my hair because the List only showed 10 photos on screen even though my data source had over 50 images loaded.

It’s important to set the value of initialListSize to the number of images your grid will have on initial load.

 

P.S. I’m working on my app Picsily now that’s why the frequency of posts is a bit low. I’ll keep posting as soon as I get time. Loads to share… It’s an ultimate delightful experience developing on React Native 🙂

 

Signing off and back to work,

Vaibhav Arora

Posted in React Native

Navigation between views in React Native – Let’s get those views jumping

Let’s begin with one of the main topics – Navigation.

The joy of those transitions that come out of native apps is priceless. Let’s see how we can achieve navigation in React Native.

Let’s begin by creating a new project.


react-native init NavigationApp

So we just named our app – NavigationApp. After the initial setup, let’s head to the code.

I’m again targeting android app so we’ll edit index.android.js

In this post, we aim to achieve –

  1. An app with two views simple views
  2. Navigation to and fro between the views
  3. Handling navigation on device’s back button

 

Since we are going to create two difference screens, for modularity, we will create two different files for each screen –

PageOne.js – The view that will contain a button to load Page Two.

PageTwo.js – The view that will contain a button to load Page One.

Back to editing index.android.js,

In React native, the navigable screens are known as “Scenes”. The navigation between scenes is handled by a function commonly known as router function. To enable navigation, we put our view inside a <Navigator> object.

Navigator requires a prop “renderScene” that is the router function to handle navigation. It requires a function that returns the View to be loaded.

Creating the function –


_renderScene(route, navigator){

if (route.id === 1) {
return<PageOne navigator={navigator}>
} else if (route.id === 2) {
return <PageTwo navigator={navigator}>
}

}

Since PageOne and PageTwo are used in the renderScene method, they need to be imported.

var PageOne = require('./PageOne');
var PageTwo = require('./PageTwo');

This is possible only when these two components are made “exportable”. You’ll get to know how to achieve this in the code of PageOne I’ve given below.

In the function _renderScene the framework sends two parameters –
1 .route Object – it will be sent by the developer on navigation so that the router can identify which scene to render
2. navigator – the instance of navigator object

So as we know to enable Navigation, our view needs to have Navigator object, the render method becomes –

render() {
 return (
 <Navigator
 initialRoute={{ id: 1, }}
 renderScene={this._renderScene.bind(this)} 
 >
 );
 }

So the starting point of our app (index.android.js) is rendering only a Navigator object with an initialRoute

initialRoute can contain an object of your choice, I’m keeping a property “id” in my object for this.
So _renderScene method would receive the object as  {id : 1} and load view PageOne on load of the application.

 

Now moving over to the other views – PageOne and PageTwo.

Edit the PageOne.js file –

Since this is also a React component, it needs to be a class extending Component-

The file looks like –


import React, { Component } from 'react';

import {
AppRegistry,
StyleSheet,
Text,
View,
Navigator,
TouchableHighlight
} from 'react-native';

class PageOne&nbsp;extends Component {

props: {
navigator: Navigator;
};

_onPressButton(){
this.props.navigator.push({
id: 2
});

}

render() {
return (
<View style={styles.container}>
<TouchableHighlight onPress={this._onPressButton.bind(this)}>
<Text style={styles.button}>Go to Page Two</Text>
</TouchableHighlight>
</View>
);
}
}

const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
button: {
fontSize: 20,
textAlign: 'center',
margin: 10,
}
});

module.exports = PageOne;

As you can see, it’s just another React component which renders a Touchable text.

The component has a prop “navigator” that contains the navigation object we created in index file, to achieve navigation to other pages from PageOne.

The click method of button uses the navigator object to navigate to PageTwo view (id: 2).

 

The last line “module.exports = PageOne” is something that got me pulling my hair out for an hour. This line lets us call our React component from other JS files.

Since we need to refer to PageOne in index.android.js , it’s important that this component is declared as an exportable module so that it can be “required” in index file.

I couldn’t find any official documentation of this yet, I’ll update this post if I find one.

 

Similarly, create PageTwoview to navigate to PageOne from a touchable text.

 

Let’s run the app and see how it goes –


react-native run-android

 

21 3

 

 

It works 🙂 … that too with all native transitions…

Now we can build an app with multiple views easily.

 

Though, on trying to press back button (of android) the app minimizes as the default behaviour of android apps.

Let’s see how we can capture the native back button to go back within the app.

A look at the API section of React native documentation reveals the BackAndroid API.

We need to listen to hardwareBackPress  event on BackAndroid object to achieve custom handling of Back Button.

Include “BackAndroid” in the import statement.


import {
 AppRegistry,
 StyleSheet,
 Text,
 View,
 Navigator,
 BackAndroid
} from 'react-native';

 

Now attach the event to BackAndroid object.

 

 

 


BackAndroid.addEventListener('hardwareBackPress', function() {
 if (navigator &&navigator.getCurrentRoutes().length > 1) {
 navigator.pop();
 return true;
 }
 return false;
});

In the event listener, we need to have the instance of navigator object created in render() method.

We will use ref prop of the Navigator to store Object created in the local variable “navigator”.

render() method finally becomes –


 render() {
 return (
 <Navigator
 ref={(nav) => { navigator = nav; }}
 initialRoute={{ id: 1, }}
 renderScene={this._renderScene.bind(this)} 
 
>
 );
 }

 

And that works as a charm! 🙂

 

I hope it helps anyone who’s starting with react native development to get those screen moving 🙂 .

I’ll start working on my app for my website now.

I shall write my learnings about more advanced topics like – calling web services, creating a login form, etc in the upcoming posts.

Please feel free to point out any errors or bad practices in my code; I’m still a starter in react native.

Till now, I feel it’s completely fun creating apps on the React Native framework for Javascript developers. 🙂

 

Signing off,

Vaibhav Arora

 

Posted in General, React Native

Changing App Icon in android react native generated apps

What’s an app without a cool icon, anyways ? (Right, @instagram ? ) 😉

Let’s see how we can change the icon of the applications created using React Native.

Since our android and iOS projects are generated by react-native build system, it’s understandable when someone searches for “react native app icon” on Google and end up with little or not relevant information.

So was the case with me, being a Javascript coder and having very little experience on native Java Android development, I searched the same.

So here’s how you can change the default icon of your app generated by React Native.

In Android,

the app icon is picked up from <your project>androidappsrcmainresmipmap-xxxx directories.

Simple place your icon in PNG format in the 4 directories and it will be used in deploying your generated APK.

Thanks to stack overflow for more information –

“for IOS:

  • you should set AppIcon in Images.xcassets.
  • you should upload 9 different size icons 29pt 29pt*2 29pt*3 40pt*2 40pt*3 57pt 57pt*2 60pt*2 60pt*3.”

 

I’ve quickly created an icon for my sample To-Do app (I really need to start on another micro project now).

icon

Placing it in directories with the name “ic_launcher.png”.

File name can be changed after adjusting AndroidManifest.xml in <your project>ToDoandroidappsrcmain directory.

Let’s launch and test now.


react-native run-android

screenshot.png

And there we have it 🙂 … Looks cool!

 

So that’s how we can change app icon for react-native generated apps. It’s not really specific to react native, but it may confuse beginners since the complete project gets generated.

Next post- let’s explore how to add a splash screen.

Signing off,

Vaibhav Arora

 

Posted in React Native

To Do android app – React Native with persistant on device storage

So, we’re back. I had a week break away from work, blogging & React. Needless to say, I missed it.

Let’s start from where we had left.

Remember the little To-Do app we had made ? Let’s make it store the To-Dos list offline.

Continuing from my project “ToDo”. Open up command prompt console and go to directory  project”ToDo”.

First, we need to start react-native server in this directory to start serving our APK to my device connected.


react-native start

 

 

Open the index.android.js file in your favourite editor.

So looking at the ways to implement offline storage, I stumble upon AsyncStorage API. It is similar to webstorage , we can store data in form of key-value pairs. According to the API, it’s available in the app globally. The API also suggests that we don’t use the AsyncStorage directly, let’s look into making an abstraction on top of it later.

So, continuing in index.android.js; add the import of AsyncStorage in the head of js file.


import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
TextInput,
ListView,
ScrollView,
View,
Dimensions,
AsyncStorage
} from 'react-native';

Now we have the AsyncStorage global object available in our app.

 

Our first step would be on load of the application, check the local storage for previously stored ToDo items.  Let’s create a method to load from local storage.


loadFromLocalStorage: function(oResult){

var oDataSource = new ListView.DataSource({rowHasChanged: (r1, r2) =&gt; r1 !== r2});
if(oResult){
try{
oResult = JSON.parse(oResult);
this._toDoList = oResult;
this.setState({dataSource: oDataSource.cloneWithRows(this._toDoList)});
}
catch(exp){
console.log(exp);
}
}
},

In the method above, we are again creating a ListView.DataSource object to hold the ToDo items we retrieve from local storage.

In the parameter, we’re expecting an object from localstorage. So this method would be a callback for the AsyncStorage API.

Since we need to check for previously stored To-Do’s we can do an API call in the very first method that will be called in our app getInitialState().

Our getInitialState method becomes –


getInitialState(){
var oDataSource = new ListView.DataSource({rowHasChanged: (r1, r2) =&gt; r1 !== r2});

&lt;strong&gt;AsyncStorage.getItem(&quot;toDoItems&quot;).then( (value) =&gt; { this.loadFromLocalStorage(value)});&lt;/strong&gt;

this._toDoList = ['Buy Coffee', 'Water the Plants'];
return {
dataSource: oDataSource.cloneWithRows(this._toDoList),
};
},

We’ve added an API call to AsyncStorage to return us the data stored against key “toDoItems“. We will use the same key to store our data.

 

Now we have a method that’s being triggered on load of app and reading local storage for any items stored by user.

Let’s modify our addToDo method to add the item to local storage as well.


addToDo: function(oEvent){
var oDataSource = new ListView.DataSource({rowHasChanged: (r1, r2) =&gt; r1 !== r2});
this._toDoList.push(oEvent.nativeEvent.text);
this.setState({dataSource: oDataSource.cloneWithRows(this._toDoList)});
AsyncStorage.setItem(&quot;toDoItems&quot;, JSON.stringify(this._toDoList));

},

We added only one line at the end to store our toDoList in form of a JSON string. I’m assuming it will add or replace any data stored against key “toDoItems” in AsyncStorage.

Let’s now deploy our app on a device and see how it works.

So I add two new items to my To-Do list.

I close the app, and open it up again.

 

Voila! We have our list persisted. That was easy 🙂 …

So we’re able to store data locally on our android app using just two methods of this API.

I’ve added my code on github, feel free to refer.

P.S. I’m still a beginner at React Native. It would be much appreciated if someone points out any bad practice or mistakes in the code.

Let’s keep learning while creating.

 

Signing off,

Vaibhav Arora

 

Posted in General, React Native

To Do app in React Native – Android

Starting with another micro project to get my hands dirty on React Native.

What I aim to do in this one –

  1. Create a To-do application on android platform using a windows machine
  2. Application should be able to –
    1. Maintain a list of To-Do’s
    2. Mark a To-Do as “Completed”
    3. Store the To-Do’s in local storage –? (let’s find out!)

 

So, let’s start with creating a new project, call it ToDo.


react-native init ToDo

The above command will create a new blank react-native project. When it’s done you’d see a directory “ToDo” created. [Grab a cup of coffee till it’s done 🙂 ]

Since we’re targeting an Android app, let’s go ahead and edit “index.android.js”.

[I use Visual Studio Code for ReactNative development, it’s pretty neat!]

I’ve created a rough design of how the app should look like. A quick prototype in Powerpoint always gives a good overview of what we’re going to create.

prototype.PNG

If you’re developing on a windows machine, you need to explicitly start the react-native build system to sync app’s JS files with your device.

Go to the project directory in command prompt, and type in


react-native start

You are now ready to package your app and serve the APK installed on your device with latest JS code that you are going to develop.

Now that we have our system up and running, let’s dive into the code and create what we’ve planned.

index.android.js

Edit the render() method –

render() {
return (
&lt;View style={styles.container}&gt;
&lt;Text style={styles.title}&gt;
To-Do:
&lt;/Text&gt;
&lt;ScrollView style={styles.scrollView}&gt;
&lt;ListView dataSource={this.state.dataSource}
renderRow={this.renderItem}
style={styles.todoList}
&gt;

&lt;/ListView&gt;
&lt;/ScrollView&gt;
&lt;TextInput placeholder=&quot;Enter Here&quot; /&gt;
&lt;/View&gt;
);
}

So we’ve created :

View — containing –> [Text, ScrollView, TextInput]

ScrollView –containing –> [ListView]

For better modularization, we’re separating the rendering logic of each list item to come from another function renderItem() that we’re going to define as below

renderItem(rowData){
return (
&lt;Text style={styles.todoItem}&gt;{rowData}&lt;/Text&gt;
);
},

Note that, the list view requires a prop dataSource. In each react component, we can maintain “states”.

States are objects that define a component’s current properties, using which the framework re-renders the component if it’s state has changed.

For now, let’s keep our data source (to-do list) in our component’s state.

Going ahead, may be we can create another component for just the ‘list’ part so that each time an item is added, the framework does not re-render the entire screen.

To define a state, we can include the method “getInitialState” in our component.

getInitialState(){
var oDataSource = new ListView.DataSource({rowHasChanged: (r1, r2) =&gt; r1 !== r2});
this._toDoList = ['Buy Coffee', 'Water the Plants'];
return {
dataSource: oDataSource.cloneWithRows(this._toDoList),
};
},

In the above method, we’re creating an object of ListView.DataSource. It is required to create List Items from a native array.

We’re using our object oDataSource to create an intial data source array from a native array [‘Buy Coffee’,’Water the Plants’].

We’re now done with our UI elements that we need on screen. We can now style our elements the way we want them to appear.

In the generated index.android.js file, a const styles variable is created. We are going to add more keys to this object for styling our UI elements.

const styles = StyleSheet.create({
 container: {
 flex: 1,
 justifyContent: 'center',
 alignItems: 'center',
 backgroundColor: '#F5FCFF',
 },
 title: {
 fontSize: 20,
 textAlign: 'center',
 margin: 10,
 },
 scrollView:{
 backgroundColor: '#EFEFEF',
 height: 300
 },
 todoList: {
 backgroundColor: &quot;#EFEFEF&quot;,
 flex: 1,
 width: Dimensions.get('window').width
 },
 todoItem:{
 backgroundColor: &quot;#FFFFFF&quot;,
 textAlign: &quot;left&quot;,
 borderColor: &quot;#000000&quot;
 }
});

Let’s try running our app to see the changes done so far.


react-native run-android

I use my Nexus 6P device with USB debugging for developing apps. You can also create a virtual android device as explained in the setup tutorial.

Here’s a screenshot of what we’ve achieved till now.

Screenshot_20160509-204213

Now that we have our UI in place, let’s start working on the interactions.

We need to make our TextInput store the entered text in component state.

Using the onSubmitEditing event of TextInput, attach a function addToDo.


&lt;TextInput placeholder=&quot;Enter Here&quot; onSubmitEditing={this.addToDo} /&gt;


addToDo: function(oEvent){
var oDataSource = new ListView.DataSource({rowHasChanged: (r1, r2) =&gt; r1 !== r2});
this._toDoList.push(oEvent.nativeEvent.text);
this.setState({dataSource: oDataSource.cloneWithRows(this._toDoList)});
},

In the above code, we’re pushing a new string to our  _toDoList array and re-setting the component’s state.

Now we achieved some interactivity on our app. When I’m typing in my text in TextInput, it’s re-rendering the component to add that item to my To-Do list above.

Screenshot_20160509-212329.pngScreenshot_20160509-212339 (1).png

 

 

 

 

 

 

 

 

 

 

 

 

Okay… that feels good! 🙂 In only 97 lines of code, we’re able to create a temporary To-Do list.

Now we need to make this list persistent. Let’s explore some local storage options in React Native.

I will try that our and write another post for it. We will also extend it to enable “complete” functionality for each to-do item.

P.S. I’m a beginner in React Native. I started learning only 48 hours ago. So it’s highly appreciated if you come across any bad practice in my code and point that out in the comments section. Thanks.

 

Signing off,

Vaibhav

Posted in React Native

Experiments with React Native

Let’s the experiments begin.

It’s been a couple months since I first saw the introduction video of ReactNative and since that night, I have been wanting to start on it. This weekend I decided to finally start.

For those of you who don’t know, ReactNative is a framework developed at Facebook for developers to easily create native applications for different platforms. Being a web developer, I’ve always wanted to jump in native app development, but the ease of developing responsive web apps for mobiles has always pulled me back. Finally, there’s a solution for us JS developers that lets us code in Javascript and the framework converts it into actual native code.

For starters, I strongly recommend going through the official Getting Started guide.

I assume we’re done with setting up the system and can dive into action now.

I’m working on a Windows machine and focussing on android platform for developing apps.

I’ll keep this post as a starting point for my ReactNative experiments. I’ll keep updating the list below with my latest ReactNative posts.

Experiements –

 

Posted in General

My Experiements

I was a blogger , only 11 years ago and then I got busy.

I’m Vaibhav, 24 years old software developer. My journey at blog-o-sphere started 11 years ago when I was introduced to Blogger by my sister who was an avid reader. It was early 2000s when we got connected to the web through a 64 kbps Sify Broadband connection.

After spending a few months on Yahoo! Messenger, Raaga.com, Hi5, I got onto blogger – not to write about my daily life, but to learn. I was mesmerized by a blog my sister used to read. The blogger used to write comic posts with an element of Javascript alerts in between the text to make his posts interactive. I always wondered how those windows popups (ahem, alerts!) worked. I was keen to know how he could write jokes in small windows triggered on clicking on the links in his posts. I thought of starting a blog myself to find out.

And thus began my experiments with the web.

I started learning Javascript from sites like JavascriptKit, JavasciptSource. It seemed like magic. I was able to create forms that let readers enter their names and blast them with alerts suggesting how bad their name sounds. It was amazing what web had for new developers – infinite code snippets, glittery graphics in marquee, the fancy flash menus, using 4 rounded images to make that rounded cornered table.It was fun.

More importantly the thing I loved the most about web was it never looked ugly with compilation errors. It was always me, my jokes and the beautiful imperfect web.

Years passed, I grew up from being a kid writing posts with embedded Javascript to a freelance developer learning  HTML, JS, PHP & MySQL while creating “static” & “dynamic” webpages for small businesses in New Delhi, India.

It was about time when my first board exams arrived. With that, like every Indian Kid in the 90s, my web surfing time was reduced. I could no longer write meaningless-yet-funny posts. I could no longer spend time browsing “WTB PHP script” posts on DigitalPoint.

And thus, slowly, I went away from the blog-o-sphere.

Luckily, last night I stumbled upon my old e-mail account which I used to write my childhood blog. It made me realize, the technology I started playing with is now my livelihood. I realized how good the hobby to write was. In this fast paced ever changing tech world, where we need to keep learning, it can be a great way to learn while I blog about what I learn.

Hence, I’m back.

I’m going to write about the things I learn, the small web apps I create. Basically anything and everything I want to learn – I’ll try and write a post about it.

May be some day, 11 years later,  I will stumble upon this blog and feel the same feeling I felt last night.