Android核心知识点
面试成功其实是必然的,因为我做足了充分的准备工作,包括刷题啊,看一些Android核心的知识点,看一些面试的博客吸取大家面试的一些经验。
下面这份PDF是我翻阅了差不多3个月左右一些Android大博主的博客从他们那里取其精华去其糟泊所整理出来的一些Android的核心知识点,全部都是精华中的精华,我能面试到现在2-2资深开发人员跟我整理的这本Android核心知识点有密不可分的关系,在这里本着共赢的心态分享给各位朋友。
不管是Android基础还是Java基础以及常见的数据结构,这些是无原则地必须要熟练掌握的,尤其是非计算机专业的同学,面试官一上来肯定是问你基础,要是基础表现不好很容易被扣上基础不扎实的帽子,常见的就那些,只要你平时认真思考过基本上面试是没太大问题的。
最后为了帮助大家深刻理解Android相关知识点的原理以及面试相关知识,这里放上我搜集整理的2019-2021BAT 面试真题解析,我把大厂面试中常被问到的技术点整理成了PDF,包知识脉络 + 诸多细节。
节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : AppCompatButton(context, attrs, defStyleAttr) {
这里实现了继承 AppCompatButton 进行扩展,默认样式 defStyleAttr 传递的是 0,那么 CommonShapeButton 的默认表现形式就是文本样式。
如果想要采用按钮样式,则需要先自定义一个按钮样式,原因是系统按钮的样式自带了 minWidth、minHeight 以及 padding,在具体业务中会影响到我们的按钮显示,所以在自定义按钮样式中重置了这三个属性:
有了自定义按钮样式,那么想要 CommonShapeButton 采用按钮样式,则采用如下形式:
<com.blue.view.CommonShapeButton
style=“@style/CommonShapeButtonStyle”
android:layout_width=“300dp”
android:layout_height=“50dp”/>
到这里就可以实现简单的文本样式和按钮样式的切换了。 接下来我们就要进行关键的 shape 渲染了:
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
// 初始化normal状态
with(normalGradientDrawable) {
// 渐变色
if (mStartColor != Color.parseColor(“#FFFFFF”) && mEndColor != Color.parseColor(“#FFFFFF”)) {
colors = intArrayOf(mStartColor, mEndColor)
when (mOrientation) {
0 -> orientation = GradientDrawable.Orientation.TOP_BOTTOM
1 -> orientation = GradientDrawable.Orientation.LEFT_RIGHT
}
}
// 填充色
else {
setColor(mFillColor)
}
when (mShapeMode) {
0 -> shape = GradientDrawable.RECTANGLE
1 -> shape = GradientDrawable.OVAL
2 -> shape = GradientDrawable.LINE
3 -> shape = GradientDrawable.RING
}
cornerRadius = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, mCornerRadius.toFloat(), resources.displayMetrics)
// 默认的透明边框不绘制,否则会导致没有阴影
if (mStrokeColor != Color.parseColor(“#00000000”)) {
setStroke(mStrokeWidth, mStrokeColor)
}
}
// 是否开启点击动效
background = if (mActiveEnable) {
// 5.0以上水波纹效果
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
RippleDrawable(ColorStateList.valueOf(mPressedColor), normalGradientDrawable, null)
}
// 5.0以下变色效果
else {
// 初始化pressed状态
with(pressedGradientDrawable) {
setColor(mPressedColor)
when (mShapeMode) {
0 -> shape = GradientDrawable.RECTANGLE
1 -> shape = GradientDrawable.OVAL
2 -> shape = GradientDrawable.LINE
3 -> shape = GradientDrawable.RING
}
cornerRadius = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, mCornerRadius.toFloat(), resources.displayMetrics)
setStroke(mStrokeWidth, mStrokeColor)
}
// 注意此处的add顺序,normal必须在最后一个,否则其他状态无效
// 设置pressed状态
stateListDrawable.apply {
addState(intArrayOf(android.R.attr.state_pressed), pressedGradientDrawable)
// 设置normal状态
addState(intArrayOf(), normalGradientDrawable)
}
}
} else {
normalGradientDrawable
}
}
这里的代码有点长,别着急,我们来慢慢分析一下:
- 首先是选择在 onMeasure 方法中做shape渲染
- 其次对 normarlGradientDrawable 设置当前是渐变色渲染还是填充色渲染,渐变色渲染还需要单独控制渲染的方向
- 然后对 normarlGradientDrawable 设置 shape 模式、圆角以及描边
- 最后对CommonShapeButton设置background。如果没有开启点击特效,则直接返回normarlGradientDrawable。如果开启了点击特效,那么 5.0 以上启用水波纹效果,5.0 以下启用变色效果。在变色效果的设置中同样初始化了 pressedGradientDrawable 的 shape 属性,并且依次添加进了 stateListDrawable 用作背景显示
到这里就可以实现了用自定义属性控制shape渲染显示 CommonShapeButton 的背景了,这里贴上全部的属性:
接下来我们还需要进行最后的工作,解决在一个 button 中添加 drawable 不居中显示的问题
override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
super.onLayout(changed, left, top, right, bottom)
// 如果xml中配置了drawable则设置padding让文字移动到边缘与drawable靠在一起
// button中配置的drawable默认贴着边缘
if (mDrawablePosition > -1) {
compoundDrawables?.let {
val drawable: Drawable? = compoundDrawables[mDrawablePosition]
drawable?.let {
// 图片间距
val drawablePadding = compoundDrawablePadding
when (mDrawablePosition) {
// 左右drawable
0, 2 -> {
// 图片宽度
val drawableWidth = it.intrinsicWidth
// 获取文字宽度
val textWidth = paint.measureText(text.toString())
// 内容总宽度
contentWidth = textWidth + drawableWidth + drawablePadding
val rightPadding = (width - contentWidth).toInt()
// 图片和文字全部靠在左侧
setPadding(0, 0, rightPadding, 0)
}
// 上下drawable
1, 3 -> {
// 图片高度
val drawableHeight = it.intrinsicHeight
// 获取文字高度
val fm = paint.fontMetrics
// 单行高度
val singeLineHeight = Math.ceil(fm.descent.toDouble() - fm.ascent.toDouble()).toFloat()
// 总的行间距
val totalLineSpaceHeight = (lineCount - 1) * lineSpacingExtra
val textHeight = singeLineHeight * lineCount + totalLineSpaceHeight
// 内容总高度
contentHeight = textHeight + drawableHeight + drawablePadding
总结
【Android 详细知识点思维脑图(技能树)】
我个人是做Android开发,已经有十来年了,目前在某创业公司任职CTO兼系统架构师。虽然 Android 没有前几年火热了,已经过去了会四大组件就能找到高薪职位的时代了。这只能说明 Android 中级以下的岗位饱和了,现在高级工程师还是比较缺少的,很多高级职位给的薪资真的特别高(钱多也不一定能找到合适的),所以努力让自己成为高级工程师才是最重要的。
这里附上上述的面试题相关的几十套字节跳动,京东,小米,腾讯、头条、阿里、美团等公司19年的面试题。把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。
由于篇幅有限,这里以图片的形式给大家展示一小部分。
网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。
最后,赠与大家一句话,共勉!
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!