hufeng/iThink

react-native实战--简单登录UI实现

hufeng opened this issue · 12 comments

以战养战,最好的学习方式就是通过实践去反馈,去感受!

明确任务

image

我们想去完成一个简单地登录UI,Why?

  1. 需求够简单,够熟悉
  2. 在这个简单地Demo中可以去了解基础组件的使用方式,组件常用的props
  3. 最重要的一点是学习flexbox的style的布局方式

1. 重构默认模板生成的代码,使用es6 import

'use strict';
import React, {
  AppRegistry,
  StyleSheet,
  View,
}  from 'react-native';


class CoolApp extends React.Component {
  render() {
    return (
      <View style={styles.container}>
      </View>
    );
  }
}

var styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  }
});

AppRegistry.registerComponent('coolapp', () => Coolapp);

2. 显示我们的图片

使用Image组件,好嘞,在render中添加Image

<Image
    source={{uri: 'http://oss-hz.qianmi.com/qianmicom/u/cms/qmwww/201511/03102524l6ur.png'}}
    />

But,我什么都没用看见啊?
我的图片你在哪里?
我读书少,不要骗我!哪里姿势不正确了?

不好意思,在RN中去加载网络图片的时候要设置图片的大小

<Image
    source={{uri: 'http://oss-hz.qianmi.com/qianmicom/u/cms/qmwww/201511/03102524l6ur.png'}}
    style={styles.logo}
    />

完整地git diff

diff --git a/index.ios.js b/index.ios.js
index 8eb461e..f5e2aa6 100644
--- a/index.ios.js
+++ b/index.ios.js
@@ -8,6 +8,7 @@ var React = require('react-native');
 var {
   AppRegistry,
   StyleSheet,
+  Image,
   View
 } = React;

@@ -16,6 +17,9 @@ class CoolApp extends React.Component {
   render() {
     return (
       <View style={styles.container}>
+        <Image
+          source={{uri: 'http://oss-hz.qianmi.com/qianmicom/u/cms/qmwww/201511/03102524l6ur.png'}}
+          style={styles.logo}/>
       </View>
     );
   }
@@ -26,6 +30,11 @@ var styles = StyleSheet.create({
     flex: 1,
     alignItems: 'center',
     backgroundColor: '#F5FCFF'
+  },
+  logo: {
+    width: 160,
+    height: 160,
+    marginTop: 100
   }
 });

效果图,来一份!
image

输入框,你在哪里?

使用TextInput,常用的属性:placeholder 设置输入框的提示, password:true|false,是不是密码

<TextInput 
     placeholder='username'/>
 <TextInput 
      placeholder='password' 
      password={true}/>

感情又被骗了,又是界面什么都没!别急,还是老问题,没设置输入框样式的高度,迅速的补上。

input: {
 height: 40,
 marginTop: 10, //间隔
 borderWidth: 1, 
 borderRadius: 5, //圆角
 borderColor: 'lightblue',
}

image

这个效果不好啊,都挤到边了,没问题,来来来,给父样式加个padding (paddingLeft:10, paddingRight:10).

diff --git a/index.ios.js b/index.ios.js
index f5e2aa6..ae87f56 100644
--- a/index.ios.js
+++ b/index.ios.js
@@ -9,6 +9,7 @@ var {
   AppRegistry,
   StyleSheet,
   Image,
+  TextInput,
   View
 } = React;

@@ -20,6 +21,13 @@ class CoolApp extends React.Component {
         <Image
           source={{uri: 'http://oss-hz.qianmi.com/qianmicom/u/cms/qmwww/201511/03102524l6ur.png'}}
           style={styles.logo}/>
+        <TextInput
+          style={styles.input}
+          placeholder='username'/>
+        <TextInput
+          style={styles.input}
+          placeholder='password'
+          password={true}/>
       </View>
     );
   }
