《设计思想解读开源框架》
第一章、 热修复设计
-
第一节、 AOT/JIT & dexopt 与 dex2oat
-
第二节、 热修复设计之 CLASS_ISPREVERIFIED 问题
-
第三节、热修复设计之热修复原理
-
第四节、Tinker 的集成与使用(自动补丁包生成)
第二章、 插件化框架设计
-
第一节、 Class 文件与 Dex 文件的结构解读
-
第二节、 Android 资源加载机制详解
-
第三节、 四大组件调用原理
-
第四节、 so 文件加载机制
-
第五节、 Android 系统服务实现原理
第三章、 组件化框架设计
-
第一节、阿里巴巴开源路由框——ARouter 原理分析
-
第二节、APT 编译时期自动生成代码&动态类加载
-
第三节、 Java SPI 机制
-
第四节、 AOP&IOC
-
第五节、 手写组件化架构
第四章、图片加载框架
-
第一节、图片加载框架选型
-
第二节、Glide 原理分析
-
第三节、手写图片加载框架实战
第五章、网络访问框架设计
-
第一节、网络通信必备基础
-
第二节、OkHttp 源码解读
-
第三节、Retrofit 源码解析
第六章、 RXJava 响应式编程框架设计
-
第一节、链式调用
-
第二节、 扩展的观察者模式
-
第三节、事件变换设计
-
第四节、Scheduler 线程控制
第七章、 IOC 架构设计
-
第一节、 依赖注入与控制反转
-
第二节、ButterKnife 原理上篇、中篇、下篇
-
第三节、Dagger 架构设计核心解密
第八章、 Android 架构组件 Jetpack
-
第一节、 LiveData 原理
-
第二节、 Navigation 如何解决 tabLayout 问题
-
第三节、 ViewModel 如何感知 View 生命周期及内核原理
-
第四节、 Room 架构方式方法
-
第五节、 dataBinding 为什么能够支持 MVVM
-
第六节、 WorkManager 内核揭秘
-
第七节、 Lifecycles 生命周期
本文包含不同方向的自学编程路线、面试题集合/面经、及系列技术文章等,资源持续更新中…
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
-
算完自己想要的宽高以后 直接拿resolveSize 方法处理一下 即可。
-
最后setMeasuredDimension 保存。
范例:
public class LoadingView extends View {
//圆形的半径
int radius;
//圆形外部矩形rect的起点
int left = 10, top = 30;
Paint mPaint = new Paint();
public LoadingView(Context context) {
super(context);
}
public LoadingView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.LoadingView);
radius = typedArray.getInt(R.styleable.LoadingView_radius, 0);
}
public LoadingView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = left + radius * 2;
int height = top + radius * 2;
//一定要用resolveSize方法来格式化一下你的view宽高噢,否则遇到某些layout的时候一定会出现奇怪的bug的。
//因为不用这个 你就完全没有父view的感受了 最后强调一遍
width = resolveSize(width, widthMeasureSpec);
height = resolveSize(height, heightMeasureSpec);
setMeasuredDimension(width, height);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
RectF oval = new RectF(left, top,
left + radius * 2, top + radius * 2);
mPaint.setColor(Color.BLUE);
canvas.drawRect(oval, mPaint);
//先画圆弧
mPaint.setColor(Color.RED);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(2);
canvas.drawArc(oval, -90, 360, false, mPaint);
}
}
布局文件:
<com.example.a16040657.customviewtest.LoadingView
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:src=“@mipmap/dly”
app:radius=“200”></com.example.a16040657.customviewtest.LoadingView>
<com.example.a16040657.customviewtest.LoadingView
android:layout_marginLeft=“10dp”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:src=“@mipmap/dly”
app:radius=“200”></com.example.a16040657.customviewtest.LoadingView>
最后效果:
自定义一个viewgroup
这个其实也就是稍微复杂了一点,但是还是有迹可循的,只是稍微需要一点额外的耐心。
自定义一个viewgroup 需要注意的点如下:
- 一定是先重写onMeasure确定子view的宽高和自己的宽高以后 才可以继续写onlayout 对这些子view进行布局噢~~
- viewgroup 的onMeasure其实就是遍历自己的view 对自己的每一个子view进行measure,绝大多数时候对子view的 measure都可以直接用 measureChild()这个方法来替代,简化我们的写法,如果你的viewgroup很复杂的话 无法就是自己写一遍measureChild 而不是调用measureChild 罢了。
- 计算出viewgroup自己的尺寸并且保存,保存的方法还是哪个setMeasuredDimension 不要忘记了
- 逼不得已要重写measureChild方法的时候,其实也不难无非就是对父view的测量和子view的测量 做一个取舍关系而已, 你看懂了基础的measureChild方法,以后就肯定会写自己的复杂的measureChild方法了。
下面是一个极简的例子,一个很简单的flowlayout的实现,没有对margin paddding做处理,也假设了每一个tag的高度 是固定的,可以说是极为简单了,但是麻雀虽小 五脏俱全,足够你们好好理解自定义viewgroup的关键点了。
/**
- 写一个简单的flowlayout 从左到右的简单layout,如果宽度不够放 就直接另起一行layout
- 这个类似的开源控件有很多,有很多写的出色的,我这里只仅仅实现一个初级的flowlayout
- 也是最简单的,目的是为了理解自定义viewgroup的关键核心点。
-
- 比方说这里并没有对padding或者margin做特殊处理,你们自己写viewgroup的时候 记得把这些属性的处理都加上
- 否则一旦有人用了这些属性 发现没有生效就比较难看了。。。。。。
*/
public class SimpleFlowLayout extends ViewGroup {
public SimpleFlowLayout(Context context) {
super(context);
}
public SimpleFlowLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SimpleFlowLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
/**
- layout的算法 其实就是 不够放剩下一行 那另外放一行 这个过程一定要自己写一遍才能体会,
- 个人有个人的写法,说不定你的写法比开源的项目还要好
- 其实也没什么夸张的,无法就是前面onMeasure结束以后 你可以拿到所有子view和自己的 测量宽高 然后就算呗
- @param changed
- @param l
- @param t
- @param r
- @param b
*/
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int childTop = 0;
int childLeft = 0;
int childRight = 0;
int childBottom = 0;
//已使用 width
int usedWidth = 0;
//customlayout 自己可使用的宽度
int layoutWidth = getMeasuredWidth();
Log.v(“wuyue”, “layoutWidth==” + layoutWidth);
for (int i = 0; i < getChildCount(); i++) {
View childView = getChildAt(i);
//取得这个子view要求的宽度和高度
int childWidth = childView.getMeasuredWidth();
int childHeight = childView.getMeasuredHeight();
//如果宽度不够了 就另外启动一行
if (layoutWidth - usedWidth < childWidth) {
childLeft = 0;
usedWidth = 0;
childTop += childHeight;
childRight = childWidth;
childBottom = childTop + childHeight;
childView.layout(0, childTop, childRight, childBottom);
usedWidth = usedWidth + childWidth;
childLeft = childWidth;
continue;
}
childRight = childLeft + childWidth;
childBottom = childTop + childHeight;
childView.layout(childLeft, childTop, childRight, childBottom);
childLeft = childLeft + childWidth;
usedWidth = usedWidth + childWidth;
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//先取出SimpleFlowLayout的父view 对SimpleFlowLayout 的测量限制 这一步很重要噢。
//你只有知道自己的宽高 才能限制你子view的宽高
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int usedWidth = 0; //已使用的宽度
int remaining = 0; //剩余可用宽度
int totalHeight = 0; //总高度
int lineHeight = 0; //当前行高
for (int i = 0; i < getChildCount(); i++) {
View childView = getChildAt(i);
LayoutParams lp = childView.getLayoutParams();
//先测量子view
measureChild(childView, widthMeasureSpec, heightMeasureSpec);
//然后计算一下宽度里面 还有多少是可用的 也就是剩余可用宽度
最后是今天给大家分享的一些独家干货:
【Android开发核心知识点笔记】
【Android思维脑图(技能树)】
【Android核心高级技术PDF文档,BAT大厂面试真题解析】
【Android高级架构视频学习资源】
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
oid核心高级技术PDF文档,BAT大厂面试真题解析】**
[外链图片转存中…(img-xP135fpn-1715124406672)]
【Android高级架构视频学习资源】
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!