一个在教练的鼓励下开始的Android应用开发项目,由Tomas独立完成。
- 6-12月内初步达到可用级别
- 尽可能使用Jetpack
- 规范开发流程
多写笔记(每天都要有Commit (目前已失败)配合项目完善自己的知识体系
本项目采用MIT协议(The MIT License
)
今天主要是使用到了(newHolder.itemView.layoutParams as StaggeredGridLayoutManager.LayoutParams).isFullSpan = true
这个比较有意思的地方。
isFullSpan == true,这个 item 将会充满所有 span,也就是变成 spanCount == 1
isFullSpan == false, 这个 item 就会根据设置的 spanCount 来摆放位置
之后在涉及到View的样式的时候还是可以多多看一下LayoutParams
这块的内容,说不准有惊喜。 不过教练也提到叻
草,视图参数里面android作用域的更新很多都要用
layoutParams
的kotlin有个拓展函数叫
updateLayoutParams
,需要指定泛型同时传入一个block但是其实不光是width, height要用
layoutParam
来更新,margin也是
constriantlayout
布局里面也是用layoutParam
更新不过有个小坑,最顶层的
LayoutParam
并没有暴露margin参数。有一个单独的LayoutParam MarginLayoutParam
其实大部分
viewGroup
的LayoutParam
也是继承自MarginLayoutParam
就是(然后它以及它的子类才能动态设置margin
不过值得一提的是,padding却又不需要通过
LayoutParam
来设置我感觉应该是和父布局相关的参数需要用
LayoutParam
来设置/更新,你可以试试view.setPadding()
,会有这样的方法padding应该是只和这个视图自己有关,所以就没有这样的限定
然后虽然说不鼓励使用RecyclerView
嵌套,但是好像...还是有时候需要这么写,挺烦的。不过前天终于学会在Rv里面自定义多种样式了,估计搭配一下修改默认LayoutManager
的一些属性还可以有更多可以调整的地方。
还有第一天为了弄底栏而接触的Jetpack Navigation
,感觉Google其实提供了很多好东西,可以实现不少现在常用的效果。不过在自己没有学习compose
之前,估计挺多View控件还是要自己去摸索XML属性去做外观定义。
等闲下来了就整理总结一下吧,写个笔记文章之类的。水一篇估计也挺好(如果我没有摸鱼的话)
今天考试挺糟糕的,虽然知道不会挂科吧,但还是觉得反应出了自己在一些事情上的态度问题。嘛,这个再之后单独写篇文章好了
重点还是今天的开发上遇到的问题:Rv
的item
本身的宽高不一定是固定的。在瀑布流中,item
本身可能需要对里面的图片或者文字之类的控件的宽高进行限制(写的是固定数值),而一旦Rv在不同的设备上进行显示的时候,Rv本身的宽dpi是不一定的,而item
宽高用数值写死 + StaggeredGridLayout对行/列的限制
,会使得列表本身的显示会不完整,或者是出现大片的空白。
今天意识到了一个问题,就是item宽度如果写死的话,不同dpi宽度下的设备显示感觉会有点问题(
--摘录自和教练的聊天记录
比较可怕的是,教练把这个当作一个面试模拟的情况来和自己讨论...虽然理智上知道是好事,但是还是很慌。最后教练也委婉的表示说咱的回答可能不一定能过面试~~(叹气)~~。
重点还是在解决问题上,先给出教练提到的最简单最暴力的方法:
比如瀑布流里面,item中的图片有固定的宽高比,正好就可以借助
constraintlayout
提供的app:constrainDimenRatio
属性来设置,让imageview
的宽高只match constraint,然后通过dimension ratio
的设置来确定imageview的size文字啥的就相对简单多了,确定好
maxLines
然后wrapcontent
就完事了(这样瀑布流的布局就可以在不同尺寸的设备上保证比例的一致了
关于剩下的一些当时讨论的内容,等我睡醒了再继续补充吧。
在这个问题的讨论当中,教练还提到了今天他在面试别人的时候想问有关Rv复用有关的问题。也等醒来一起归纳一下吧(
摸鱼了大概两天吧,今天也和同学聊了一会儿天,关于毕业之后未来做什么。emmmm,聊完之后看来还是要好好的学习Android方面的东西,估计是没有回头路了吧。等哪天有空整理一下自己的学习路线和需求好了(不是怎么老是挖坑)
因为前几次写Rv比较多,现在熟练一些了。感觉目前在Layout
的自适应和Constraint
上面有那么一点点的感觉了(虽然总觉得好像面试不一定考这个,貌似很多人对这个并不是那么感兴趣)
今天碰到的问题和之前有点关联吧,大概就是在MyFragment
里面的一个Rv上面想做到前面四个item可以等距离分隔开,最后一个item宽度自定义。但是就在刚刚写下这段话的时候,突然意识到可以把最后一个item不放在RecyclerView
里面里(因为实际项目里好像这玩意儿一直都在列表的最右边来着...也许...我没猜错吧)
那等我明天起床好好修改一下。之后周末回家也要开始多写代码,不能老是摸鱼了(
虽然是这么说的,但是还是觉得自己的知识没有成体系,还有很多的知识需要重新补齐。虽然说不一定是要像大厂那样那么在乎所谓的“八股文”,但...还是不能太轻视基础知识的重要性的。包括算法之类的东西,有空还是要摸一摸,看一看啥的。
不过感觉如果又什么都安排上的话,大概率又是什么都学不到吧(摊手
今天也是写很少代码的一天。现在手上碰到了几个问题:
- “我的”页面上应该是用到了
collapsingToolbarLayout
,但是这个效果需要再自己去定义一下,并不是系统默认的那个简单的东东 - “发现”页面
RecyclerView
和TabLayout
的响应。这个是没有接触过的东东,但是估计网上可能还是有这种东西。不过Tab应该是重新写过样式了,还得想想看要自己怎么弄。 - 自己在电脑上跑的时候已经偶尔会有ANR的情况了,不知道是不是因为我本身8G的内存导致模拟器给不了太大内存导致的...(不过Rv嵌套好像是据说会大量占用内存啥的,但是教练他的成品好像在虚拟机跑的时候并没有ANR过,所以...目前还不知道原因是什么)
目前来看,可能还是第二点比较容易先处理掉一些内容,虽然自定义样式这个没有接触过,但是响应的这块儿还是可以比较简单的处理吧。明天手上还有两个电工的实验报告要写,下个礼拜也要开始考虑和补修的课程老师联系一下了。应该说这学期真正忙碌的时候要开始了,大概要给自己要求一下做事情要落到实处吧,不然又荒废一学期真的不行。这个学期还是很重要的,太多事情等着我处理了。嗯,好好给自己打个气。希望不要再焦虑下去,要坚持住(
上面的问题明天也再问一下教练吧,应该可以再学习到一点(逃
看了消息机制(Handler
之类的)和一小部分事件分发(TouchEvent
)的东东,感觉有点脑子不够用。消息处理这块儿感觉还是要再配上一点多线程相关的东西。但是说实话,写代码也有几千行了,还真的没有好好的尝试过写多线程的东东,感觉还是要自己再尝试一下。然后之后学习完的内容还是通过日记来画个提纲吧,以防自己忘记,定期复习起来应该会有不错的效果。(天知道能不能做到
- Event-Dispatch(md笔记)
- message-mechanism(md笔记)
- ThreadPool(Android进阶之光)
- tabLayout(setScrollPosition, addOnTabSelectedListener)
- RecyclerView(setOnScrollChangeListener, findFirstVisibleItemPosition, smoothScrollToPosition)
最后那个smoothScrollToPosition
简单的阅读了一下源码,但是还没有完全弄明白。但是这个的看起来已经比下午看的Handler什么的轻松太多了。争取明天再弄懂这个吧。
今天其实总体还是可以的,但是依旧浪费了不少的时间,所以效率还是要继续提高一点。明天想看看网络框架方面(Rx和Retrofit之类的),然后顺带加强一下多线程还有Kotlin的coroutine
,挺重要的。(草,突然想起来之前看的扔物线的launchMode的视频还没有做总结,里面singleTask
和singleInstance
还是有点错乱...)
晚上早睡早起吧,少玩手机(
上课也在看昨天没看明白的源码,下课了之后中午和下午也在看,到三点多才读完将近一半。然而最关键的部分还没看懂...真的是太菜了(哭
最后的结果就是今天项目上基本什么都没做,还花了一大半的时间在研究Anim
和Transition
到底哪个能用来做一个简单的Activity切换的效果,服了我自己。不过也再次感受到了中文内容和英文内容的差距,还是要锻炼自己英语阅读文档和网页的能力,挺重要的。
大概明天要好好看一下本来想在今天看的内容吧,主要是郭神的书里面的多线程和Service的内容。(然而写下这段文字的时候已经是3月1日了,白天还要陪超超去修手机,打算翘个课看看)
缺乏的内容太多了,感觉明天可以再试着给自己列个MindMap,对着书和网上的一些内容再做做总结。啊对了,之前的字节青训营的内容也还没有补完...好多坑,呜呜呜
今天的唯一有效输出,就是在掘金上发了篇翻译StackOverflow的问答吧。相比前几天真的是越来越少了,得好好改进一下。不过睡觉玩手机还是有改善的,夸夸自己w
该睡了,晚安!
很神奇,这几天的日记都是等到第二天凌晨才来写的。不知道算不算是某种意义上的拖延症(逃
陪超超去修了下手机,花了大半天的时间。中间腾了一miumiu的零碎时间复习Java的Collection
这块的内容,虽然也就...大概的范围,并没有很细致。
回南昌之后第一次翘课 (哦好像不对,还有一次睡过头错过上课),也是很奇妙的感觉。路上和超超聊了挺多的事情,再一次认识到自己还是很喜欢情绪输出,发现自己依旧有着把自己的情感托付给别人的习惯。嘛,只能说再继续改了。不过这些都是后话,也不能算是开发日记的重点 (欸,写了这么多才发现吗?
Java集合这块挺多的方法和实现类,但是真正常用的也就那么些。目前看到的复习资料上也其实没怎么提线程安全这块的内容,凭着自己的好奇去查了下,意识到ArrayList
和LinkedList
等一大票并不是线程安全,基本上就vector
,stack
,hashtable
和enumeratio
n是安全的。
而线程安全主要是三个点:原子性,可见性和有序性。这个应该是在前两天看进阶之光里面的多线程的时候有提到的。这本书里第四章有提到这块的内容,下次还是要多写点笔记出来,提取精华内容方便记忆。虽然看得多,但是不去写下来的话,光靠脑子还是容易忘记啊...(突然想到去年这个时候网申飞书的日常实习,都是血和泪的教训啊)
说到笔记,今天还是用平板记了一下集合大概的类继承图,还有看第一行代码时候写了一半的内容。不过还好,这部分的内容自己用MD做了笔记,也挺不错的。就是昨天看的源码今天也没有继续处理了,大概真的是因为不愿意去看了吧(毕竟需求解决了)。
自己主动看书和阅读的部分大概就这些吧,接下来回顾一下写代码遇到的坑...
首先最疑惑的地方就是之前花了大半天想要实现的Activity
切换Slide覆盖动画。莫名奇妙的就有了我想要的效果,之前还花费了好半天才做到了一半想要的样式。(其实今天又差点花一大堆的时间在这个上面...)
再一个,就是想解决Toolbar
的问题。查了一堆的文章,CSDN和掘金上都看了不少,基本上都是很老的内容。更悲剧的是,我看下来都是没有很大帮助的。只能从垃圾堆里一点点刨出想要的东西:
- Toolbar是替代ActionBar的。如果想在代码中像ActionBar一样对Toolbar进行部分操作,可以使用
supportActionbar(Toolbar)
/getActionbar()
- 在
androidx
和android
包下各有一个toolbar的实现,但是网络上的内容大多都是针对前者的(甚至还有support v7包...) - Toolbar也可以像Actionbar一样插入菜单,并且设置菜单项的监听
- Toolbar本质是
ViewGroup
,所以可以在中间插入任何自己想要的View
其实最后这一点就是困扰了我一个多小时的东西。当时想实现图片详情页的菜单栏,但是发现按下去的时候没有Bottom的阴影动画。所以一开始就一直在想怎么处理这个,甚至想着要不自己重写一下Toolbar类里面的菜单的style属性(因为发现菜单项貌似是ImageBottom
,而且也查到了用什么style属性可以去除)。
后来突然意识到是不是可以像网上一些自定义居中TextView
一样,去做类似的处理。但是一开始在写的时候完全忘记了要怎么样去排列view的位置,甚至因为外面的rooe view是constraintLayout
所以想直接去写constratRight_ToRightOf
属性...结果发现,好像直接用layout_gravit
y就可以。
实在是佩服自己傻得可以 (扶额)
反正今晚的小问题算是解决了吧,明天针对项目这块的话,打算弄一下点击更多按钮的弹出菜单。目前来看,感觉像是用CustomDialog
写的。但是目前还不太确定,到时候再试试看吧。
然后是看书的内容,进阶之光就再做一下多线程编程章节的笔记,剩下的要不就试试看网络编程这块吧。尤其是框架这块,感觉也可以再了解一下。今天好好的对着郭神的书和网上的笔记和其他的一些内容看了下,那本书真的就是一个帮助你建立框架的入门书记,高阶的东西还是要自己去寻找一些更好的文章或者书籍再去建立基础。
最后还有一个,把掘金上的内容顺带的也发布到了CSDN上。对比完之后发现...掘金的体验确实要纯粹一些,而且不少内容要好一点点。只能说,确实差距很大。CSDN还是太...本土化了,掘金就相对的互联网一点。
趁着这段时间课少,还是要多努努力。一点一点来,克服焦虑,充实自己的知识库。噶油!
我靠,属实是没想到居然开始断电了...本来前几天一直没有断电,还以为这学期开始不会再断了。虽然是情理之中,但还是在意料之外。只能说,以后一定要在12点之前处理完所有事情了。
原本今天还打算花点时间把图片详情页的部分多写一些的,看来只能等睡醒之后去处理。悲(x
今天主要还是把之前在进阶之光里面的多线程的内容再读了一遍,好好的整理了一部分笔记。但是多线程完全弄懂真的还是挺花功夫,今天看了一大半时间还只是读了一半的内容。晚上安慰了焦虑的凯子之后,原本的一些时间也无了。其实本来下午两点多的时候也是可以再学习一会儿的,可惜用去摸鱼了...虽然说还是要劳逸结合吧,但还是有点不甘心。
因为很多事情不可能是在主线程上一口气就全部就做完的,所以一些耗时间的操作都需要我们自己手动去开启线程去操作。
- 继承
Thread
类 - 实现
Runnable
接口 - 实现
Callable
接口
开启线程后,对部分需要在不同线程中进行共享的数据和对象,要做同步和加锁,以保证数据的安全。
volatile
-> 将变量的数据进行及时更新,保证数据一致性和可见性- 同步方法 -> 对方法中的资源进行保护,避免竞争;自动释放
- 同步代码块 -> 对代码块中的资源进行保护,避免竞争;手动配置需要上锁的对象,自动释放
- 重入锁+条件对象 -> 当不满足条件时自动释放锁并阻塞线程;手动上锁和释放
再一个就是collection的HashMap
,顺带还复习了一下Hash的处理方法 (话说没想到这玩意儿居然是在util包里)
- Java 1.8开始使用数组+链表(红黑树),每次将map放进数组前需要对
k.hashCode
进行hash计算下标(二次hash,减少碰撞),之后保存为Node并放入数组中。当发生碰撞后,就使用链表将数据向后存放;当链表长度大于8后就改为使用红黑树。 - 有两个关键参数:capacity和load factor。默认长度为16,比例是0.75。当使用了12个下标后,就将长度拓展为2n(也就是16),
- get()每次从数组第一个进行查询,如果命中就直接返回;没命中就判断数组后面是否有链表/红黑树,并进去查找;再没找到,就换数组的下一个进行查询
对于Android开发本身相关的内容,今天其实并没有怎么看。和教练在晚上沟通的时候意识到实习方面还是重点在Android开发上,像是算法和Java、计算机网络八股等等并没有那么的重要。虽然算法方面我不意外,但还是担心像其他的基础内容会不会有影响。不过细想一下也是有一定道理的,确实也应该稍微把复习的内容做点微调。明天 (实际上写的时候已经是“明天”了233333) 开始复习一下
fragment和ContentProvider的内容 (其实本来是今天想要看的...) 吧,顺带看一看之前复习过的Handler和Service的使用(按照郭神书上的内容来看,这也算是Android多线程相关的内容。不过我还是觉得coroutine
更重要一点,也更加接近kotlin中的多“线程”)。
还是那句话吧,不能太贪心,但是也不能没有要求。上午九点半还约了宝莱他们寝室一起去看来学院春招的企业,也不知道自己到底是个什么情况。嘛,随缘吧。
但行好事,莫问前程
很罪恶的两天。首先是昨天上午所有时间都用去看学院的双选会去了,下午上水课的时候本来可以再认真学一点的,虽然“量子速读”了网络那一块的内容,但其实并没有那么过脑子。周六一整天也就晚上吃完饭的时候稍微认真的把周五的剩下的一点工作完成了...总体而言就是在一个焦虑但又不那么焦虑的两天中,以摸鱼为主的学习。
今天终于明白了那个GridLayoutManager
实现动态设置每一行的子项如何实现:spanSizeLookup
。一开始还以为是可以直接设置子项所在的列如何排列的,crush了之后好几次+看文章里面的文字好几遍才意识到,它的正确使用方法,应该是在一开始初始化LayoutManager
的时候就首先设置足够大的span,然后可以通过这个方法去修改子项所占有span中的数量。(看起来其实还挺像BootStrap的动态网格)
本来还想再实现一下应用的闪屏(splash),后来发现Google的API只能在API31+使用,向前兼容的Compact
库又不使用AppCompact
的Theme。有点离谱,不太想给自己找麻烦,于是作罢。
完全没读书的一台,凭着DDL让自己稍微写了那么一点点的代码。对自己上床再看一点八股之类的不抱希望了,只能寄托于明天早上起床之后早点做完家务早点学习吧(x
在网上又给几个HR发了消息,但是也完全没有了下文。emmm,其实也好,反正准备的也并不是那么充足。但是现在的市场也确实是Android相关的岗位会少亿些,怎么说呢,选择了也没啥后悔的,只能说要自己主动、积极去改变了
明天好好再给网络这块儿做点笔记吧,之前好像还在网上找过一些免费的API接口来着,试着自己用用然后配合协程看看。(话说协程真的是又强大又诡异的神奇东西...)
精神状态上比昨天好上不少,所以即使今天也挺摸鱼的,心情也算得上是不错的。和快三个礼拜没有见过的爸妈一起吃了我做的饭(今天的饭菜也比昨天的好上不少),鼓起勇气和老爸申请换一台新的电脑,和同学晚上聊了一会儿天。某种意义上也算是好好放松了一下吧,这样算下来,还是周一到周五用力学习,然后等周末再稍微放松放松。如此生活学习的话,应该能对自己有不小的帮助。
下午稍微看了一点网络和多线程的一些简单内容,然后决定暂停手上的项目,先换一个新的DEMO去试试网络、线程和多线程相关的内容。这方面我觉得也挺重要的,大概等手写请求这方面稍微熟络后,再回去看一看UI相关的内容吧。 (所以要开新的仓库了) (刚刚和教练交流了一下,感觉之后还可以再看看RxJava的内容)
勉宝晚上也突然回复了消息,说新公司有wlb,好羡慕...然而自己简历上面啥都不敢写,太尴尬了... (突然焦虑)
今天本身产出和学习也不多,就偷个懒先写到这里吧。明天下午好好弄一下~
新的笔记本到了,32GB内存跑项目和虚拟机真的太舒服了,后面几天开始如果不好好学习测试的话,那实在是太对不起新机器了 (逃)
今天上午起床整个人都不太舒服,硬撑着上完了早八,回来就睡觉了。下午简单的修改了一下webResource的Demo,没多久新机器就到了,兴冲冲的去1314找宝莱他们开箱验机,然后就是花费大量时间的数据迁移还有配置环境...
晚上快结束的时候简单的试了一下build&run之前的CreamWallpaper项目,发现用nexus5跑也会cursh,终于意识到应该是我自己代码的问题。简单思考了一下,发现还是在获取屏幕宽(dp)之后的处理上出了问题,导致让column出现0的情况。和教练交流后了解到在UI相关计算方面还是要多使用roundToInt来着。
一是浮点数转整型,除了普通的
toInt
,还有roundToInt
。然后还有两个需要传参的顶级函数,一个是ceil
一个是floor
。前者向上取整,后者向下取整然后第二个就是你可以限定你要的整型在哪个区间里面,
coerceIn(min,max)
;或者单独限制上下限coerceAtLeast(min)
/coerceAtMost(max)
。不过没记错coerce
系列函数浮点数也能用来着
话说怎么突然提到这个
因为你说的这个错误就可以用这些函数规避掉a
还有
roundToInt
这个其实听说过,但是因为用的少+平时感觉自己不太注意细节,习惯上直接用
toint
了(
比如你的
spancount
,我希望它最小2最大5,那在上面那个用法里面你就肯定不会出现设置个spancount
为0的情况。我的意思就是,很多ui上面需要计算乘除法的时候,优先考虑用roundToInt
,然后结合后面我说的那些coerce
系列函数来限定范围
虽然说有开心,但是更多的还是摸鱼。值得庆幸的是,知道了一个之前自己一直没怎么注意到的点。明天起来再好好研究一下这个东东~
应该是在360f/400f运算完结果后再把2转换2f来着吧
可以decompile看看是编译期就做了还是jit做的
教练:你还有很多工作没做哦(阿米娅音)
在做了在做了 (失去理智.jpg)
已经记不得昨天忙碌了些什么,依稀能感受到的只有残余的焦虑感。今天也是。
如果硬要说有点什么收获,大概就是把网络请求的三个类型,还有Gson,都简单的使用了一下。新的Demo在跟着书上写的简单内容一起写的话,总是能成功。但是当我尝试自己使用Coroutine的时候,一切都乱了套。
刚开始是使用的thread{}
开启子线程,然后当子线程获取到数据后,再手动调用runOnUiThread()
。虽然目前看起来没什么毛病,但是总觉得会有很大的耦合(说不清道不明,可能还是没有完全理解透彻)。后面尝试手动去阻塞线程,发现有点不太对。经常会出现空指针之类的crush。想了想还是改回之前的版本,不过因为分别尝试了HttpURLConnection,OkHttp和Retrofit三个获取数据的方法,突然发现好像可以把获取结果最后刷新UI的方法提取出来。同时,再把之前给Rv传递的List单独放在类成员中。感觉稍微的舒服了一点。
今天上****课的时候,想着再看看协程的内容。不知道是我的问题,还是郭神书中的介绍确实比较乱,依旧是没有看懂...对协程的概念真的很混乱。但还是自己尝试着用Job
对象创建了CoroutineScope
,然后用launch{}
主动开启一个协程。之后突然想到,我在协程中进行的网络请求是可以用async.await()
来做到协程内的异步。感觉顿悟(?)了。啊对,中间有一次甚至还直接把Retrofit的请求放在了主线程中,没想到直接throw Exception。大概是它里面的实现全都是suspend吧,不然不应该报错(?)。对了,中间有一次打算手动切换一下获取到的数据,然后直接把Adapter引用的List对象换掉了。后面发现数据没法更新,才知道原来那玩意儿不能换,只能把List换成Mutable,然后手动clear()和 addAll()
...好呆哦
现在对网络请求和异步的认识就是:所有IO操作都应该先放在子线程/协程中,对需要集中处理的,可以使用await()或者阻塞队列去统一处理。如果流程不清晰的,可以自己先画一遍流程图,把所有情况想清楚之后再动手coding。(中间想一出是一出的写代码,真的挺乱脑子的...)
草,猛然想起来昨天还大概的看了一下itemDecorator
。主要也就是两个方法:getItemOffset
和onDraw
。前者负责给ItemView设置出类似于pendding/margin的空白区域,后者负责在ItemView的底部去进行绘制,而空白区域可以显示出底部的内容,变相的实现了分割线的效果。
中间还涉及到了获取颜色资源的内容(ContextCompat.getColor(context, R.color.black)
,而很多文章里写的context.resources.getColor()
貌似并不能获取到Resouce/color.xml
里的结果...还没来得及弄清楚啥原因,反正当时挺烦人的)。再一个就是当时想获取R.dimen.Divider_Height
来着,但是也获取不到,只能自己手动写死一个2px的数值在里面。
对于方法的重写,发现了好像getItemOffset
是对在屏幕内存在的view进行渲染(不过好像根据Rv的缓存机制来说貌似不是?但是我打了Log发现貌似就是这样来着),如果要加载列表下方的内容,则会对最下方要新进入屏幕的Item去设置offset;加载上方的内容也是同理。所以说列表中的所有项目都会去设置offset;但是onDraw并不和getItemOffset一样,貌似是一次性的Draw来着。我当时是发现网上看到的代码可以做到最后一个列表项不进行绘制,所以想让最后一个列表项也不进行offset。不过一直没弄成。每次调用parent.indexOfChild()
获得的都是当时屏幕中的index,而不是背后数据列表的index...可能之后有空再思考一下吧。说来也有趣,第一次发现原来Google提供了DividerItemDecoration()
,所以压根可以不用去自己实现
最后就是焦虑的部分了。大厂陆续开放暑期实习了,但是小公司大多都还是需要尽快到岗。也不知道这样拖下去,暑假能不能有实习机会。现在是又想要实习,又怕要面对实习的面试/笔试。每次上牛客都看到别人的建立贼牛逼,一堆的项目先不说,八股文和DAS都是一个个的了解/熟悉。也不知道自己前四年都干了点什么...哎。看着宝莱每天早上起来背八股,然后还有很多的新的视频资料(Java后端确实卷,资料也确实多(都是相比于客户端而言))。自己...也不知道现在这样是好是坏。身边关系好的同学和网友都说现在我的状态很不错,但是依旧很焦虑,不知道要怎么办才好。每天说学习也确实有在学习,但是总觉得进度不够,嘛...
可能还是要好好睡一觉吧。
趁着还有一个小时不到的时间,赶紧先把总结写了(x
早上起来简单的看了一下教练昨晚提到的两点:主线程网络请求被Exception,Rv的List数据在notifyDatasetChanged()之后没有响应(后者简直是暴露自己在Java上的不熟悉...太丢人叻)
主线程的网络请求主要是因为StrictMode的原因,系统对在主线程的所有IO耗时请求进行了限制。但是可以自己手动修改参数去除。但是notifyDataChanged()这个主要是因为自己修改引用了。这方面主要还是自己对pass-by-value这块理解不够深刻。不过可能今天没时间去总结了,只能再拖到明天早上去看 (悲)
上午上课的时候基本上都用来摸鱼看外文文章还有知乎问答叻。文章主要就看了两块:一个是MinSDK,TargetSDK还有CompileSDK三者的区别;另一个就是git的Rebase和Merge的区别。
MinSDK决定了App可以安装的最低系统版本,TargetSDK决定了SDK在系统中的具体逻辑行为,CompileSDK决定了SDK由哪个版本的Android SDK Tool编译。MinSDK-TargetSDK之间的API版本会保持较好的体验,因为SDK大多会针对低版本做不同的实现,尽可能达到一致的效果,而TargetSDK-CompileSDK之间的API版本主要的表现行为以TargetSDK为准,而CompileSDK的版本号可以保证在TargetSDK版本号以上的系统中不会出现未定义行为,防止出现闪退等现象。
Git的Merge和Rebase的目的都是为了合并分支,但是并没有完全的优劣。Merge可以使得提交记录更加明晰,而且每个commit都不会被变动;Rebase可以让分支更加干净,不过需要对每个commit去处理冲突。具体情况需要根据开发的流程决定。不过有作者推荐,对于自己pull的内容,可以考虑使用rebase,让分支更加干净;对于合并主分支(或者说主版本)的内容,考虑继续使用merge。
下午和超超出去办了点事情,他去注销手机卡,我去银行办转账。然后旭辉旁边那个网点信用卡中心的小哥人挺好的,帮我分析了一下我的征信记录情况,给了一点养征信记录的建议,好感度+1。以后对这方面估计也得更上心一点,确实还蛮重要的。
回学校之后就开始摸鱼,上床玩了一会儿手机,然后拖到了下午四点半才去睡觉。一个小时后起来,约了宝莱去食堂吃饭,路上又聊了一会儿。感觉他的行动力比我强多了,人家每天都花很多时间在学习和背八股上,自己确实差点意思,得加油。
晚上开始看八股,之前项目的内容就完全没有动过了。看了一点深拷贝浅拷贝的内容,还有try-catch-finally执行顺序的新知识(以前还真没注意过)。不过话说回来,看深拷贝浅拷贝之后,对早上那个Rv的List更新的事情还是没有太理解(或者说,描述不清楚?),要完全弄明白估计还是得等明天早上自己弄清楚了。
拷贝主要是指把对象内的所有成员变量都复制一份到新的对象中,但是深拷贝和浅拷贝的区别主要是在于是复制成员变量中引用类型成员变量的值还是其引用。浅拷贝就不必多说,难点和深一点的内容基本上都是在深拷贝里面。深拷贝的实现方式有两种,一个是实现Cloneable接口,还有一个是实现Serializeable/Externalizable接口。对于数组、Date等引用对象,JavaAPI中已经实现了Cloneable接口,而对于其他自定义的对象,则需要我们自己去实现。主要需要注意的地方,是要把类对象中引用成员变量的内容,通过自己手动新建对象并将被克隆对象中引用成员变量的值复制进来。如果是使用Serializeable接口,则需要注意,如果有不希望被序列化的成员,需要对其使用transient关键字进行声明。或者是使用Externalizable接口,自己手动实现对象序列化过程中会被序列化的数据。而transient关键字本身也有一定的注意事项,一个是声明该关键字之后对应的变量在Clone后是不会有值的;再一个就是它只能用于声明变量,而不能对方法和类使用;最后一个,对于const变量,transient是不会生效的,也就是说const变量并不会被序列化。
今天也和之前很久没联系的梓祥发了消息,他也给了一些建议。算下来,感觉自己要补的内容真的好多,照这个速度下去,真的不知道自己来不来得及。这学期还有一些课程我要去补修处理,不知道来不来得及。下学期也是,属实头疼...某种意义上,是给自己埋了个坑 (哎)
只能说,以后少留坑,多填坑。别最后只是感动自己,做很多无用功。
又是一次三天没有写记录。然而并不是去认真体验生活了,或者说,是我自己不这么觉得。
还是没有摆脱焦虑的状态,甚至更加严重了点。不过对于目前找不到实习这件事情倒是看开了不少:毕竟自己能力确实差了那么些,大公司是不指望了,小公司现在的实习都是需要尽快到岗的。所以某种意义上,算是有喘息的时间去慢慢准备了,也可以安心下来去准备,认真的写项目和复习八股。但是怎么说呢,这方面还是感觉自己没有把握好如何去处理两者的平衡关系。啊对了,补修课程的事情...明天上Web课的时候看一下吧,确实拖不得叻
今天把Java并发相关的内容看了一看,算是简单的结束了。(然而并没有看完,只是剩下的内容啃不动了)
首先从创建多线程的方式开始:Runnable,Callable和继承Thread。然后使用Future去获取线程运行结果,同时还可以使用阻塞队列实现消费者-生产者模型,或者是利用它去调用线程池。
阻塞队列有很多中实现,比如LinkedBlockingQueue,ArrayBlockingQueue,SynchronousQueue和PriorityBlockingQueue。前两个只是队列实现的数据结构不同,后者一个是无容量,只可以当有消费者试图获取线程时才会创建,一个是具有优先级。而这些不同的队列,某种程度上对应了不容的线程池:newFixedThreadPool,newCachedThreadPool,newSingleThreadExecutor和newSchedualedThreadPool。线程池当有任务到达时,首先判断是否有核心线程可提供,如果没有,则放入队列并阻塞;当队列满后,启动非核心线程执行任务;最后线程池全满,则执行rejectedExecutionHandler去处理新的任务。
死锁的四个条件:互斥、请求和保持、循环等待、不可剥夺。因为互斥是锁的本质,所以不能打破。只能从后面三个条件入手。如果不能全获取,就放弃手上已有全部;资源编号,请求资源必须有序;请求资源必须一次性全部获取。
如果要上锁,考虑悲观锁和乐观锁两种。悲观锁是认为上锁的数据一定会被其他线程修改,所以必须完全保护起来,排除干扰。比如使用synchronized/reentrantlock,后者还可以设置condition,在一定条件下进行释放锁和通知的功能。乐观锁就不认为使用的数据一定会被其他线程修改,如果有冲突,就反复请求,直至成功为止。比如CAS(compare-and-swap),修改数据前先确认数据是否是原数据,无误后就进行修改。
大概粗略的就这么些吧。然后就是Android的部分,Context,动画和IPC里的Message。
因为Android是组件化的应用程序,所以应用中需要一个上下文去管理组件和系统交互的部分。像Activity,Service和Application都是继承自Context的。但是他们并不是真正的Context,因为Context只是一个接口,而真正的实现是ContextImpl类。不过在ContextWrapper中会包含对它的引用,所以当我们使用Service等的Context中的方法时,实际调用的还是ContextImpl对象。一个Application中,Context的数量是"Activity数 + Service数"。从这里其实也可以看出,不同的对象引用出来的Context尽管是同一个对象,但是仍然有不同的作用域。所以说,如果Context使用不当,可能会导致内存泄漏或者是应用Crush。
然后是动画:帧动画和补间动画还有属性动画。帧动画类似于GIF,主要是注意图片资源不要过大(OOM);补间动画形式单一,不会影响View的属性,只是在视觉上有影响;属性动画可以完全的改变View的属性,通过使用ValueAnimation/ObjectAnimation对属性和起始/末位值进行标注,然后TypeEvaluator进行差值计算,实时更新View的属性即可。
最后是Message,利用了Handler传递Message,然后通过what和Bundle去辨别信息来源和将信息的内容进行封装。这块有把实例代码修改,但是感觉依旧不熟练(好吧其实上面也是orz)
结束了一段本来就没有希望的Relationship,和考研失败许久没见的朋友一起逛了街吃了饭,做了两天失败的饭菜,用吸尘器好好打扫了一次家里。完全可以用混乱和脑子不在线形容这几天的自己,虽然也不是第一次了。嘛...感觉又回到了自己一个人的日子,可能,以后也一直要这样了吧。
应该,都会好起来的(
早点睡吧zZ...
上午上课的时候主要看MyBatis的内容去了,下午睡了一觉起来之后就去倒腾了一下Serveless,有点上手了,但是还没有搞清楚怎么读取API网关的内容,RESTfull的请求怎么去做也没想清楚。不过有一点苗头了,应该也是好事一件。如果能成功的话,简历上应该可以加上一笔(不过貌似又是再挖坑...所以还是先好好把UI和逻辑部分写好吧,网络部分之后再说x)
晚上开始重新捡起了之前的项目,把搜索页面简单的写了一下,做了一个共享元素切换。效果还不错,主要是需要在两个Activity之间首先添加window.enterTransition()
和window.exitTransition()
,然后对两个xml中的元素添加android:transitionName
属性,之后去需要进行切换的起始页面中调用ActivityOptionsCompat.makeSceneTransitionAnimation(activity, sharedElement, sharedElementName)
,最后使用startActivity()
即可。
之后发现在第二个Activity中直接调用finish()
是没有动画的,后面查到了finishAfterTransition()
可以满足需求。
再一个发现,就是Theme中对于很多View组件有外观的定义,可以通过自定义其中的一些属性并应用到当前的themes.xml
就可以了。不过自己实在是弄不懂中间那么多的属性,目前还是只能靠查别人写好了的,然后直接贴上去。今天就是通过这样的方法去修改了toolbar中navigationIcon的右边距,使得serachActivity中间的EditText宽度变大一点。而且toolbar中间也可以再嵌套一个ConstraintLayout,这样就可以让右边的元素尽可能的看起来整齐一些。
最后就是不知道searchActivity中的热门搜索部分怎么写比较好。第一反应是用RecyclerView,但是感觉不太对。不过没有再尝试,毕竟也挺晚了,就干脆明天早上再说吧。
突然想起来,还有一个地方:需要在启动Activity后自动弹出输入法。这个其实也挺重要的,网上目前看到的一些部分貌似好像还解决不了,估计也得到时候再看看了。今天完全没有复习八股文的内容,有点愧疚...哎
还是玩手机玩多了(瘫
早睡早起吧,对身体好一些
上午起来先看了一下昨天没有处理完的内容,思考了昨天没有处理掉的dialogFragment的问题(然而并没有成功)。中午回去再刷了一会儿BOSS直聘,没想到第一次收到了别人对我的询问,也第一次收到了有HR直接说想要我。尽管公司一言难尽吧,但还是很开心,某种意义上算是一个肯定。之后睡了会儿,起来再次处理一下dialog的问题:没法处理点击外部取消弹出。没想到最后是在自定义dialogFragment里的onCreateView调用了dialog.setCanceledOnTouchOutside(true)才成功实现。之前在activity中对新建的dialogFragment对象设置isCancelable还有在自定义dialogFragment中去直接设置isCancelable都没有成功。非常诡异...
之后又想着修改一下Tablayout的样式,踩坑了很久到底是应该把tabMode写成fixed还是scrollable。一开始以为可以写成fixed+tabGravity+textAppearance,没想到这么设置发现tabGravity失效了,tabItem全部集中在中间的位置。后面发现scrollable+start就可以实现,完全没想到之前居然卡壳了这么久。有被自己蠢到。
最后把dialogFragment里面的button重新写了一下样式,发现原来默认主题下button其实是调用的materialButton的Theme,自己复写是没有用的。只能把Button换成android.widget.button,这才变成了自己写的样式。不过现在发现,Theme和Style里的东西还是蛮神奇的,不过貌似这方面的文章真的太少了,完全靠自己碰到问题解决之后才能意识到它有多重要。很多样式其实是可以在弄清楚view的属性之后快速的去实现样式的,而不用自己费大功夫去重写类。而且Theme对于一些类的属性还会有很多很神奇的效果,不过还是得等之后碰到了再慢慢看了。
今天终于把拖了很久的补修课程跟班情况查了一下,这礼拜因为要出去玩,原来应该周五就去找的老师就得再拖一拖了(瘫)。不过也正好趁这个机会和同学好好交流感情,放松一下。晚上和梓祥交流意识到,工作中遇到的问题有时候才是真正推着自己学习的动力。也许还是学生思维作祟吧,总是觉得要成体系的一步一步学习。不过我也觉得可能是受到了大厂招人总是看八股文的影响吧,这个思路也一直很难转变过来,哪怕是工作上也经常会遇到自己从没碰到过的问题,依旧逃不脱Bing和Google的命运。只是可能需要自己再花时间去整理并建立知识体系,这大概也是到了大学之后才真正大范围锻炼的能力。
和1314的同学吃完饭,又和文林聊了很久。再一次操练起自己和别人谈心的本领,试图帮助他解决过去的一些自卑的小问题。不过话说回来,自己这方面倒是一直没有什么改进(笑)。只能说有时候,医者不能自医。
好晚了,明天还有早八。狗命要紧(x
剩下的随缘补充...