开发者学堂课程【高校精品课-上海交通大学 -互联网应用开发技术:移动端App 2】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/76/detail/15780
移动端App 2
如图所示为book store的例子,右边为ios登录进去之后点输入可以看到详情然后可以返回。
左边是安卓的,它与ios差不多底下有输入弹出,然后就可以看到两边的内容是一样的,做了一个屏幕的适配
左右是一样的,然后两边都可以返回,我们要做的客户端应该就是这样的。
上述的例子如果跑的话,在工程打开的URLconfit里面要注意把它写成本地的ip,有可能在每一次加载之后ip会发生变化。如果想方便把家里的路由器设一下,苹果机器和windows不一样,点在网络里面然后看一下ip地址。
一定要与它对上才行,这里是15 locohost写完以后是有问题的,放在手机里跑不了,所以一定要改成ip。因此这个工程拿到以后必须要改正ip
回顾,第一是要构件化,所以开发的所有东西都是构件化。它有两种写法,第一种是function,还有一种是class Cat它的继承字Component,如果是function就直接是return就行,如果是class的话是有一个render,里面的内容和下面一样,两种是等价的。
JSX就是看到的</Text>这种标签,以及{getFullName(“RUN”, “TUM”, “Tugger”)}!脚本混编的这种情况。那么这个例子定义了一个Cat里面有一个getFullName函数,关键return有一个</Text>,不要忘记现在看到的是一个React Native的标签,显示一个文本说Hello,I am后面的东西是getFullName。用它得到,传了三个参数{ ‘’return firstName‘’ ‘’+secondName +”“+thirdName; },就直接把这三个合并一下中间加空格连缀起来。就会看到 Hello,I am{getFullName(“Run”,‘’ Tum”, ‘’Tugger”)}这样的东西
然后定义好空间的意思就是可以再构建自己的页面,比如说Cat可以用</View>组装整个页面,里面包含<Text>有一个<Textinput> 对应的右上角这两个东西。
然后刚才我们看到在每个标签可以有一个内联的inline这样一个样式跟之前看到的写法是一样的,然后底下有一个defaultValue= “Name me!”
这个开发是当我们定义好一个构建(Cat)之后,就可以在底下不断地复用它,所以说它是一个很重要的概念,必须去复用它。代码一定要抽样出来不能有大量重复代码。
然后看到的构建是可以带参数的,比如说这个构建它在构造的时候可以传递进来一个参数是(props),那么我们会给它一个name=“Maru/\”,name=“Jellylorum”.name=“Spot”,就是说所有参数封装在(props)里面。所以在{props.name}里面就拿到了name=“Maru/\”,name=“Jellylorum”.name=“Spot”这三个名字,所以现在三个Cat展示出来的Name就不太一样,肯定要写参数化构建。
Prop就是不能改的内容它一直在存活着,然后有一些参数比如source这里头看到的可以写死,但是它本身这个值可以通过Props传递。
可以有一个Props然后让它的source=props里边的某一个,比方确实有一个source的参数,然后就可以实现这样一个定值化。
State为了要去改变它,主要是在不同构建之间传递一些信息然后改变它。比如现在的Cat(props)它里面就会有{isHungry,setlsHungry},然后return下面是一个大的<View>在这个<View>里面上边是一个<Text>。看到下一行I am谁谁谁,这个信息来自于{ props.name },所以我们在创建这个Cat的时候,传递的“Munkustrap”“Spot”这些name进去,所以显示Munkustrap是一个人名、Spot是一个人名。
然后它说我现在饿还是饱,这件事情取决于isHungry的值。isHungry的值通过一开始它是为真的,所以它一出来就都是I am hungry,然后右下角这两个东西是按钮我们看到是<Button,这一行文本是一个按钮因为有两个Cat所以我们看到是这样的内容。</text>底下是<Button它在按下的时候会执行一个箭头函数onPass={()=>{,然后把setlsHungry设成(false)一旦设置成(false)它的状态就会发生变化,然后这个(false)就会取值“full”于是就会重新绘制这个页面,底下就会显示 “Thank you”底下可以看到Button上显示的内容title取决于isHungry这个值,如果是就是开始看到的true显示右下角的内容,点一下就显示“Thank you”。
刚才这个例子就来自于官方的文档,点一下右上角蓝色的按钮就会显示“Thank you”,而且可以看到下边还有一句disabled起不起作用取{!isHungry}这个反,也就是说这个确实是{!isHungry}的话那它就是否,那就是说它没有被禁用是可以点。一旦点了它变成不饿了,再取反就是true它点就被禁用了,所以鼠标就会点不动了状况就会发生一次刷新。
这个例子虽然简单但是要注意一下,其实这已经是react-native的东西了,可以注意一下“react-native”里面用到的就是{Button,Text,View}已经来自于“react-native”。它跟react其实没有区别,就是它运用了自己的标签它也存在着属性或者状态这样的东西,但是它在设置状态的时候跟之前看起来有点不一样,之前都是set data然后是哪一个属性什么值,它现在就是set这个属性把它设置成一个值。其他的没有任何差异,所以说只要react知道怎么写“react-native”很自然就转过来了。
这个就是react里面我们看到的“react-native”里面主要的一些东西。如果很习惯于react这些东西,不习惯于刚才的setIsHungry,那么可以完全照着react去写,它变成class CAT extends Component它的状态是{isHungey:true},然后在底下判断{this.state.isHungry}的状态这个isHungry是怎样props.name是怎样,setState这种方式把isHungry变成false。
所以跟react其实没差,原因就是上面这张图讲的很清楚,react-native其实就来自于react,只是它们的标签不同。
刚才看到这个动作是比较简单的,它点了一下按钮之后产生相应的动作。
那它也可以去捕获空间上的动作Core Component去执行一个相应的操作。
例如代码PizzaTranslator叫披萨翻译器,有两个状态一个叫text一个叫setText,一开始都是空字符串。然后有一个View这个view占位相当于上面要填充一下。TextInput对应的就是Something这个输入,它的高度是40,当什么都没输入的时候会显示“Type here to translate!”这句话。关键在底下word它的值就是text的值。如果取TextIput这个值还没有输就要取的值默认的就是text,以后再去修改的时候defaultValue就会发生变化,text就是它的值。所以要想获取TextIput的值就是拿这个text的值,底下说一旦Something这个输入发生变化,在输入的过程中其实就是文本发生了变化,它会触发onChangeText这个动作然后会执行一个操作,这个操作是拿到text然后调用setText(text)。就是一旦发生变化就把输入的值设置成{text}这个框里的值,然后相当于把这个属性里的值改掉,相当于setText(text)这段的含义是拿text去改写setText(text)。然后底下表情图片的内容仍然是Text,它的做法是拿Text往里面填的东西就会付给这个text,然后text还能付给setText(text)。完了之后去拿这个text.split然后用空格把它断开,就会得到一个数组然后调map,map对数组里的每一个元素做(word)=>word&&这个操作,每一个元素都付给word,word它要去做一个处理就是拿word&&去做一下雨,它俩的结果就是这个表情。
只要前面的单词不为空后面的结果就是这个披萨饼,如果单词是空最后的结果也是空。然后把最后的结果连起来再加一个空格。就是说如果输入多个单词底下就会出现多个披萨饼,删掉一个就会少一个。
例如输入一个单词打一个空格它就会多一个,这就是执行的逻辑。
重点不在逻辑上,而是怎么拿到这个text然后每次把它的值取到。只要输入的时候它就会做这样的事情,底下的状态就会发生时变化,setText(text)就会相当于前边的setIsHungry,写成函数的时候就是setIsHungry...这个属性,当写成类的时候就是setState里面写属性名和值构成的键值对,所以这个地方就把setText(text)的属性设置一下就相当于刷新跟text有关的内容都会刷新披萨饼的表情一个一个就出来了。
然后首先比较特殊电脑上没有的就是它有一个滚动屏ScrollView,只是说手机上不用特别区分,它都是在这个DIV里面上下拉动就行,但手机里面要拿手指头上下拖动,所以ScrollView在整个<ScrollView>里面写了一堆东西,这些东西仔细看其实什么都没有。就是Text和Image,而且显示的都是同一张图片。然后这张图片就来自于https://reactnative.dev/img/tiny_logo.pong这个位置,就是const logo的位置去它的URI宽度。
关键是它跑起来的时候,这个东西的滚动屏就会非常明显,当然可以看到安卓上的样子。
每次在这里等的时间会长一点
点过去,在这边等的时间要短一点,它显示的跟外部是类似的,只不过那手指头可以上下拖动。那么ScrollView就是支持去在屏幕上下滚动这个动作,拿手指头可以去点。
我们看到像通讯录这种方式平铺,用数组内容来显示,这也是FlatList里边可以看到,它也在一个大的<View里。这个<View里面有一个<FlatList,就这一个FlatList标签然后它首先FlatList没法显示data有一堆数组,就会有键值这样的东西,这只是data。到底要呈现什么,对于这个数组的每一项都要有一个文本,文本的标签里面显示style.item这个style指向{styles.container}定义了container这个容器的item的两个样式。
就是说整个大的<View外面要附和container这个样式,里面的item在显示每一个项的时候要下面的item样式,左边要填充一点东西不能顶着写字体大小为18,高度是44.所以上下拉的比较开。最下面的<Text的意思是要显示每一项key对应的值,所以item对应出来,上边的key对应的值就是右边框架里的名字。这是一个<FlatList,就是把它摊平没有做任何的限制和组织架构的设置。
如果不是摊平的,比如说这里上边都是D开头的J开头的在下边,相当于有两级这时不是一个Flat完全摊平一维的东西,像一个二级结构,先是字母分类然后再是里面的每一个人,SectionList就叫一个分区的list,有一个styles是对容器container的,还有一个sectionHeader是对D和J的,它们属于sectionHeader,在画的时候说清楚。在呈现内容的时候有一块用的styles有一块用的sectionHeader,它俩是不一样的。
对于Header来说主要的区别在于背景色发生了变化,前三个就是RGB的值就是247.247.247是一个比较白的值,如果是255.255.255就完全白的,而247是带一点灰度的东西,后边的α表示透明度,1表示不透明,0表示完全透明,所以它是不完全透明的。底下的没指定颜色就是默认的item在显示的时候就是白色,所以合起来用的大的<View指定的是container上边用22,所以在上边看到了22个像素这么宽的确切说应该叫做一个相对距离。意思是在不同手机上看到的会有差异,它会让你有适配的更好一点。
上面会有一个填充,然后它会说里头其实就有一个SectionList,是两级的所以它叫sections,只有两级所以看起来是{ {,每一项都是数组,有两个键值对。
第一个是sections的title是什么,看到的D、J,第二个是在data里面看到的是到底对应的那些数据,和刚才的组织方式有点差异。底下就是对sections里面每一项要去按照右下角的东西画里面的内容,然后绘制sectionHeader要对应每一个section就是D和J。它说按照section的style去把title显示出来就是D和J,上面就是对于每一个item直接显示出来。这个代码和前面的差异就是它分了两极。
底下就是最复杂的,跑每一个的时候可能都比较费时间,这个是配ios的,一定要记住这里面每一个都要装,已经有node就不用装,说明在之前开发前已经装了node。先要装watchman,然后装cocoapods这是苹果必须要跑起来的。当然要配一下右上角我们看到的ios的模拟器要注意每下一个模拟器它有3G多的下载量,其实在安卓里面也是差不多都是若干个G的规模下载。所以在电脑上千万不要下载太多的模拟器各下载一个就行。
意思就是模拟器来自于Xcode,在这个里面就会看到它的偏执爱好配置有很多的模拟器都是3G或2G下载量非常的大,下载之后按照操作进行。
安卓studio也是一样的,下载之后默认情况下没有做模拟器的配置也要配一下。除了页面上讲的东西本身的要求,底下是安卓studio的要求。
安卓studio是要装的,在里边选SDK,要装一个什么类型的SDK,就是安卓模拟的设备Devices,主要是看它的API的版本,可以在里面增加新的。
在里边可以看到有这些肯定是选手机的,里面有很多种手机可以选。上面是品牌,下面是屏幕。比如找不到具体的型号就用屏幕大小来选择,但是这个也一样非常的费空间。所以在开发的时候,如果跑千万不要安装好几个手机的模拟器,有一个就行了。这是一个配置的问题,这里是按照他要求的步骤配的。
唯一要提醒的是还得装一个jdk8然后为了安卓还得把jdk8放在jdk的路径里面,让它默认启动jdk8,否则仿真器跑不起来。
这是配置好之后能看到的样子,就是刚才看到的。真配置好了右上角蓝色在运行的时候可以选择两个创建一个,然后跑不同的他就会在不同的手机上创造一个浏览器,把模拟器启动起来在上面展示,trecaenative新工程在创建的时候可以选择。Cordora是要装控件的,就可以跑他的项目,然后把recate的项目放进来,比较偷懒不建议这么做。在配置的时候可以增加跑ios还是安卓,这个文件本身不需要动,他里面已经写好了ios和安卓。
要做的就是创建两个不同的,比如说增加一个npm配置。然后可以在里面选跑哪一个命令。跑完把名字区别一下,写ios、安卓就可以。
这两个命令跑完,切换一下就可以看到不同的模拟器上跑这个程序。
这是在配这个系统,也就是跑reactnative必须要做的事情。如果不喜欢reactnative就用别的也可以。但是前面的配置无论是用reactnative还是什么,这两个动作都是必须要做的。但是不是苹果机器这个配不了,所以studio一定要配对了,尤其jdk8容易出错。等能够创建一个新的reactnative什么都不写,让它去跑,能同时打开一个安卓的和ios的模拟器并且能看到这样的界面就说明配置上至少是成功的没有任何障碍,接下来才能说你写的代码是什么样子。
这些都跑成功后,接着看设计中会出现的问题。第一个是样式,这里面的样式他和样式表是一样的,可以像刚才看的创建一个样式然后写进去刚才所看到的所有的样式,然后因为它是在style里面,所以饮用的时候是style.container/style.redstyle.bigBule。然后这些东西就可以在标签里被引用。
我们在设计控件在手机里面存在高度宽度的问题,那么怎么设置呢。一种是直接指明比如宽度高度都是50背景颜色是如图的蓝色,还有100的150的颜色也都不一样。但是这种会碰到一个问题,手机屏幕大小不一样,如果高度500,会不会不能正确的去显示。
怎样去让他看起来差不多,符合人类的使用习惯。就是可以用Flex Dimensions,就是不说具体多宽的值,说它怎么填充在里面。Flex是一个灵活的尺寸,它不说宽度多少只说就在上面占一个单位宽的东西,然后两个三个单位。于是就发现在不同的机器上看他们的高度就有点差异,取决于手机屏幕。看到的是这样的关系三个等级就是1.5倍2倍3倍的关系,灵活的显示空间,没有说死和前边的就不一样。
一旦谈到这个问题就涉及到看起来很复杂,实际上很简单的东西。就是大家都是灵活的那这个布局应该在这个页面上运用Flexbox,只要用它宽度就不是固定的,所以在不同的屏幕尺寸上看到的布局大体相同,flex就是它在显示的时候这些值以什么样的方式填充到屏幕空间上。这个填充包括竖着的横着两种。
于是就有点复杂,举个例子,先可以指定它的方向。像Flex Direction可以是row也可以是这里看到的column,现在写三个View他们都有自己的颜色,当显示的时候可以指定大的View应该怎么去排列三个小View,首先它要是占一个高度首先的方向应该是按行,于是就是第一个图的显示。如果Flex写的column,就像第一个图竖着显示。如果用row写说是横着显示但是反过来了绿的在最前面,最后一个是color revors。差异是前面说的是尺寸,底下说给了一堆View怎么把它填到里面。可以理解最外面是带阴影的view里边有三个小的,现在指的是大的里边三个小的他们的方向应该是什么样的。
至于他们本身的尺寸,如果想要灵活的不想要这样的就要用前面的方式,他们的style也要是123那种。所以看起来比较复杂其实没有什么难度,就是按照自己想要的方式组织他们。
除了刚才看到的Flex Direction还有justify Content就是右边展示的几个它的不同取值。第一个就是直接从开头开始排、第二个是在中间、第三个在最底下,前提是column也可以是row,第四个是充满当前页面充满平分他们,第五个是其实就是他们之间距离的高度上下各有相同尺寸的空间。
上一个是在什么地方显示,这个是做对齐。比如指定按列去排,可以把它放在中间,就是说在排的时候可以把内容放在中间,还有一个问题是怎么对齐就是说可以在中间末尾拉伸,就是把里面的view按照什么布局放在一起。不是要写具体的尺寸而是根据屏幕适配,这样在不同的页面看到的尺寸几乎是一致的,也有可能做的很烂。如果用上一页底下的两种会发现如果view只有三种尺寸有比较大,就会发现页面很难看,只有三个选项支撑。所以说要根据时机内容判断用哪一种更好看。
底下有一个alinSelf是说不是全部按前面的对齐,每一个row可以指定自身对齐方式。相当于可以指定View里面的三个小的都是一种对齐方式,但某一个特殊的有自己的方式alin就和其他的不一样。
这个是在说Aline Content,就是View里面具体的内容怎么排。如果内容很长到底是拐弯过来还是直接排下去,去做滑动。然后内容太多的时候是往下的还是拐弯到旁边。
flexWrap表达的是刚才的类似的意思,就是它的内容怎么样排列。
这个是排他们的位置,就是按相对位置去排让他们占每一个空间多大,还是按照绝对位置排,哪怕空间比较大互相中间有重叠。
其实我们应该关系的是怎么处理,例如ButtonBasics是一个按钮的控件,按下去它要弹一个alert的对话框出来,说在这个按钮上做了点击的动作,底下要渲染什么内容。
先看const到style的样式表。
然后说按照不同的样式去显示。整个大的有一个<View它的里边又分了三个部分,第一个部分有一个按钮。如果按下就调当前的方法,上面写的是”Press Me”,还有一个按钮也是显示”Press Me”,差异是它的颜色有点不一样,然后下面还有一个按钮显示的内容不一样,按钮上的字不一样,但是按下去还是显示的这个内容,再往下也是字不一样但是和第二个的颜色一样。
所以看到的效果就是这样,两两颜色一样。
再看他们为什么会排列成刚才的样式。
样式在这里约定,我们看到有一个叫做
alternativeLayoutButtonContainer,它里面就用到了灵活的方式,然后是space-between的方式。在回过头一个是buttonContainer,一个是alternativeLayoutButtonContainer,右边两个是一种,左边是一种。
所以看到的两个上下排两个左右排。因为写了是按照row的方式滑动,大小是按照要显示的内容匹配,所以这边是THIS BOOKS GREAT!OK!比较短显示出来就只有一点,所以按照行的方式填充。我们看到的尺寸按照自动匹配。但是上面的两个按钮不一样,使用的是buttonContainer,直接说两边各留20,然后剩余填满。所以尽管字很短,但是它会填充整个页面。
这是它有关我们看到响应这个事件,其实还有很多短按、长按、上下拖动等等。
现在面临的最大挑战是能不能让模拟器在机器跑起来,保证基础环境不会出错。








