@@ -28,6 +36,8 @@ class CoolApp extends React.Component {
 var styles = StyleSheet.create({
   container: {
     flex: 1,
+    paddingLeft: 10,
+    paddingRight: 10,
     alignItems: 'center',
     backgroundColor: '#F5FCFF'
   },
@@ -35,6 +45,13 @@ var styles = StyleSheet.create({
     width: 160,
     height: 160,
     marginTop: 100
+  },
+  input: {
+    marginTop: 10,
+    height: 40,
+    borderRadius: 5,
+    borderWidth: 1,
+    borderColor: 'lightblue'
   }
 });

(END)

image

登录按钮

我们使用最简单的TouchableOpacity来实现

<TouchableOpacity style={styles.btn}>
   <Text style={styles.text}>login</Text>
 </TouchableOpacity>

样式:

text: {
    fontWeight: 'bold',
    fontSize: 14,
    color: '#FFF'
  },
  btn: {
    alignSelf: 'stretch', //非常重要,覆盖父样式
    alignItems: 'center',
    justifyContent: 'center',
    backgroundColor: '#3333FF',
    height: 40,
    borderRadius: 5,
    marginTop: 10
  }

Ok!大功告成了呢?
image

diff --git a/index.ios.js b/index.ios.js
index ae87f56..4a3092e 100644
--- a/index.ios.js
+++ b/index.ios.js
@@ -10,6 +10,8 @@ var {
   StyleSheet,
   Image,
   TextInput,
+  Text,
+  TouchableOpacity,
   View
 } = React;

@@ -28,6 +30,10 @@ class CoolApp extends React.Component {
           style={styles.input}
           placeholder='password'
           password={true}/>
+
+        <TouchableOpacity style={styles.btn}>
+          <Text style={styles.text}>login</Text>
+        </TouchableOpacity>
       </View>
     );
   }
@@ -52,6 +58,23 @@ var styles = StyleSheet.create({
     borderRadius: 5,
     borderWidth: 1,
     borderColor: 'lightblue'
+  },
+  btn: {
+
+  },
+  text: {
+    fontWeight: 'bold',
+    fontSize: 14,
+    color: '#FFF'
+  },
+  btn: {
+    alignSelf: 'stretch',
+    alignItems: 'center',
+    justifyContent: 'center',
+    backgroundColor: '#3333FF',
+    height: 40,
+    borderRadius: 5,
+    marginTop: 10
   }
 });

(END)

来点交互啊....

是的,在样式上来说,是搞定了啊,那我touch登录按钮,给我一点反应啥。

<TouchableOpacity
   style={styles.btn}
   onPress={() => console.log('press me')}>
   <Text style={styles.text}>login</Text>
 </TouchableOpacity>

恭喜你,可以拿chrome看console.log了。

不错不错,But,我发现输入法不能很好的切换和退掉。。

嗯,嗯,嗯。。。这个还真不好办呢。。。。ok,让我们来点猛的。。。

使用ScrollView包装我们的View

ScrollView可以设置keyboardDismissMode,keyboardShouldPersistTaps来控制输入法的行为。

<ScrollView
    contentContainerStyle={{flex:1}} //非常重要,让ScrollView的子元素占满整个区域
     keyboardDismissMode='on-drag' //拖动界面输入法退出
     keyboardShouldPersistTaps={false} //点击输入法意外的区域,输入法退出
   >
....
</ScrollView>
diff --git a/index.ios.js b/index.ios.js
index b0431d6..a1db2c4 100644
--- a/index.ios.js
+++ b/index.ios.js
@@ -11,6 +11,7 @@ var {
   Image,
   TextInput,
   Text,
+  ScrollView,
   TouchableOpacity,
   View
 } = React;
