captuerperfect 3.0 one 9软件运行不了 显示已停止工作是什么回事!

Captrue one 8 安装成DB 了 也就是后背专用的,怎么才能更改回pro。 重装就没有之前选择的那个界面了_百度知道
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。
Captrue one 8 安装成DB 了 也就是后背专用的,怎么才能更改回pro。 重装就没有之前选择的那个界面了
您的回答被采纳后将获得:
系统奖励15(财富值+成长值)+难题奖励30(财富值+成长值)
我有更好的答案
9,打补丁、将U盘插入被装电脑、下一个U盘启动盘制作工具。就“大白菜”吧,我比较熟悉。下一个网卡驱动,就用驱动精灵集成网卡版(200M左右)的,让你的电脑从DVD启动。2、下一个系统。3。选择之。关键步骤,重难点所在。3、接下来顺着走就行,然后选择U盘上的ISO文件。就ISO版本的,下面的事情比较麻烦但是无脑。注意看清楚C盘一定是主分区,你只能上网去找。安装版的最好。在“MSDN,然后点击桌面上快捷图标重新打开、等待系统安装完成。14、选择还原系统(默认的就是)。10、选择好盘,把系统选择在c盘就OK了。4、确认等待即可,我告诉你”下载一、U盘装系统。你要有两个工具:一个能够够格式化的U盘(8G及以上)、进入系统,然后使安装驱动精灵,这个时候你的电脑你就可以上网了。好了。关键步骤,重难点所在。每台电脑进入方式都不一样。1。下载方法自己百度。此举就是让你下一个无毒的系统。11、确认就可以了。有时候不用设置的,能直接就进。13。5。台式电脑的话就看主板的型号找。7、进入“大白菜”PE系统之后,选择“win8"那个吧。8、会自动弹出一个窗口,但是貌似不能用(可能是个BUG),会自动出现一个wim下拉的东西、设置bios,让电脑从硬盘启动。之后你可以模拟启动一次。————————————————————————————————不能开机不一定就是系统坏,若是硬件损坏就有可能无法安装。可直接买也可自己制作。2、设置bios。6。一般就是C盘。(分配盘你可以用里面的另一个工具diskgenuis)
C盘一般50G就够了,当然你想大一点也没有问题、用“大白菜”制作一个U盘启动盘、把你下的系统放到U盘生成的GHO文件夹里面,然后等个十分钟左右就要重启电脑了。应该是自动的。插入U盘,然后一键就可以了、设置bios,让你的电脑从U盘启动,你要忙活一阵子了。二、光盘装系统。光盘装系统比较简单。1、需要系统光碟一张。同时也把驱动精灵放进去。你关掉那个窗口。4,装驱动,还有另外能一台能联网的电脑,记不清了。12,但是就是那个窗口可以安装的
为您推荐:
其他类似问题
换一换
回答问题,赢新手礼包今日: 2|昨日: 3|帖子: 7806|会员: 65261|欢迎新会员:
友情链接提供云计算与安全服务
Powered by&figure&&img src=&/50/v2-fddcb9cd3acf5dfbb7fab52_b.png& data-rawwidth=&1517& data-rawheight=&798& class=&origin_image zh-lightbox-thumb& width=&1517& data-original=&/50/v2-fddcb9cd3acf5dfbb7fab52_r.png&&&/figure&&p&&b&这句话我真的憋了好久。Android 工程师只要关注我,我就能让你达到大师级水平,不是面试时的吹牛逼水平,不是自我欺骗的了解皮毛的水平,是真正的开发实力。以前我有这个自信,没这个证据。但现在,证据我也有了。&/b&&/p&&p&关注我的人都知道,我这三个多月来一直在网上分享关于 Android 自定义绘制的技术,并且在一周多前举办了一场线上的「仿写酷应用」活动,让我的粉丝仿写即刻、薄荷健康、小米运动、Flipboard 这四个软件中的几个经典效果,来自我验证一下这三个月来的学习成果。&/p&&p&简单地说,这事儿很成功(脸红)。&/p&&p&经过一周的投稿时间,共收到 97 份来自关注者的投稿(真的很多,出乎意料),而且做得都很棒。在四位原开发者的艰难筛选下,每个效果选出了一位优胜者。下面就是这四位优胜者的作品以及来自各位原开发者对他们的点评。&/p&&h2&&b&仿写作品&/b&&/h2&&h2&&b&仿写一:即刻&/b&&/h2&&p&二话不说,先看结果。&/p&&p&原效果:&/p&&p&&br&&/p&&figure&&img src=&/v2-bd293de0019bea6cdfa655fbc4453b98_b.jpg& data-caption=&& data-rawwidth=&136& data-rawheight=&124& data-thumbnail=&/50/v2-bd293de0019bea6cdfa655fbc4453b98_b.jpg& class=&content_image& width=&136&&&/figure&&p&&br&&/p&&p&仿写效果:&/p&&p&&br&&/p&&figure&&img src=&/v2-a9beaddfdaddc3_b.jpg& data-caption=&& data-rawwidth=&320& data-rawheight=&569& data-thumbnail=&/50/v2-a9beaddfdaddc3_b.jpg& class=&content_image& width=&320&&&/figure&&p&&br&&/p&&p&仿得很细致有没有。而且,这个仿写效果看似简单,其实是假象。它右边的数字跳动,是一个字符一个字符跳动替换的,而不是整个字符串一起被替换掉,这个需要对文字绘制的 API 有足够的熟悉才能做到。&/p&&p&这位仿写者叫刘金伟。在通知刘金伟成为「被选中的人」后,我对他进行了一个简短的微信采访。关于这次仿写的过程,刘金伟是这样对我说的:&/p&&blockquote&到这次仿写活动为止,HenCoder专栏已经出了8篇View绘制相关的技术文章了,每篇文章认真阅读之后我也根据例子进行实践操作,学到的一些东西也在项目开发中得以应用,正如文章中所说,在自定义View相关方面更加自如了。&br&看到这次HenCoder的仿写活动,就有点跃跃欲试,发现这几个效果都挺不错的,和朋友聊了聊之后就选了这个经常会用到的点赞功能进行实践。这个点赞效果经过我分析发现虽然内部动画挺多,但是所用到的技术点都是在HenCoder中讲到过的,所以在简单的分析之后就开始写,大约花了大半天时间就基本完成了,整个过程也没太多技术难点,做出来后还给朋友炫耀了一番。 &br&最后再次由衷的感谢HenCoder专栏,为了提升大家技术水平而做的事,非常敬佩。&/blockquote&&p&不谢不谢,哈哈。&/p&&p&&br&&/p&&figure&&img src=&/50/v2-5ab4caa76f128383cbcb2_b.jpg& data-caption=&& data-rawwidth=&252& data-rawheight=&200& class=&content_image& width=&252&&&/figure&&p&&br&&/p&&h2&&b&原作者点评&/b&&/h2&&p&对他的作品进行点评的是即刻的 Android Leader 罗琼。他对这份仿写的评价似乎还不错(知乎粘贴文本的支持一般般,所以你们将就看一下。):&/p&&blockquote&仿写效果的点评,主要针对以下几点&/blockquote&&ol&&li&对原创的还原程度&/li&&li&示例的完备程度(可测试性)&/li&&li&项目规范&/li&&li&代码实现&/li&&/ol&&p&&b&对原创的还原程度&/b&&/p&&h2&这位同学仔细观察了即刻点赞效果&/h2&&ul&&li&使用的资源应该是反编译即刻 apk 之后拿到的&/li&&li&实现了点赞和取消点赞两种效果&/li&&li&实现了左边图片部分的动画&/li&&li&实现了右边数字部分的动画&/li&&/ul&&p&未实现的部分&/p&&ul&&li&点赞对 touch 操作的处理(只处理了 click 操作)&/li&&li&点赞效果在图片上的先放大后缩小&/li&&li&散开的点的放大效果&/li&&li&整体动画的细节优化&/li&&/ul&&p&&b&示例的完备程度&/b&&/p&&h2&这个是做得比较好的&/h2&&ul&&li&可以直接设置具体数字,这样方便做边界条件(进位退位)的测试。&/li&&li&上传了可以直接安装的 app-release.apk ,方便先安装看效果。&/li&&li&README 有对动画实现的说明。&/li&&/ul&&p&&b&项目规范&/b&&/p&&ul&&li&没有 .idea 这种不该上传的文件夹&/li&&li&.gitignore 也是专门修改过的&/li&&/ul&&p&可以优化的部分&/p&&ul&&li&对 android support 包的依赖,不要依赖 alpha 这种版本,尽量依赖稳定版&/li&&li&代码文件都需要进行格式化,包括 xml&/li&&li&mdpi 的资源不再需要了&/li&&li&自定义 View 的 attr 的命名,需要有自己的命名空间(前缀)&/li&&li&自定义 View 的变量命名不规范,一会儿有 m ,一会儿有下划线&/li&&/ul&&p&&b&代码实现&/b&&/p&&h2&作者把图片和文字写在一个类里面了,这样的话不太灵活,即刻 app 现在在某些主题下的点赞效果不是大拇指,比如&b&逝者&/b&这个主题就是蜡烛,所以建议图片和文字还是分成两个类来搞。&/h2&&blockquote&对点击事件的防重处理好像有点问题,另外连续点击是否直接对之前动画进行 cancel 也需要斟酌一下。&br&整体的实现代码上冗余逻辑比较多,并且每一个函数内部每一行语句并没有完全去考虑,如对 specMode 的 switch case ,没有穷尽所有的可能值。&br&图片这块的实现,整体的思路是通过事先画好各种元素,然后通过属性动画的方式,但自定义的属性动画的方法是通过反射调用的,整个类里面并没有显示调用,对于& 此类不是很复杂的动画,建议还是用系统自带的属性比较好。&br&文字这块的实现,涉及到偏移、颜色、以及分离出变化和不变的部分(作者对文字的解剖分析得很好),但代码的复用程度不高。&br&总体而言,项目完成度比较高,恭喜获得本次仿写即刻点赞效果的冠军,不过真正商用的话还是有不少需要考虑的,尤其是代码规范上需要加强,再好的实现和算法,如果代码不够规范,恐怕看得人也会比较累,希望再接再厉。&/blockquote&&p&评价得好详细啊,我在读这份点评的过程中多次遇到「哇塞好细,如果是我的话这里肯定要被扣分了」的情况。&/p&&h2&&b&仿写二:薄荷健康&/b&&/h2&&p&依然是先上效果:&/p&&p&原效果:&/p&&p&&br&&/p&&figure&&img src=&/v2-beca91c59f7_b.jpg& data-caption=&& data-rawwidth=&412& data-rawheight=&252& data-thumbnail=&/50/v2-beca91c59f7_b.jpg& class=&content_image& width=&412&&&/figure&&p&&br&&/p&&p&仿写效果:&/p&&p&&br&&/p&&figure&&img src=&/v2-0bbd745cdf183dd50ae8_b.jpg& data-caption=&& data-rawwidth=&367& data-rawheight=&631& data-thumbnail=&/50/v2-0bbd745cdf183dd50ae8_b.jpg& class=&content_image& width=&367&&&/figure&&p&&br&&/p&&p&以假乱真了有没有?&/p&&p&这份仿写的作者叫严积楷。他对仿写过程的回顾是这样的:&/p&&blockquote&我觉得仿写,首先就是要了解清楚仿写对象的细节,所以还是自己亲自体验一下比较好,所以就下载了薄荷健康APP,发现尺子UI已经改变了(这样就提醒了我要做一个适合多变需求的控件),但是一些特性也是和效果图差不多的:触摸滑动后是有惯性滚动的光标保持在中间,不随尺子滚动光标选中的刻度只会是0.1整点让触摸滑动、惯性滚动之后,尺子会回滚到最近的整点刻度,如最后滑动到66.5和66.6中间靠右,则回滚到66.6。&br&了解了特性之后,就是想着怎样实现了:首先就是画出刻度和数字,这里是采用一下子就画出所有刻度的方法,然后通过滑动方法scrollBy()来移动画面(不知道这样系统会不会对尺子那些不在屏幕显示的部分进行绘画计算的,我当时是加上滑动之后,发现很可以滑的流畅,所以就这样了,现在想想还可以处理一下的)。触摸控制方面,因为之前分析过GestureDetector,了解了它的实现,所以这里就试着直接重写onTouchEvent()和OverScroller配合实现惯性滑动。对于刻度的计算,这里通过滑动位置getScrollX()来计算当前刻度,而又通过把滑动结束后的刻度四舍五入之后,计算对应的ScrollX来让尺子最近的整0.1点刻度。对于光标的绘制,由于这里是采用了scrollBy()的方法移动画面,所以也没有找到一个好的方法让光标不随尺子移动,所以就外层加入一个ViewGroup重写dispatchDraw()方法在这里绘制(这个方法执行在onDraw()之后,在这里绘制才不会被尺子的刻度覆盖掉)。&br&主要的实现思路就是这样了,还有一些细节,如代码封装这些比较常见的就不详细说了,大家可以看代码,已经写好了注释,欢迎指教小弟。&/blockquote&&p&「欢迎指教小弟。」高仿到这种程度竟然还求指教,这谦虚的态度莫非是讨打?有人想当面指教他一下吗?&/p&&h2&&b&原作者点评&/b&&/h2&&p&对这份作品进行点评,我请到的是薄荷健康的 Android 工程师 loody。&/p&&blockquote&&b&还原度&/b&&/blockquote&&h2&99分,多一分怕你骄傲。&/h2&&blockquote&&b&实现思路&/b&&/blockquote&&ol&&li&背景绘制 顶部基准线+纯色背景。&/li&&li&刻度绘制,包括长、短刻度及长刻度下的文字绘制 这块是整个卷尺最复杂的部分,整个卷尺有最大最小边界,所以整个刻度的绘制会基于最大、最小值以及定义的最小刻度单位来从左往右依次绘制,同时要保证当前选中的位置位于屏幕中央。&/li&&li&基准线绘制 位于屏幕中间、可以有多种样式、以上绘制必须按照顺序依次绘制。&/li&&li&手势滑动处理、惯性滑动 通过监测 MotionEvent 里的 ACTION_DOWN、ACTION_MOVE、ACTION_UP、ACTION_CANCEL 事件来监测滑动距离来进行重绘,如果满足Fling,则使用OverScroller来计算速度来进行惯性滑动。&/li&&li&智能精准定位 滑动完之后需要进行精准定位,必须回到基准线最近的刻度,用作者的话就是滑动到66.5和66.6中间靠右,则回滚到66.6。&/li&&/ol&&p&&b&优点&/b&&/p&&h2&整个实现的非常好,所有的要点都实现了,特别是精准定位体验做得很棒,在拓展性方面,也定义了很多自定义属性,同时也上传到 Maven 仓库,方便其他人调用。&/h2&&blockquote&&b&不足之处&/b&&/blockquote&&ol&&li&背景和基准线的绘制和刻度的绘制进行了分离,其实没必要,因为他们的绘制并没有冲突;&/li&&li&在刻度绘制上,屏幕之外的刻度其实可以不用绘制;&/li&&li&卷尺的小刻度模式可以再丰富一些,一般两个大刻度之间有10个小刻度,当然也有2个、5个情况;&/li&&li&对外开放的初始化方法应该更丰富一些,因为很多时候我们的边界值并不是固定的。&/li&&/ol&&p&&br&&/p&&p&薄荷的卷尺效果要实现起来是有非常多的细节的。loody 要从几十份仿写中选出这一份,还要写出这么细致的点评,别的我不想说,我只想对他说一句:苦了你了。另外也更想回头对上面的仿写者严积楷说一句:你太苦了!&/p&&h2&&b&仿写三:小米运动&/b&&/h2&&p&原效果:&/p&&p&&br&&/p&&figure&&img src=&/v2-fcfba8ad7fae7aface2377e6_b.jpg& data-caption=&& data-rawwidth=&504& data-rawheight=&412& data-thumbnail=&/50/v2-fcfba8ad7fae7aface2377e6_b.jpg& class=&origin_image zh-lightbox-thumb& width=&504& data-original=&/50/v2-fcfba8ad7fae7aface2377e6_r.gif&&&/figure&&p&&br&&/p&&p&仿写效果:&/p&&p&&br&&/p&&figure&&img src=&/v2-c8bbc451d92ecaac446f8c9d_b.jpg& data-caption=&& data-rawwidth=&337& data-rawheight=&553& data-thumbnail=&/50/v2-c8bbc451d92ecaac446f8c9d_b.jpg& class=&content_image& width=&337&&&/figure&&p&&br&&/p&&p&仿得也是超棒。这件仿写作品的作者叫陈浩,他的仿写过程回顾充满了认真和辛酸:&/p&&blockquote&之前没有太多做UI的经验,所以一开始我是比较乐观的,但最后花了整整5个晚上才做完。&br&我编程属于比较严谨(啰嗦)的那种,所以准备工作时我把gif下下来用电脑逐帧看了,还借了朋友的小米手环来看实际的动画(最新版有点出入)。然后把动画流程写下来,没有做什么模块规划,就开始编程了。&br&最开始动手时我只有动画参数可配置和要做动画状态机的这两个想法,后面整个代码结构都是在编写的过程中多次重构产生的。毕竟代码是程序员的第二张脸(我说的),给别人看的时候还是想写的更好一些。但这也存在一些过度设计的情况,导致完成的时间变长了不少。比如,我看到那个转动的烟花圆环线条不是一成不变的,于是天马行空设计出来一套的动画运动公式:这个线条是椭圆的一段圆弧,其圆心,宽和高的偏移都是随机参数,变化量d由变化速度v决定,变化速度v由外力1.衰减常量力,2.速度平方成正比的阻力,3.定时触发的随机力决定(戏真多)。结果导致动画参数调整就花太多时间,也改了好几版才稳定下来。。&br&写得好的地方的话,因为工作原因会比较考虑封装,可维护性,可拓展性这些,这些方面我觉得还是做到位了的。&/blockquote&&p&说实话,在发布仿写征稿文的时候我就知道,肯定每个效果都有人能完成,但陈浩的这份作品还是让我有点意外:你仿得也太真了!但看了他的这份回顾,我觉得我知道为什么他写得这么好了。&/p&&h2&&b&原作者评价&/b&&/h2&&p&我很高兴请到了这个效果的原作者,来自小米运动团队的卜冬旭来点评这份作品:&/p&&blockquote&&b&总体评价&/b&&/blockquote&&h2&相当不错。。。(本来想这四个字完结点评了的,因为模仿的效果相似度很高了,而且仅凭一个gif图,在很短的时间做出这样的效果,真的挺厉害的。同时up主提供的&a href=&/?target=https%3A///SickWorm/MISportsConnectWidget& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&代码&i class=&icon-external&&&/i&&/a&里的注释也很清晰,规范,可以很容易理解实现的原理。但是秉着认(wu)真(ren)负(zi)责(di)的态度, 还是来吹毛求疵一下。)&/h2&&blockquote&&b&细节对比&/b&&/blockquote&&h2&这块的动效是小米运动app首页的效果。示例GIF图中包含了2部分效果,一个是小米手环连接过程中效果,就是一大堆杂乱的白色渐变的圆圈在转,圆圈的起始位置有一个往后发散的粒子效果。另一部分就是小米手环连接成功后的效果, 也就是几个白色透明度不等的渐变的圆环叠加在一起,最外圈层次渐变的光晕效果围绕圆环转动。&/h2&&h2&下面具体分析对比下这几块动画效果.&/h2&&blockquote&&b&圆圈的叠加效果&/b&&/blockquote&&h2&我这边用了8个圆圈,每个圆圈的centerX, centerY有微小的差别,半径有微小的差别。通过SweepGradient来设置它的渐变,从纯白到20%左右透明度的白色,每个圆圈canvas.rotate的角度也有微小的差别。当然以上所有参数都可以自己任意调节,来达到参差不齐的效果, 只要整体效果不离谱就可以了。我对于其中一些参数用的都是random, 这块没有个标准。杂而不乱, 达到这个效果就行. :D &/h2&&blockquote&&b&粒子效果&/b&&/blockquote&&h2&比较麻烦的就是这块粒子效果。一方面要实现功能,一方面性能也要满足,不能卡顿。模仿的效果就这一块有点小问题, 一个是半径有点大了,然后透明度可以稍微降的快一点, 再聚拢一点效果会更好。(坏笑.jpg) 这块调起来是相当的麻烦。 这块粒子产生在第一个效果中圆圈的最亮的地方,也就是透明度最低的地方。具体位置可以从图中看一下。&/h2&&figure&&img src=&/50/v2-3b82a26f3a73b92baded0c2_b.jpg& data-caption=&& data-rawwidth=&337& data-rawheight=&351& class=&content_image& width=&337&&&/figure&&p&&br&&/p&&blockquote&粒子产生的位置是竖着的线的位置, 也就是随机在这条线上生成初始粒子。 发射的角度大概是左边2个线之间。第一个不是水平线,这两条线的角度可以慢慢的调整,从而找到合适的效果。 需要注意一点的就是, 粒子发射的角度需要比较精细的控制, 具体点说就是因为产生粒子的位置不是一个点,而是一条很短的线,所以尽量不要让粒子发射的延长线在很短的位置相交, 如图&/blockquote&&figure&&img src=&/50/v2-6a0d93a2cead2cd025702c_b.jpg& data-caption=&& data-rawwidth=&461& data-rawheight=&354& class=&origin_image zh-lightbox-thumb& width=&461& data-original=&/50/v2-6a0d93a2cead2cd025702c_r.jpg&&&/figure&&p&。 &/p&&blockquote&关于粒子发生器的原理这里就不赘述了,我这里是通过距离超过一定数就重新生成一个粒子来控制的,当然也可以通过半径大小或者透明度来控制。Up主是通过透明度来控制的,也是没关系的。靠近发生器位置的粒子半径稍微大一点,然后半径是递减的。透明度也是递减的。至于性能问题,也不属于这个文章的范围内了。可以看下up主代码。 &br&&b&圆环效果&/b&&/blockquote&&h2&圆环主体是五个渐变的圆环叠加在一起,其实不能算作是圆环,应该是一个圆环和4个椭圆环。 绘制的时候,第一个渐变的圆环正常绘制,后面的椭圆环通过drawArc来绘制。保证它们五个环的left,right,`bottom一样, top参数为依次递增一定的大小。同时需要注意一点的就是颜色最深的圆环,也就是透明度最低的环,不是椭圆环放在最后绘制,这样可以盖住其他稍高透明度的环,这样不会看出叠加部分因为用的SweapGradient导致的叠加的效果。而是会觉得主体是一个整个系统,光晕是独立系统。不然能比较清楚的看出五个环的叠加效果。&/h2&&blockquote&&b&多余的效果&/b&&/blockquote&&h2&其实那个整体效果,带有一点上下振动的这块是因为程序的下拉上推导致的,不属于这块的动画效果,没想到也给做出来了。(捂脸.jpg)&/h2&&blockquote&这块效果看着挺炫的,其实使用&a href=&/?target=http%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&HenCoder&i class=&icon-external&&&/i&&/a&里绘图的基础知识就可以实现,麻烦的地方就在于细节的调整, 可能调个参数就要重新跑一下程序, 还是相当痛苦的。想了解完整的动画效果,可以从仿写的&a href=&/?target=https%3A///SickWorm/MISportsConnectWidget& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&代码&i class=&icon-external&&&/i&&/a&里看到, 也可以来&a href=&/?target=http%3A///jobs& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&这里&i class=&icon-external&&&/i&&/a&看。&/blockquote&&p&最后竟然被冬旭兄弟打了我一个猝不及防的广告……&/p&&p&&br&&/p&&figure&&img src=&/50/v2-5ab4caa76f128383cbcb2_b.jpg& data-caption=&& data-rawwidth=&252& data-rawheight=&200& class=&content_image& width=&252&&&/figure&&h2&&b&仿写四:Flipboard&/b&&/h2&&p&原效果:&/p&&p&&br&&/p&&figure&&img src=&/v2-b661be9c25a8e99b72e1_b.jpg& data-caption=&& data-rawwidth=&490& data-rawheight=&432& data-thumbnail=&/50/v2-b661be9c25a8e99b72e1_b.jpg& class=&origin_image zh-lightbox-thumb& width=&490& data-original=&/50/v2-b661be9c25a8e99b72e1_r.gif&&&/figure&&p&&br&&/p&&p&仿写效果:&/p&&p&&br&&/p&&figure&&img src=&/v2-9da7d2c9bb811cc57cf36_b.jpg& data-caption=&& data-rawwidth=&582& data-rawheight=&1036& data-thumbnail=&/50/v2-9da7d2c9bb811cc57cf36_b.jpg& class=&origin_image zh-lightbox-thumb& width=&582& data-original=&/50/v2-9da7d2c9bb811cc57cf36_r.gif&&&/figure&&p&&br&&/p&&p&这个效果可谓是人气超高了。我在之前的几篇文章或视频中都展示过这个效果,但只是说「用我教的技术就能实现」,却没有展示过具体的实现代码。很多人找我要实现,我也都没给过,为的就是这一天,让我的读者自己实现出来,我只帮你展示。&/p&&p&这个仿写的作者叫贾元斌,它的仿写过程回顾如下:&/p&&blockquote&仿写“翻页效果(加强版)”这个动效的想法,源于凯哥讲解几何变换章节提到的一个动画栗子,很炫酷,极大地激发了偶的好奇心。 &br&做动画的过程,其实就是一个典型的“发现问题,分析问题,解决问题”的过程。所以大概的流程就是,先拆解分析,动画是怎么“动”的,然后再去解决问题,想如何使用Android提供的Api实现“这么动”。 把gif图放在手机上一帧一帧地截屏,然后逐张观察,可以发现这个动画是由三个部分组成的: - 开始动画,一个Y轴三维旋转-45度动效 - 中间动画,比较复杂,图片右半边三维旋转,同时三维旋转的“转轴”平面内旋转了-270度,左半边图不变 - 结束动画,一个绕Y轴三维旋转30度动效 开始和结束的动画比较简单,camera旋转就能实现,重点分析中间的动画: 右半边三维旋转的时候,canvas先旋转,再裁切,再使用camera执行三维动效,然后保存camera效果,最后再旋转回来。问题分析清楚,具体到代码,拿canvas和camera的几何变换+范围裁切,就能实现了。 &br&需要注意的坑:camera执行几何变换时,我们会把canvas的中心点移动到原点,所以这个时候canvas再执行其他变换(比如范围裁切),要用移动后的坐标系计算。 最后一点,不要忘记做糊脸校正,不然图片尺寸变大时,就没法看了…&/blockquote&&p&贾元斌在最后提到的「糊脸修正」是我自己造的词,我觉得好形象啊,佩服自己。&/p&&p&&br&&/p&&figure&&img src=&/50/v2-5ab4caa76f128383cbcb2_b.jpg& data-caption=&& data-rawwidth=&252& data-rawheight=&200& class=&content_image& width=&252&&&/figure&&p&&br&&/p&&p&另外,一直找我要实现的,请到文末自取贾兄的源码。&/p&&h2&&b&原作者评价&/b&&/h2&&p&这个点评者我熟悉,我前同事,来自 Flipboard 的段建华(技术小黑屋),以前我在 Flipboard 的时候我俩挨着坐的。&/p&&blockquote&&b&总体点评&/b&&/blockquote&&h2&运行效果良好,思路比较清晰。总的来说不错。&/h2&&blockquote&&b&思路与实现&/b&&/blockquote&&ul&&li&在readme文件中给出了具体的实现方案并进行逐步拆分,同时给出了需要的理论分析和一些注意事项&/li&&li&提供了在布局文件中设置图片资源的实现,同时也支持在代码中设置。可扩展性较强&/li&&li&做到动画的执行实现与View分离,便于在不修改代码的情况下,更改动画的配置,比如duration和delay时间等&/li&&/ul&&p&&b&代码质量&/b&&/p&&ul&&li&配合以必要的注释,便于理解。&/li&&li&MainActivity中handler.postDelayed已经位于UI线程,无需在进行runOnUiThread调用&/li&&li&对于degreeY等方法使用Keep来注解修饰,既解决了编译器的报警提示也避免了一些因为Proguard优化删除无用方法带来的潜在的问题,这一点体现了作者很周全考虑。&/li&&/ul&&p&&b&其他&/b&&/p&&ul&&li&祥云图标的Flipboard Logo很赞&/li&&li&替代的google_map提供了三种dpi对应的资源,+1&/li&&/ul&&p&&b&改进与完善&/b&&/p&&ul&&li&MapView 类的javadoc写成“整个动画拆分成了三部分”有些不妥,一般为类的功能介绍&/li&&li&每一个commit的提交信息都需要概括修改的内容,不宜出现简单的update来了事&/li&&li&View命名成MapView,可能存在继续优化改善的空间&/li&&li&Repo的命名建议更加和参赛作品有关,这样便于筛选人员更好的快速辨识并分发给对应的评委。&/li&&/ul&&p&&br&&/p&&p&看了建华的评价,我最大的感受就是,他果然还是这么认真,一些很细节的地方他也都提到了。另外可能是出于谨慎考虑,建华对于这份仿写实现和 Flipboard 的内部代码实现没有进行比对。而我作为一个已经离职的员工,我就……当然也不会泄露前公司的源码啦。但我要特别说明一下的是,贾元斌的仿写代码中的实现虽然和 Flipboard 的内部实现不完全一样,但执行效率和代码可读性都不比 Flipboard 的实现差。&/p&&p&至于 Flipboard 的内部实现到底是怎样的?我就不告诉你……&/p&&h2&&b&优胜者中的优胜者&/b&&/h2&&p&上期内容我说过,由于赞助方爸爸 &a href=&/?target=http%3A//insight.io& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&insight.io&/span&&span class=&invisible&&&/span&&i class=&icon-external&&&/i&&/a& 的支持,这次活动的四位优胜者中,还会有一位特别优胜者,他获得的奖品和另外三位不一样,他将获得一步 Google Clips 相机:&/p&&p&&br&&/p&&figure&&img src=&/50/v2-ba36a73c86adebe48bf9de2_b.jpg& data-caption=&& data-rawwidth=&794& data-rawheight=&552& class=&origin_image zh-lightbox-thumb& width=&794& data-original=&/50/v2-ba36a73c86adebe48bf9de2_r.jpg&&&/figure&&p&&br&&/p&&p&这位优胜者将通过微博投票得出,投票链接:&a href=&/?target=http%3A///poll/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&微博 投票 --HenCoder「仿写酷应用」投票&i class=&icon-external&&&/i&&/a& &/p&&h2&&b&资源链接&/b&&/h2&&p&几位仿写者的仿写代码链接在这里。这里贴的是 &a href=&/?target=http%3A//insight.io& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&insight.io&/span&&span class=&invisible&&&/span&&i class=&icon-external&&&/i&&/a& 从 github 同步的代码库,用 &a href=&/?target=http%3A//insight.io& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&insight.io&/span&&span class=&invisible&&&/span&&i class=&icon-external&&&/i&&/a& 来读源码超级爽(具体怎么爽,你点开就知道了),真的感谢 &a href=&/?target=http%3A//insight.io& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&insight.io&/span&&span class=&invisible&&&/span&&i class=&icon-external&&&/i&&/a& 的在礼物支持之外还给予我的技术支持。&/p&&p&&b&即刻仿写&/b&: &a href=&/?target=https%3A//insight./arvinljw/ThumbUpSample/tree/master/& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://&/span&&span class=&visible&&insight./a&/span&&span class=&invisible&&rvinljw/ThumbUpSample/tree/master/&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&br&&br&关于仿写者刘金伟:&br&&br&github: &a href=&/?target=https%3A///arvinljw& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://&/span&&span class=&visible&&/arvinljw&/span&&span class=&invisible&&&/span&&i class=&icon-external&&&/i&&/a&&br&&br&简书: &a href=&/?target=http%3A///u/8fcc3372beb7& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://www.&/span&&span class=&visible&&/u/8fcc3372b&/span&&span class=&invisible&&eb7&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&/p&&p&&b&薄荷健康仿写&/b&: &a href=&/?target=https%3A//insight./totond/BooheeRuler/tree/master/& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://&/span&&span class=&visible&&insight./t&/span&&span class=&invisible&&otond/BooheeRuler/tree/master/&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&br&&br&关于仿写者严积楷:&br&&br&github: &a href=&/?target=https%3A///totond& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://&/span&&span class=&visible&&/totond&/span&&span class=&invisible&&&/span&&i class=&icon-external&&&/i&&/a&&br&&br&CSDN: &a href=&/?target=http%3A//blog.csdn.net/totond& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&blog.csdn.net/totond&/span&&span class=&invisible&&&/span&&i class=&icon-external&&&/i&&/a&&br&&br&邮箱: &a href=&mailto:yanzhikai_&&yanzhikai_&/a&&/p&&p&&b&小米运动仿写&/b&: &a href=&/?target=https%3A//insight./SickWorm/MISportsConnectWidget/tree/master/& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://&/span&&span class=&visible&&insight./S&/span&&span class=&invisible&&ickWorm/MISportsConnectWidget/tree/master/&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&br&&br&关于仿写者陈浩:&br&&br&github: &a href=&/?target=https%3A///SickWorm& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://&/span&&span class=&visible&&/SickWorm&/span&&span class=&invisible&&&/span&&i class=&icon-external&&&/i&&/a&&/p&&p&&b&Flipboard 仿写&/b&: &a href=&/?target=https%3A//insight./sunnyxibei/HenCoderPractice/tree/master/& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://&/span&&span class=&visible&&insight./s&/span&&span class=&invisible&&unnyxibei/HenCoderPractice/tree/master/&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&br&&br&关于仿写者贾元斌:&br&&br&github: &a href=&/?target=https%3A///sunnyxibei& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://&/span&&span class=&visible&&/sunnyxibei&/span&&span class=&invisible&&&/span&&i class=&icon-external&&&/i&&/a&&br&&br&微博: &a href=&/?target=https%3A///& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://&/span&&span class=&visible&&/&/span&&span class=&invisible&&&/span&&i class=&icon-external&&&/i&&/a&&br&&br&微信: sun521xibei&br&&br&个人博客: &a href=&/?target=http%3A//.cn/& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&.cn/&/span&&span class=&invisible&&&/span&&i class=&icon-external&&&/i&&/a&&/p&&h2&&b&关于几位点评者&/b&&/h2&&p&想了解几位点评者,想和他们一起工作?赶快看这里。&/p&&h2&&b&即刻&/b&&/h2&&blockquote&罗琼给了我一份超长的文案,我嫌长想给他删点,可又觉得这份文案写得已经超级棒,哪一句都删不得,所以干脆把这份文案最重要的关键词提取了出来,被这些关键词吸引了的可以点下面的链接进去看详情:&/blockquote&&p&即刻的关键词:&/p&&p&流浪猫、400 平米、自带 Gif 表情包文化、健身房、台球桌、无人机、电玩设备、足球队、男女比例平衡、年轻、一年两次免费国内外纯玩 Outing、La Marzocco咖啡机 + Volcan 豆(这个看不懂)、咖啡师、Herman Miller人体工学座椅、公费参加 Google IO & WWDC&/p&&p&好吧我只提取了「福利」部分的关键词,因为我最关心这个……其实即刻团队做的事情更有意思,不过篇幅有限就不给它展示的机会啦(任性脸),有兴趣的可以点链接去看详情:&/p&&p&&a href=&/?target=https%3A///t/388064& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://www.&/span&&span class=&visible&&/t/388064&/span&&span class=&invisible&&&/span&&i class=&icon-external&&&/i&&/a&&/p&&p&哦对了,工作地点上海。&/p&&h2&&b&小米运动&/b&&/h2&&p&冬旭兄比较委婉地把招聘广告插进了点评的最后(就是上面那句「想了解完整的动画效果,可以从仿写的代码里看到, 也可以来这里看」的「这里」)。不过我还是要在这里再贴一次他们的招聘链接,让需要的人更清楚地看到:&/p&&p&&a href=&/?target=http%3A///jobs& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://www.&/span&&span class=&visible&&/jobs&/span&&span class=&invisible&&&/span&&i class=&icon-external&&&/i&&/a&&/p&&p&「华米科技」,又是一个米。你猜小米旗下到底有多少种米?&/p&&h2&&b&Flipboard&/b&&/h2&&p&我的老同事建华给我发的「广告」是这样的:&/p&&blockquote&此次仿写的参考目标之一为 Flipboard 的折页效果,Flipboard 中国团队目前进行了有史以来最特别、动作最大的一次产品升级改版,推出全新产品——红板报,它将带来更对味的个性化内容推荐、更广阔的全球化新闻视野、更生动的杂志化浏览体验。通过红板报,要将全球最优质的新闻内容用最好看的方式呈现,精简产品功能回归到阅读最核心使命:新闻可以很好看。&/blockquote&&p&嗯,Flipboard 中国改为名红板报之后,作为开发者之一的建华很自豪,也很希望推荐给大家用。至于招聘链接……建华表示「什么招聘链接?」&/p&&p&Flipboard 北京办公室暂时没有 Android 职位空缺,所以建华其实是在给他自己打广告(哈哈哈我写了个好 App),大家快去打他呀。&/p&&h2&&b&薄荷健康&/b&&/h2&&p&关于招聘,loody 和建华一样对我表示目前没有需求,只是告诉我「能提到薄荷健康就最好了」。&/p&&p&只付出不求回报的好同志。好吧,那我就来负责他们的文案吧:&/p&&p&薄荷健康,真呀真健康,装了薄荷健康,又瘦又健康。耶。&/p&&h2&&b&感谢&/b&&/h2&&p&最后非常感谢四位点评者的帮助,这次活动的响应度比我的预期大很多,各位点评者光是审阅投稿就花了一天的时间,审完还要来帮我写点评语,写得短的还要被我打回去重写……真的辛苦了,你们。谢谢!&/p&&p&另外,还要感谢 &a href=&/?target=http%3A//insight.io& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&insight.io&/span&&span class=&invisible&&&/span&&i class=&icon-external&&&/i&&/a& 的两位联合创始人李崇哲、赵扶摇,在物质和技术上给我提供支持,让我这第一次自己主持的线上活动少了许多手忙脚乱。当然,也得感谢介绍我与 &a href=&/?target=http%3A//insight.io& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&insight.io&/span&&span class=&invisible&&&/span&&i class=&icon-external&&&/i&&/a& 相识的代码家(怎么哪儿都有你)。&/p&&h2&&b&下期预告&/b&&/h2&&p&到这期位置,HenCoder 的自定义 View 系列的绘制部分就结束了,从下期开始,就要开始布局部分了。按照惯例,官方泄露一点截图吧:&/p&&p&&br&&/p&&figure&&img src=&/50/v2-a2224b95ebb1ecee28176d_b.jpg& data-caption=&& data-rawwidth=&1287& data-rawheight=&741& class=&origin_image zh-lightbox-thumb& width=&1287& data-original=&/50/v2-a2224b95ebb1ecee28176d_r.jpg&&&/figure&&p&&br&&/p&&p&&br&&/p&&figure&&img src=&/50/v2-eb5c89af59f1f9e1e1e70ff_b.jpg& data-caption=&& data-rawwidth=&897& data-rawheight=&675& class=&origin_image zh-lightbox-thumb& width=&897& data-original=&/50/v2-eb5c89af59f1f9e1e1e70ff_r.jpg&&&/figure&&p&&br&&/p&&p&布局部分由于技术的概念比绘制要大得多,所以掌握起来也会难一些,这个各位做好思想准备吧。不过你依然可以相信一点:就像之前的绘制部分一样,虽然有很多人已经尝试过通过看博客、看文档、读源码的方式来学习 Android 的布局(有很多甚至尝试过多次),最终都以「太难了实在学不会」告终,但只要你跟着我走,几期内容之后,你会发现,&b&同样的技术,只要到 HenCoder 来学,它怎么就变得那么的简单。&/b&&/p&&p&就像本文标题和开头我说的,关注我,你就能达到大师级水平,这话我憋了好久,现在终于敢说了。因为,我做到了。&/p&&figure&&img src=&/50/v2-f66e568fba167a21ea2df0c_b.jpg& data-caption=&& data-rawwidth=&900& data-rawheight=&429& class=&origin_image zh-lightbox-thumb& width=&900& data-original=&/50/v2-f66e568fba167a21ea2df0c_r.jpg&&&/figure&&p&&/p&
这句话我真的憋了好久。Android 工程师只要关注我,我就能让你达到大师级水平,不是面试时的吹牛逼水平,不是自我欺骗的了解皮毛的水平,是真正的开发实力。以前我有这个自信,没这个证据。但现在,证据我也有了。关注我的人都知道,我这三个多月来一直在网…
&figure&&img src=&/50/v2-3e425c5f26bd28f9d69e486e_b.jpg& data-rawwidth=&2488& data-rawheight=&870& class=&origin_image zh-lightbox-thumb& width=&2488& data-original=&/50/v2-3e425c5f26bd28f9d69e486e_r.jpg&&&/figure&&h2&前言:&/h2&&p&从9月初开始到现在,我一直在寻找一个适合自己的,可以跨平台的开发APP的js框架。&/p&&p&之前有接触过Weex,React Native,Flutter,NativeScript,Appjs。但是或多或少都提不起我个人的兴趣。原因可能是我不太喜欢RN的书写方式,不太想写css或者去写declarative形式的UI,更加的不喜欢去写html。还有就是难以接受的复杂的开发环境以及高成本的安装方式,调试形式,和乱七八糟的插件文档,总之我一直没去开始尝试,很大一部分是个人的喜好原因。&/p&&p&我其实一直想着能有一款框架只需要编写javascript,就可以完成APP的开发,比如之前我一直在关注的nodeapp,我觉得这才是理想中我想要的js开发者形式的框架,我就是想在app里快乐的书写js,只有js。&/p&&p&可以看出我非常偏执的喜欢js,能拿js干的事绝对不要别的乱七八糟的东西来辅助,直到有一天无意看到了tabris.js,简单阅读了一下文档,我发现这玩意简直就是为了我这种怪物量身打造的。&/p&&p&本文涉及内容分为四个部分,tabris的介绍和一些使用心得,使用nodejs开发简单的API范例,以及代码迁移到码云后,管理代码和项目的一些体验感受。&/p&&p&本文非常适合个人开发者,或者认同js天下无敌的人阅读。&/p&&h2&一,什么是tabris.js&/h2&&p&一开始接触的时候,我本来也想着是不是能够吃现成的。看看有没有前辈也用过这个框架开发了什么好东西。但是经过长时间的搜索,发现在知乎,国内技术社区谈到tabris.js的文章简直可以说基本没有。已知的是2016年底infoq上有过一篇展望前端发展的文章里提了一句,网易前端技术部在16年底某篇BLOG下,有提到且并不是专门介绍tabris.js的。所以tabris基本可以说没有什么二手资料可以让你学习的,我也希望我这篇文章能够帮助大家快速的了解tabris.js到底是什么,好在哪里,如何使用。&/p&&p&&a href=&/?target=https%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&mobile app development in JavaScript&i class=&icon-external&&&/i&&/a& 官方的首页介绍说的非常明白,tabris.js是一款跨平台的移动端app开发框架,兼容ios,android和win phone。&/p&&p&首先它并不对你的javascript代码进行编译转换成native code,而是在app里直接执行你的javascript code,所以是支持允许热更新技术的 &a href=&/?target=https%3A///documentation/latest/patch.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Patching a Tabris.js App&i class=&icon-external&&&/i&&/a&。&/p&&p&tabris.js完全不需要依赖webview,就可以直接运行javascript代码来进行纯UI的编码,和进行原生代码功能的调用,在Android上使用了J2V8作为JS引擎方案,在iOS上使用系统自带的JSCore来完成javascript代码的执行。&/p&&p&简单的了解了tabris.js的原理后,我们再来看一下tabris的几个我觉得比较关键的点。&/p&&p&1,tabris.js是完全开源免费的,使用BSD 3-clause License。&/p&&p&2,安装和开发方式非常简单,只需要本地有nodejs,因为开发是基于它们的developer app来的,所有的开发过程都是在真机进行的调试开发,本地也不需要下载庞大的SDK。&/p&&p&3,支持模块化开发,支持远程和本地编译,支持cordova插件(没有DOM的),支持本地的node_modules包(纯javascript的),支持canvas,支持fetch,xmlhttprequest,localStorage,fs,基本的ES6语法环境,支持ts还有jsx,支持对widget进行selector,总之非常的符合js程序员的思维。&/p&&p&4,内置部分cordova插件,如摄像头调用,扫码,陀螺仪,消息提醒等。也支持内置的一些实用widget,比如collectionView,scrollView,input,text,image等等。也支持扩展自己的widget和cordova插件。&/p&&p&5,如果你愿意,你完全可以只用javascript来编写你的APP,编写过程是基于事件驱动的,并且所有的常用UI都可以直接以类的形式继承到新类里直接使用,也可以自己使用canvas绘制UI和开发游戏,内置了丰富的动画效果库,当然也可以自己自定义。&/p&&p&6,文档写的非常好,编写文档和SDK的同学明显就是javascript工程师出身,非常符合我的胃口,社区响应速度很快,我提过的2个issues都在24小时之内回复和处理,官方非常活跃,开发和提交速度比较频繁,而且是团队开发的形式。&/p&&h2&二,tabris.js开发体验&/h2&&p&tabris.js我上手基本就是几个小时的事,安装方法官方非常简单,就不叙述,我这里以我自己的APP为基础进行讲解。&/p&&p&首先开发之前可以先扫一遍每一个widget的文档,知道都能做什么。&/p&&p&然后可以跑几个他们官方的&a href=&/?target=https%3A///eclipsesource/tabris-js/tree/master/examples& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&eclipsesource/tabris-js&i class=&icon-external&&&/i&&/a& 完整例子和&a href=&/?target=https%3A///eclipsesource/tabris-js/tree/master/snippets& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&eclipsesource/tabris-js&i class=&icon-external&&&/i&&/a& 代码片段,不过就我个人而言,这些demo都不是一个完整的APP开发案例,真的只是demo,所以下面我还是基于我自己实战开发的兔耳日记,来简单的讲解一下整个开发体验:&/p&&figure&&img data-rawheight=&410& src=&/50/v2-f266bdf9fcac2fb8e71029_b.jpg& data-rawwidth=&328& class=&content_image& width=&328&&&/figure&&p&目录结构比较清晰,安装完成后入口文件是src下的app.js,然后就没了,其他目录结构自己可以随意定制,根据官方的例子我也没看出什么套路,所以我也干脆自己设计了一套结构和代码维护方式,我这里就拿登录退出这个流程来简单讲一下:&/p&&figure&&img data-rawheight=&712& src=&/50/v2-873afd49c70bb304b00565_b.jpg& data-rawwidth=&732& class=&origin_image zh-lightbox-thumb& width=&732& data-original=&/50/v2-873afd49c70bb304b00565_r.jpg&&&/figure&&p&代码真的非常好理解,我在启动时对登录态做一个初始化判断, 然后检查登录态,如果登录了就进行tabs的视图调用,如果没登录就调用登录界面。&/p&&p&这里和web开发不太一样的是没有路由的概念,和开发游戏有点类似,app中我理解都是场景的转换,所以每个场景我都使用一个class来表示,这样方便复用,调用以及销毁注销,每个调用后的场景都是一个独立的实例,然后不同的实例之间用事件进行关联。&/p&&p&可能一直做前端开发的同学在这里需要绕一下,如果之前就开发过app的人可能上手就非常快了。&/p&&figure&&img data-rawheight=&742& src=&/50/v2-c66e3f0c765a688e1daaf2_b.jpg& data-rawwidth=&712& class=&origin_image zh-lightbox-thumb& width=&712& data-original=&/50/v2-c66e3f0c765a688e1daaf2_r.jpg&&&/figure&&p&判断是否登录和正常的web开发也不一样,首先在app里是没有session的概念的,也没cookie,所以在这里我选择localStorage来进行状态的保存,使用方法就和平时没两样,jwt是大家平时通用的token验证形式,如果本地有并且解析完token没有过期,则返回true,如果解析完过期或者本地没有jwt token,则是没登录状态,jwt-decode是一个npm上的纯js包,在tabris里是都是可以直接安装调用的,这里开始写成异步的了,是因为可能后期还要加入刷新token的机制,刷新需要异步访问远程API的。&/p&&figure&&img data-rawheight=&1166& src=&/50/v2-5a9f90bdd524c_b.jpg& data-rawwidth=&660& class=&origin_image zh-lightbox-thumb& width=&660& data-original=&/50/v2-5a9f90bdd524c_r.jpg&&&/figure&&p&上面是一个login的部分代码,首先引入tabris的widget,比如Button,ImageView等,然后定义我们的登录类,初始化的时候我们保存了一个Composite到实例中,Composite大家可以理解成是一个图层,里面可以随意放置组件,然后还可以通过对这个Composite进行过滤删选组件,非常方便管理UI比较复杂的地方。&/p&&p&destory方法是提供给别人调用进行组件销毁用的,dispose是删除并销毁,对应还有方法可以删除不销毁,方便之后复用的,可以参见widget类的文档。&/p&&p&init方法里就开始进行组件的绘制过程了,看起来非常的熟悉这不就是面向DOM编程咩?new 一个组件然后定义它的样式和属性最后再appendTo到父组件里,如果想实现居中X轴,Y轴居中偏移120,就定义centerX,centerY就可以了,非常方便。如果使用过YUI的同学会非常熟悉这种形式。如果需要给组件绑定事件,直接on就可以了,支持的事件非常丰富:&a href=&/?target=https%3A///documentation/latest/touch.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Gesture and Touch Events&i class=&icon-external&&&/i&&/a& &/p&&figure&&img data-rawheight=&1248& src=&/50/v2-e4cd8d92c73c7def2af6dbe02a796210_b.jpg& data-rawwidth=&1218& class=&origin_image zh-lightbox-thumb& width=&1218& data-original=&/50/v2-e4cd8d92c73c7def2af6dbe02a796210_r.jpg&&&/figure&&p&下面这里是对登录按钮进行了select事件的处理,然后简单的进行一下校验,最后再用我们对fetch封装后的post方法进行api接口调用,成功后对jwt值进行保存,然后调用自身的destory方法,再初始化登录后的实例。&/p&&p&下面对外进行了constant的管理,对外暴露init和destory方法,其实这部分后期是可以再抽象出来一个base类的,这里就简单的给大家演示下。&/p&&figure&&img data-rawheight=&324& src=&/50/v2-6ac3ee0c6c_b.jpg& data-rawwidth=&524& class=&origin_image zh-lightbox-thumb& width=&524& data-original=&/50/v2-6ac3ee0c6c_r.jpg&&&/figure&&p&退出部分的代码也非常的简单,清楚本地ls,对实例进行切换。因为一个app其实主要的场景可能没几个,如果有的话也是以树形的形式一级一级向下维护的关系,所以最顶层我这里就设置了登录和未登录2个状态。&/p&&p&下面可以给大家看一个DEMO视频:&/p&&br&&a class=&video-box& href=&/?target=https%3A///video/054464& target=&_blank& data-video-id=&& data-video-playable=&true& data-name=&& data-poster=&/v2-092a170aab6a2a.jpg& data-lens-id=&054464&&
&img class=&thumbnail& src=&/v2-092a170aab6a2a.jpg&&&span class=&content&&
&span class=&title&&&span class=&z-ico-extern-gray&&&/span&&span class=&z-ico-extern-blue&&&/span&&/span&
&span class=&url&&&span class=&z-ico-video&&&/span&/video/054464&/span&
&br&&br&&p&因为篇幅有限,代码等完整开发完毕后我会开源,其中的坑当然也有,我下面简单的总结一下:&/p&&p&1,collectionView中的cell无法绑定独立的事件,所以如果不是纯列表展示,建议用scrollView+Composite的方式来进行自定义列表的渲染。&/p&&p&2,collectionView不指定高度,渲染时会有重叠bug,已经提交给官方。&/p&&p&3,按钮,图片,文本,控件等支持的css样式比较可怜,所以建议都使用背景图或者图层叠加的方式实现设计。&/p&&p&4,input支持的多行形式比较傻,如果要做像知乎一样的APP端发布器肯定需要自己扩展,目前的形式加滚动条都要和scrollView配合使用,非常的反人类,不过后期我都打算自学写widget了。&/p&&p&5,调试很方便,打包速度也比较快,等我上架了应用后会简单提炼一个build的中文教程吧,包括内置apple pay和google pay等。&/p&&p&6,对使用者的js抽象能力要求较高,虽然支持jsx,但是我肯定是不会用的。。而且其实本身对样式的定义,widget就给了classList这种属性支持汇总管理的,只不过我暂时还没用。&/p&&p&基本上缺陷比较少,如果做纯展示类的项目,开发速度扛扛的,当然如果很多空间都需要定制化开发,那么还是需要掌握native开发的,但是纯UI层面的开发就完全不必了,这里的layout方式和web也不太一样,参见:&a href=&/?target=https%3A///documentation/latest/layout.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Layout - Tabris.js Documentation&i class=&icon-external&&&/i&&/a& 个人来说感觉比web布局方便多了。。因为全部都是基于相对和视图位置来布局的,说实话我很烦浮动那种布局方式,也可能是我好久没写css了,我很喜欢目前这种layout方式。&/p&&h2&三,使用restify开发API&/h2&&p&基本上tabris的使用和体验就如上,后边说一下另外一个老牌nodejs框架restify,一个专门用来编写API的类express框架。&/p&&p&会用express的人太多了,因为类express,所以就简单说一下哪里和express不太一样吧,开发方式基本一致,主要是增加了N多的中间件配合restfulAPI的开发,而且增加了一些频率,网段,IP等限制节流的方法,又引入了API版本管理以及常见的API错误和常见错误号等。&/p&&p&所以大家如果对express比较熟悉,那么选择restfiy开发纯API服务还是比较靠谱的,上手也非常快,官方文档 &a href=&/?target=http%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Restify&i class=&icon-external&&&/i&&/a& 。&/p&&p&下面还是拿登录接口做一个例子:&/p&&figure&&img data-rawheight=&1176& src=&/50/v2-bb20d24f707dc38eb47c05_b.jpg& data-rawwidth=&992& class=&origin_image zh-lightbox-thumb& width=&992& data-original=&/50/v2-bb20d24f707dc38eb47c05_r.jpg&&&/figure&&p&对所有请求做一次jwt的验证,这里使用了一个jwt的express插件叫jwtAuth,我看了下源码,如果header里没有token,则对query进行验证要自己做,做完补充后,我再手动挂到req的decoded字段中的,这里就完成了对所有api的jwt验证。&/p&&p&然后数据库orm用的mongoose,定义好user的model之后,api是这样写的:&/p&&figure&&img data-rawheight=&1224& src=&/50/v2-5f1ac6c1bacde_b.jpg& data-rawwidth=&904& class=&origin_image zh-lightbox-thumb& width=&904& data-original=&/50/v2-5f1ac6c1bacde_r.jpg&&&/figure&&p&对post过来的用户密码进行校验和md5加密,然后对数据库匹配,最后返回用户的非敏感信息,登录过期时间,然后返回jwt给客户端保存。&/p&&p&基本上这就和上面第二部分登录对应上了,使用nodejs开发API真的是非常的简单。&/p&&h2&四,使用码云管理完整的开发项目&/h2&&p&上面介绍了开发APP客户端和服务端的一些代码片段,最后说一下项目管理和代码管理部分,因为github要收费,gitlab的速度我有点无法接受,正好有一次机缘巧合,朋友推荐我用一下这个国内的代码托管服务还不错,叫码云 &a href=&/?target=https%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&码云 | 开源中国基于Git和SVN的代码托管和研发协作平台&i class=&icon-external&&&/i&&/a& 。&/p&&p&后来我就体验了一下非常的不错,这里也给大家安利一下吧。&/p&&p&首先码云提供的免费版相比github就已经足够个人开发者和小team使用了,5人成员上限,5G容量,单文件最大100M,单项目最大1G,社区与邮件支持,我就用的企业免费版,说一下感受吧。&/p&&figure&&img data-rawheight=&1138& src=&/50/v2-ca0df52e38af4bfea836edffe55a2e8d_b.jpg& data-rawwidth=&2230& class=&origin_image zh-lightbox-thumb& width=&2230& data-original=&/50/v2-ca0df52e38af4bfea836edffe55a2e8d_r.jpg&&&/figure&&p&首先注册完成后,我添加了2个项目,一个是客户端项目一个是API项目,在时间线上每次登陆都可以看到我的提交动态,包括成员任务的处理和状态,然后是支持非常方便的从其他地方导入项目,比如我就是从gitlab导入的码云的,不过其实对于大家来说直接设置一个新origin的remote地址就可以了。&/p&&figure&&img data-rawheight=&508& src=&/50/v2-dfb03b958634ccbba0e6f7_b.jpg& data-rawwidth=&610& class=&origin_image zh-lightbox-thumb& width=&610& data-original=&/50/v2-dfb03b958634ccbba0e6f7_r.jpg&&&/figure&&p&整个企业版的完整功能,免费版是完全都解锁的。&/p&&p&比如文档协作,还有任务管理,开发量统计等,非常适合小型敏捷迭代的项目。&/p&&figure&&img data-rawheight=&1088& src=&/50/v2-fe7da474d6_b.jpg& data-rawwidth=&1622& class=&origin_image zh-lightbox-thumb& width=&1622& data-original=&/50/v2-fe7da474d6_r.jpg&&&/figure&&p&感觉比github的issues好用很多,而且同样是可以跟踪到人,非常方便,还有时间统计。&/p&&figure&&img data-rawheight=&1052& src=&/50/v2-1f86ad1f340fecd9835b8_b.jpg& data-rawwidth=&2042& class=&origin_image zh-lightbox-thumb& width=&2042& data-original=&/50/v2-1f86ad1f340fecd9835b8_r.jpg&&&/figure&&p&统计的维度有代码提交次数,新增任务量,任务完成量等。当然因为项目只有我一个人,所以我大部分都是拿码云来当托管仓用的,没有太多看这些时间相关的管理任务,因为怎么搞都是我自己一个人。。&/p&&p&最后是仓库的界面,用习惯了github切换到码云也没有什么特别的阻碍,设置好ssh公钥就ok了,而且码云也有对应的教程,&a href=&/?target=http%3A//git.mydoc.io/%3Ft%3D154712& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&码云平台帮助文档_V1.2&i class=&icon-external&&&/i&&/a&&/p&&p&&br&&/p&&figure&&img data-rawheight=&1386& src=&/50/v2-36e3bdf125dade6cc67b6c3_b.jpg& data-rawwidth=&2040& class=&origin_image zh-lightbox-thumb& width=&2040& data-original=&/50/v2-36e3bdf125dade6cc67b6c3_r.jpg&&&/figure&&p&在代码管理方面,码云延续了 Git 的优点,并增加了分支保护的功能,和更细粒度的权限管控,让团队协作更安心。&/p&&p&在任务管理方面,更轻、更灵活,支持关联任务和多层子任务,同时也具有任务多类型功能,可以让企业用户方便地维护自己的自定义类型以及自定义状态。无论拿来做需求管理还是 Bug 跟踪,都能够轻松实现。并且任务(Issue)直接关联到项目、到分支,并与 Pull Request 相关联,项目 → 任务 → 代码 完全一体,让开发前所未有地流畅、便捷。&/p&&p&另外码云的全自动仓库快照功能,也同时为企业代码安全保驾护航,个人十分推荐,虽然我还没有使用全面,但是给我的感觉很靠谱。&/p&&h2&总结&/h2&&p&总的来说,使用tabris.js和restfiy的初衷就是选对一个适合符合自己的开发习惯和感受的框架,文中我也说明了,如果大家喜欢tabris和restfiy的话可以和我一起学习交流。&/p&&p&码云的项目地址:&a href=&/?target=https%3A///terj/tuerAPP& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://&/span&&span class=&visible&&/terj/tuerAPP&/span&&span class=&invisible&&&/span&&i class=&icon-external&&&/i&&/a&&/p&&p&&a href=&/?target=https%3A///terj/tuerAPI& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://&/span&&span class=&visible&&/terj/tuerAPI&/span&&span class=&invisible&&&/span&&i class=&icon-external&&&/i&&/a&&br&&/p&&p&更多细节欢迎查看项目源码,文档正在慢慢补充ing,谢谢收看。&/p&
前言:从9月初开始到现在,我一直在寻找一个适合自己的,可以跨平台的开发APP的js框架。之前有接触过Weex,React Native,Flutter,NativeScript,Appjs。但是或多或少都提不起我个人的兴趣。原因可能是我不太喜欢RN的书写方式,不太想写css或者去写declarative…
&figure&&img src=&/50/v2-a6900bac29e8e4eaed758d24793cc13c_b.png& data-rawwidth=&1920& data-rawheight=&1080& class=&origin_image zh-lightbox-thumb& width=&1920& data-original=&/50/v2-a6900bac29e8e4eaed758d24793cc13c_r.png&&&/figure&&blockquote&8 /* 一共绘制 8 个数(4 个点)*/这期的文章格式如果看着太难受,可以去我的网站看原文。我调了几个小时了还是调不好,实在是 hold 不住知乎的编辑器啊……
网站原文:&a href=&/?target=http%3A///ui-1-1/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Android 开发进阶: 自定义 View 1-1 绘制基础&i class=&icon-external&&&/i&&/a&&/blockquote&&p&从今天开始,HenCoder 就正式开讲知识技能了。按照我的计划,第一季是 UI,UI 一共分为三部分:绘制、布局和触摸反馈。本期是绘制部分的第一期。绘制大概会用 5~6 期的时间讲完,整个 UI 的绘制、布局和触摸反馈三部分大概会用十来期。更新频率大约为每周一更(不承诺哟)。&/p&&p&如果你不知道 HenCoder 是什么,可以先看这里:&/p&&p&&a href=&/p/& class=&internal&&HenCoder:给高级 Android 工程师的进阶手册&/a&&/p&&h2&自定义绘制概述&/h2&&p&二话不说,我反手就是一个视频:&/p&&a class=&video-box& href=&/?target=https%3A///video/340160& target=&_blank& data-video-id=&& data-video-playable=&true& data-name=&& data-poster=&/v2-ae5e658da8e2.jpg& data-lens-id=&340160&&
&img class=&thumbnail& src=&/v2-ae5e658da8e2.jpg&&&span class=&content&&
&span class=&title&&&span class=&z-ico-extern-gray&&&/span&&span class=&z-ico-extern-blue&&&/span&&/span&
&span class=&url&&&span class=&z-ico-video&&&/span&/video/340160&/span&
&p&首先总结一下视频中的关键点:&/p&&ul&&li&自定义绘制的方式是重写绘制方法,其中最常用的是 onDraw()&/li&&li&绘制的关键是 Canvas 的使用&/li&&ul&&li&Canvas 的绘制类方法: drawXXX() (关键参数:Paint)&/li&&li&Canvas 的辅助类方法:范围裁切和几何变换&/li&&/ul&&li&可以使用不同的绘制方法来控制遮盖关系&/li&&/ul&&p&概念已经在视频里全部讲出来了,知识点并不多,但你可能也看出来了,我讲得并不细。这是因为知识点虽然不多,但细节还是很多的,仅仅靠一节分享不可能讲完。我按照顺序把这些知识分成了 4 个级别,拆成几节来讲,你按照这 4 个级别的顺序学习下来,就能够平滑地逐步进阶。&/p&&h2&自定义绘制知识的四个级别&/h2&&ol&&li&Canvas 的 drawXXX() 系列方法及 Paint 最常见的使用&/li&&/ol&&p&Canvas.drawXXX() 是自定义绘制最基本的操作。掌握了这些方法,你才知道怎么绘制内容,例如怎么画圆、怎么画方、怎么画图像和文字。组合绘制这些内容,再配合上 Paint 的一些常见方法来对绘制内容的颜色和风格进行简单的配置,就能够应付大部分的绘制需求了。&/p&&figure&&img src=&/v2-764d6f89dadfff_b.png& data-rawwidth=&288& data-rawheight=&182& class=&content_image& width=&288&&&/figure&&p&&br&&/p&&figure&&img src=&/v2-4c904db3ec7c80b1946bfe8d81332bea_b.png& data-rawwidth=&343& data-rawheight=&197& class=&content_image& width=&343&&&/figure&&p&&br&&/p&&figure&&img src=&/v2-325d2d5e4ca61b9acc4d9f2fa9daa7fb_b.png& data-rawwidth=&254& data-rawheight=&237& class=&content_image& width=&254&&&/figure&&p&&br&&/p&&p&今天这篇分享我要讲的就是这些内容。也就是说,你在看完这篇文章&b&并做完练习&/b&之后,上面这几幅图你就会绘制出来了。从今以后,你也很少再需要假装一本正经地对设计师说「不行这个图技术上实现不了」,也不用心惊胆战得等待设计师的那句「那 iOS 怎么可以」了。&/p&&figure&&img src=&/v2-3ea01a73cd5b67957ebc72_b.png& data-rawwidth=&234& data-rawheight=&272& class=&content_image& width=&234&&&/figure&&p&&br&&/p&&ol&&li&Paint 的完全攻略&/li&&/ol&&p&Paint 可以做的事,不只是设置颜色,也不只是我在视频里讲的实心空心、线条粗细、有没有阴影,它可以做的风格设置真的是非常多、非常细。例如:&/p&&blockquote&拐角要什么形状?&/blockquote&&figure&&img src=&/v2-c1cebee3038cbdd759abf5_b.png& data-rawwidth=&449& data-rawheight=&149& class=&origin_image zh-lightbox-thumb& width=&449& data-original=&/v2-c1cebee3038cbdd759abf5_r.png&&&/figure&&p&&br&&/p&&blockquote&开不开双线性过滤?&/blockquote&&figure&&img src=&/v2-6b7ac60ce_b.png& data-rawwidth=&658& data-rawheight=&304& class=&origin_image zh-lightbox-thumb& width=&658& data-original=&/v2-6b7ac60ce_r.png&&&/figure&&p&&br&&/p&&blockquote&加不加特效?&/blockquote&&figure&&img src=&/v2-d5ac530b51cf68a1fc0656_b.png& data-rawwidth=&667& data-rawheight=&306& class=&origin_image zh-lightbox-thumb& width=&667& data-original=&/v2-d5ac530b51cf68a1fc0656_r.png&&&/figure&&p&&br&&/p&&p&可以调节的非常多,我就不一一列举了。当你掌握到这个级别,就真的不会有什么东西会是 iOS 能做到但你做不到的了。就算设计师再设计出了很难做的东西,做不出来的也不再会是你们 Android 组了。&/p&&figure&&img src=&/v2-e71f850f2aad008cb831b49_b.png& data-rawwidth=&260& data-rawheight=&281& class=&content_image& width=&260&&&/figure&&p&&br&&/p&&ol&&li&Canvas 对绘制的辅助——范围裁切和几何变换。&/li&&/ol&&p&范围裁切:&/p&&figure&&img src=&/v2-5b034d70cf6d4d6240ee56_b.png& data-rawwidth=&655& data-rawheight=&431& class=&origin_image zh-lightbox-thumb& width=&655& data-original=&/v2-5b034d70cf6d4d6240ee56_r.png&&&/figure&&p&几何变换:&/p&&figure&&img src=&/v2-785dbc3841fcab4ad39e_b.png& data-rawwidth=&938& data-rawheight=&722& class=&origin_image zh-lightbox-thumb& width=&938& data-original=&/v2-785dbc3841fcab4ad39e_r.png&&&/figure&&p&&br&&/p&&p&大多数时候,它们并不会被用到,但一旦用到,通常都是很炫酷的效果。范围裁切和几何变换都是用于辅助的,它们本身并不酷,让它们变酷的是设计师们的想象力与创造力。而你要做的,是把他们的想象力与创造力变成现实。&/p&&figure&&img src=&/v2-1a3cbb4baf21d59a884bf4_b.png& data-rawwidth=&458& data-rawheight=&251& class=&origin_image zh-lightbox-thumb& width=&458& data-original=&/v2-1a3cbb4baf21d59a884bf4_r.png&&&/figure&&p&&br&&/p&&ol&&li&使用不同的绘制方法来控制绘制顺序&/li&&/ol&&figure&&img src=&/v2-b7a4ae853ee0abe720f901b_b.png& data-rawwidth=&443& data-rawheight=&264& class=&origin_image zh-lightbox-thumb& width=&443& data-original=&/v2-b7a4ae853ee0abe720f901b_r.png&&&/figure&&p&控制绘制顺序解决的并不是「做不到」的问题,而是性能问题。同样的一种效果,你不用绘制顺序的控制往往也能做到,但需要用多个 View 甚至是多层 View 才能拼凑出来,因此代价是 UI 的性能;而使用绘制顺序的控制的话,一个 View 就全部搞定了。&/p&&p&自定义绘制的知识,大概就分为上面这四个级别。在你把这四个级别依次掌握了之后,你就是一个自定义绘制的高手了。它们具体的细节,我将分成几篇来讲。今天这篇就是第一篇: Canvas.drawXXX() 系列方法及 Paint 最基本的使用。我要正式开始喽?&/p&&h2&一切的开始:onDraw()&/h2&&p&自定义绘制的上手非常容易:提前创建好 Paint 对象,重写 onDraw(),把绘制代码写在 onDraw() 里面,就是自定义绘制最基本的实现。大概就像这样:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&Paint paint = new Paint();
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 绘制一个圆
canvas.drawCircle(300, 300, 200, paint);
&/code&&/pre&&/div&&p&就这么简单。所以关于 onDraw() 其实没什么好说的,一个很普通的方法重写,唯一需要注意的是别漏写了 super.onDraw()。&/p&&h2&Canvas.drawXXX() 和 Paint 基础&/h2&&p&drawXXX() 系列方法和 Paint 的基础掌握了,就能够应付简单的绘制需求。它们主要包括:&/p&&ol&&li&Canvas 类下的所有 draw- 打头的方法,例如 drawCircle() drawBitmap()。&/li&&li&Paint 类的几个最常用的方法。具体是:&/li&&/ol&&ul&&li&Paint.setStyle(Style style) 设置绘制模式&/li&&li&Paint.setColor(int color) 设置颜色&/li&&li&Paint.setStrokeWidth(float width) 设置线条宽度&/li&&li&Paint.setTextSize(float textSize) 设置文字大小&/li&&li&Paint.setAntiAlias(boolean aa) 设置抗锯齿开关&/li&&/ul&&p&对于比较习惯于自学的人(我就是这样的人),你看到这里就已经可以去 Google 的官方文档里,打开 &a href=&/?target=https%3A///reference/android/graphics/Canvas.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Canvas&i class=&icon-external&&&/i&&/a& 和 &a href=&/?target=https%3A///reference/android/graphics/Paint.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Paint&i class=&icon-external&&&/i&&/a& 的页面,把上面的这两类方法学习一下,然后今天的内容就算结束了。当然,这篇文章也可以关掉了。&/p&&figure&&img src=&/v2-b8a6e501d7d71d0909157_b.png& data-rawwidth=&236& data-rawheight=&276& class=&content_image& width=&236&&&/figure&&p&下面的内容就是展开讲解上面的这两类方法。&/p&&h2&Canvas.drawColor(@ColorInt int color) 颜色填充&/h2&&p&这是最基本的 drawXXX() 方法:在整个绘制区域统一涂上指定的颜色。&/p&&p&例如 drawColor(Color.BLACK) 会把整个区域染成纯黑色,覆盖掉原有内容; drawColor(Color.parse(&#&) 会在原有的绘制效果上加一层半透明的红色遮罩。&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&drawColor(Color.BLACK);
&/code&&/pre&&/div&&figure&&img src=&/v2-bd7b32f98a2caeef607da91_b.png& data-rawwidth=&455& data-rawheight=&218& class=&origin_image zh-lightbox-thumb& width=&455& data-original=&/v2-bd7b32f98a2caeef607da91_r.png&&&/figure&&p&&br&&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&drawColor(Color.parse(&#&); // 半透明红色
&/code&&/pre&&/div&&figure&&img src=&/v2-7fb1a6ddde036c532a25b45a830e2468_b.png& data-rawwidth=&448& data-rawheight=&217& class=&origin_image zh-lightbox-thumb& width=&448& data-original=&/v2-7fb1a6ddde036c532a25b45a830e2468_r.png&&&/figure&&p&&br&&/p&&p&类似的方法还有 drawRGB(int r, int g, int b) 和 drawARGB(int a, int r, int g, int b) ,它们和 drawColor(color) 只是使用方式不同,作用都是一样的。&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&canvas.drawRGB(100, 200, 100);
canvas.drawARGB(100, 100, 200, 100);
&/code&&/pre&&/div&&p&这类颜色填充方法一般用于在绘制之前设置底色,或者在绘制之后为界面设置半透明蒙版。&/p&&h2&drawCircle(float centerX, float centerY, float radius, Paint paint) 画圆&/h2&&p&前两个参数 centerX centerY 是圆心的坐标,第三个参数 radius 是圆的半径,单位都是像素,它们共同构成了这个圆的基本信息(即用这几个信息可以构建出一个确定的圆);第四个参数 paint 我在视频里面已经说过了,它提供基本信息之外的所有风格信息,例如颜色、线条粗细、阴影等。&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&canvas.drawCircle(300, 300, 200, paint);
&/code&&/pre&&/div&&figure&&img src=&/v2-57bfe51b2fdf4e5c9b4d6d57987d86ca_b.png& data-rawwidth=&259& data-rawheight=&265& class=&content_image& width=&259&&&/figure&&p&&br&&/p&&p&那位说:「你等会儿!先别往后讲,你刚才说圆心的坐标,我想问坐标系在哪儿呢?没坐标系你跟我聊什么坐标啊。」&/p&&p&我想说:问得好(强行插入剧情)。在 Android 里,每个 View 都有一个自己的坐标系,彼此之间是不影响的。这个坐标系的原点是 View 左上角的那个点;水平方向是 x 轴,右正左负;竖直方向是 y 轴,下正上负(注意,是下正上负,不是上正下负,和上学时候学的坐标系方向不一样)。也就是下面这个样子。&/p&&figure&&img src=&/v2-52b6d2a36ba5f803f1fdf36372dbc57d_b.png& data-rawwidth=&616& data-rawheight=&533& class=&origin_image zh-lightbox-thumb& width=&616& data-original=&/v2-52b6d2a36ba5f803f1fdf36372dbc57d_r.png&&&/figure&&p&所以一个 View 的坐标 (x, y) 处,指的就是相对它的左上角那个点的水平方向 x 像素、竖直方向 y 像素的点。例如,(300, 300) 指的就是左上角的点向右 300 、向下 300 的位置; (100, -50) 指的就是左上角的点向右 100 、向上 50 的位置。&/p&&p&也就是说, canvas.drawCircle(300, 300, 200, paint) 这行代码绘制出的圆,在 View 中的位置和尺寸应该是这样的:&/p&&figure&&img src=&/v2-7379659fcefc81490d42b_b.png& data-rawwidth=&612& data-rawheight=&530& class=&origin_image zh-lightbox-thumb& width=&612& data-original=&/v2-7379659fcefc81490d42b_r.png&&&/figure&&p&圆心坐标和半径,这些都是圆的基本信息,也是它的独有信息。什么叫独有信息?就是只有它有,别人没有的信息。你画圆有圆心坐标和半径,画方有吗?画椭圆有吗?这就叫独有信息。独有信息都是直接作为参数写进 drawXXX() 方法里的(比如 drawCircle(centerX, centerY, radius, paint) 的前三个参数)。&/p&&p&而除此之外,其他的都是公有信息。比如图形的颜色、空心实心这些,你不管是画圆还是画方都有可能用到的,这些信息则是统一放在 paint 参数里的。&/p&&p&&b&插播一: Paint.setColor(int color)&/b&&/p&&p&例如,你要画一个红色的圆,并不是写成 canvas.drawCircle(300, 300, 200, RED, paint) 这样,而是像下面这样:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&paint.setColor(Color.RED); // 设置为红色
canvas.drawCircle(300, 300, 200, paint);
&/code&&/pre&&/div&&figure&&img src=&/v2-299df7cf4a404f2cee837a76778aec67_b.png& data-rawwidth=&160& data-rawheight=&141& class=&content_image& width=&160&&&/figure&&p&Paint.setColor(int color) 是 Paint 最常用的方法之一,用来设置绘制内容的颜色。你不止可以用它画红色的圆,也可以用它来画红色的矩形、红色的五角星、红色的文字。&/p&&p&&b&插播二: Paint.setStyle(Paint.Style style)&/b&&/p&&p&而如果你想画的不是实心圆,而是空心圆(或者叫环形),也可以使用 paint.setStyle(Paint.Style.STROKE) 来把绘制模式改为画线模式。&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&paint.setStyle(Paint.Style.STROKE); // Style 修改为画线模式
canvas.drawCircle(300, 300, 200, paint);
&/code&&/pre&&/div&&figure&&img src=&/v2-b5cd05d3b2bb376e7359d_b.png& data-rawwidth=&143& data-rawheight=&137& class=&content_image& width=&143&&&/figure&&p&setStyle(Style style) 这个方法设置的是绘制的 Style 。Style 具体来说有三种: FILL, STROKE 和 FILL_AND_STROKE 。FILL 是填充模式,STROKE 是画线模式(即勾边模式),FILL_AND_STROKE 是两种模式一并使用:既画线又填充。它的默认值是 FILL,填充模式。&/p&&p&插播三: Paint.setStrokeWidth(float width)&/p&&p&在 STROKE 和 FILL_AND_STROKE 下,还可以使用 paint.setStrokeWidth(float width) 来设置线条的宽度:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(20); // 线条宽度为 20 像素
canvas.drawCircle(300, 300, 200, paint);
&/code&&/pre&&/div&&figure&&img src=&/v2-d3b18a2bd936aa0f5b5c0_b.png& data-rawwidth=&165& data-rawheight=&152& class=&content_image& width=&165&&&/figure&&p&&b&插播四: 抗锯齿&/b&&/p&&p&在绘制的时候,往往需要开启抗锯齿来让图形和文字的边缘更加平滑。开启抗锯齿很简单,只要在 new Paint() 的时候加上一个 ANTI_ALIAS_FLAG 参数就行:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
&/code&&/pre&&/div&&p&另外,你也可以使用 Paint.setAntiAlias(boolean aa) 来动态开关抗锯齿。&/p&&p&抗锯齿的效果如下:&/p&&figure&&img src=&/v2-7dcde98a1ed79faaca08_b.png& data-rawwidth=&429& data-rawheight=&241& class=&origin_image zh-lightbox-thumb& width=&429& data-original=&/v2-7dcde98a1ed79faaca08_r.png&&&/figure&&p&可以看出,没有开启抗锯齿的时候,图形会有毛片现象,啊不,毛边现象。所以一定记得要打开抗锯齿哟!&/p&&blockquote&&u&可以跳过的冷知识&/u&
好奇的人可能会问:抗锯齿既然这么有用,为什么不默认开启,或者干脆把这个开关取消,自动让所有绘制都开启抗锯齿?
短答案:因为抗锯齿并不一定适合所有场景。
长答案:所谓的毛边或者锯齿,发生的原因并不是很多人所想象的「绘制太粗糙」「像素计算能力不足」;同样,抗锯齿的原理也并不是选择了更精细的算法来算出了更平滑的图形边缘。
实质上,锯齿现象的发生,只是由于图形分辨率过低,导致人眼察觉出了画面中的像素颗粒而已。换句话说,就算不开启抗锯齿,图形的边缘也已经是最完美的了,而并不是一个粗略计算的粗糙版本。
那么,为什么抗锯齿开启之后的图形边缘会更加平滑呢?因为抗锯齿的原理是:修改图形边缘处的像素颜色,从而&b&让图形在肉眼看来具有更加平滑的感觉&/b&。一图胜千言,上图:&/blockquote&&figure&&img src=&/v2-aad083dafb99774bb35ccb0e2bb23b6c_b.png& data-rawwidth=&446& data-rawheight=&254& class=&origin_image zh-lightbox-thumb& width=&446& data-original=&/v2-aad083dafb99774bb35ccb0e2bb23b6c_r.png&&&/figure&&p&&br&&/p&&blockquote&上面这个是把前面那两个圆放大后的局部效果。看到没有?未开启抗锯齿的圆,所有像素都是同样的黑色,而开启了抗锯齿的圆,边缘的颜色被略微改变了。这种改变可以让人眼有边缘平滑的感觉,但从某种角度讲,它也造成了图形的颜色失真。
所以,抗锯齿好不好?好,大多数情况下它都应该是开启的;但在极少数的某些时候,你还真的需要把它关闭。「某些时候」是什么时候?到你用到的时候自然就知道了。&/blockquote&&p&除了圆,Canvas 还可以绘制一些别的简单图形。它们的使用方法和 drawCircle() 大同小异,我就只对它们的 API 做简单的介绍,不再做详细的讲解。&/p&&h2&drawRect(float left, float top, float right, float bottom, Paint paint) 画矩形&/h2&&p&left, top, right, bottom 是矩形四条边的坐标。&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&paint.setStyle(Style.FILL);
canvas.drawRect(100, 100, 500, 500, paint);
paint.setStyle(Style.STROKE);
canvas.drawRect(700, 100, , paint);
&/code&&/pre&&/div&&figure&&img src=&/v2-716c6e178ae6caee76394ba_b.png& data-rawwidth=&341& data-rawheight=&166& class=&content_image& width=&341&&&/figure&&p&另外,它还有两个重载方法 drawRect(RectF rect, Paint paint) 和 drawRect(Rect rect, Paint paint) ,让你可以直接填写 RectF 或 Rect 对象来绘制矩形。&/p&&h2&drawPoint(float x, float y, Paint paint) 画点&/h2&&p&x 和 y 是点的坐标。点的大小可以通过 paint.setStrokeWidth(width) 来设置;点的形状可以通过 paint.setStrokeCap(cap) 来设置:ROUND 画出来是圆形的点,SQUARE 或 BUTT 画出来是方形的点。(点还有形状?是的,反正 Google 是这么说的,你要问问 Google 去,我也很懵逼。)&/p&&blockquote&注:Paint.setStrokeCap(cap) 可以设置点的形状,但这个方法并不是专门用来设置点的形状的,而是一个设置线条端点形状的方法。端点有圆头 (ROUND)、平头 (BUTT) 和方头 (SQUARE) 三种,具体会在下一节里面讲。&/blockquote&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&paint.setStrokeWidth(20);
paint.setStrokeCap(Paint.Cap.ROUND);
canvas.drawPoint(50, 50, paint);
&/code&&/pre&&/div&&figure&&img src=&/v2-be3f47dccc5c40ae0ec21da_b.png& data-rawwidth=&130& data-rawheight=&112& class=&content_image& width=&130&&&/figure&&p&&br&&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&paint.setStrokeWidth(20);
paint.setStrokeCap(Paint.Cap.SQUARE;
canvas.drawPoint(50, 50, paint);
&/code&&/pre&&/div&&figure&&img src=&/v2-2dba848aac682ad018038c_b.png& data-rawwidth=&141& data-rawheight=&107& class=&content_image& width=&141&&&/figure&&p&&br&&/p&&p&好像有点像 FILL 模式下的 drawCircle() 和 drawRect() ?事实上确实是这样的,它们和 drawPoint() 的绘制效果没有区别。各位在使用的时候按个人习惯和实际场景来吧,哪个方便和顺手用哪个。&/p&&h2&drawPoints(float[] pts, int offset, int count, Paint paint) / drawPoints(float[] pts, Paint paint) 画点(批量)&/h2&&p&同样是画点,它和 drawPoint() 的区别是可以画多个点。pts 这个数组是点的坐标,每两个成一对;offset 表示跳过数组的前几个

我要回帖

更多关于 two girls one cap 的文章

 

随机推荐