@@ -19,25 +20,31 @@ var {
 class CoolApp extends React.Component {
   render() {
     return (
-      <View style={styles.container}>
-        <Image
-          source={{uri: 'http://oss-hz.qianmi.com/qianmicom/u/cms/qmwww/201511/03102524l6ur.png'}}
-          style={styles.logo}/>
-        <TextInput
-          style={styles.input}
-          placeholder='username'/>
-        <TextInput
-          style={styles.input}
-          placeholder='password'
-          password={true}/>
+      <ScrollView
+        contentContainerStyle={{flex:1}}
+        keyboardDismissMode='on-drag'
+        keyboardShouldPersistTaps={false}
+        >
+        <View style={styles.container}>
+          <Image
+            source={{uri: 'http://oss-hz.qianmi.com/qianmicom/u/cms/qmwww/201511/03102524l6ur.png'}}
+            style={styles.logo}/>
+          <TextInput
+            style={styles.input}
+            placeholder='username'/>
+          <TextInput
+            style={styles.input}
+            placeholder='password'
+            password={true}/>

-        <TouchableOpacity
-          style={styles.btn}
-          onPress={() => console.log('press me')}
-          >
-          <Text style={styles.text}>login</Text>
-        </TouchableOpacity>
-      </View>
+          <TouchableOpacity
+            style={styles.btn}
+            onPress={() => console.log('press me')}
+            >
+            <Text style={styles.text}>login</Text>
+          </TouchableOpacity>
+        </View>
+      </ScrollView>
     );
   }
 }
(END)

但是我发现,输入法相互切换后,还是不退出。。。

好吧,来来来。。re-focus

diff --git a/index.ios.js b/index.ios.js
index a1db2c4..123716c 100644
--- a/index.ios.js
+++ b/index.ios.js
@@ -30,9 +30,13 @@ class CoolApp extends React.Component {
             source={{uri: 'http://oss-hz.qianmi.com/qianmicom/u/cms/qmwww/201511/03102524l6ur.png'}}
             style={styles.logo}/>
           <TextInput
+            ref={(username) => this.username = username}
+            onFocus={() => this.username.focus()}
             style={styles.input}
             placeholder='username'/>
           <TextInput
+            ref={(password) => this.password = password}
+            onFocus={() => this.password.focus()}
             style={styles.input}
             placeholder='password'
             password={true}/>
(END)

好了,为师累了,你先看代码。。。

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 */
'use strict';

var React = require('react-native');
var {
  AppRegistry,
  StyleSheet,
  Image,
  TextInput,
  Text,
  ScrollView,
  TouchableOpacity,
  View
} = React;


class CoolApp extends React.Component {
  render() {
    return (
      <ScrollView
        contentContainerStyle={{flex:1}}
        keyboardDismissMode='on-drag'
        keyboardShouldPersistTaps={false}
        >
        <View style={styles.container}>
          <Image
            source={{uri: 'http://oss-hz.qianmi.com/qianmicom/u/cms/qmwww/201511/03102524l6ur.png'}}
            style={styles.logo}/>
          <TextInput
            ref={(username) => this.username = username}
            onFocus={() => this.username.focus()}
            style={styles.input}
            placeholder='username'/>
          <TextInput
            ref={(password) => this.password = password}
            onFocus={() => this.password.focus()}
            style={styles.input}
            placeholder='password'
            password={true}/>

          <TouchableOpacity
            style={styles.btn}
            onPress={() => console.log('press me')}
            >
            <Text style={styles.text}>login</Text>
          </TouchableOpacity>
        </View>
      </ScrollView>
    );
  }
}

var styles = StyleSheet.create({
  container: {
    flex: 1,
    paddingLeft: 10,
    paddingRight: 10,
    alignItems: 'center',
    backgroundColor: '#F5FCFF'
  },
  logo: {
    width: 160,
    height: 160,
    marginTop: 100
  },
  input: {
    marginTop: 10,
    height: 40,
    borderRadius: 5,
    borderWidth: 1,
    borderColor: 'lightblue'
  },
  text: {
    fontWeight: 'bold',
    fontSize: 14,
    color: '#FFF'
  },
  btn: {
    alignSelf: 'stretch',
    alignItems: 'center',
    justifyContent: 'center',
    backgroundColor: '#3333FF',
    height: 40,
    borderRadius: 5,
    marginTop: 10
  }
});

AppRegistry.registerComponent('coolapp', () => CoolApp);

胡老师呕心沥血之作

@javascala 呕心不敢当 就是码字太累 👍

支持!

超级好

99个赞!

赞!

不知道是不版本的问题,InputText长度默认很小,需要添加alignSelf: 'stretch',属性才能自动撑开。还有就是ScrollView的那些属性,我在测试的时候,不填写也可以点击空白隐藏键盘,唯一问题是两个输入框直接切换也会隐藏键盘,需要按两次才可以。。。

和楼上同样的问题,应该是版本原因,输入法从一个框点击另一个框也会退出

没有模拟现实的请求网络。。。有点儿不开心

有时间加个fetch的使用

2016-10-17 16:39 GMT+08:00 liubobuzhidao notifications@github.com:

没有模拟现实的请求网络。。。有点儿不开心


You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
#3 (comment), or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAgiEGAAMxkClHfpvb52jYulBt_ffawdks5q0zQogaJpZM4GpAC3
.

life is short, you need python!

@nl101531 @yuzhewo 我们通过事件拦截解决了这个问题

为什么输入法键盘会挡住输入框?