先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
如果你需要这些资料,可以添加V获取:vip204888 (备注Android)
正文
我们代码中引入了一个边界颜色,如果设置的话,着色的边界参考为该边界颜色,否则会只要与种子颜色不一致为边界。
(一)构造方法与测量
public class ColourImageView extends ImageView
{
private Bitmap mBitmap;
/**
- 边界的颜色
*/
private int mBorderColor = -1;
private boolean hasBorderColor = false;
private Stack mStacks = new Stack();
public ColourImageView(Context context, AttributeSet attrs)
{
super(context, attrs);
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.ColourImageView);
mBorderColor = ta.getColor(R.styleable.ColourImageView_border_color, -1);
hasBorderColor = (mBorderColor != -1);
L.e("hasBorderColor = " + hasBorderColor + " , mBorderColor = " + mBorderColor);
ta.recycle();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int viewWidth = getMeasuredWidth();
int viewHeight = getMeasuredHeight();
//以宽度为标准,等比例缩放view的高度
setMeasuredDimension(viewWidth,
getDrawable().getIntrinsicHeight() * viewWidth / getDrawable().getIntrinsicWidth());
L.e("view’s width = " + getMeasuredWidth() + " , view’s height = " + getMeasuredHeight());
//根据drawable,去得到一个和view一样大小的bitmap
BitmapDrawable drawable = (BitmapDrawable) getDrawable();
Bitmap bm = drawable.getBitmap();
mBitmap = Bitmap.createScaledBitmap(bm, getMeasuredWidth(), getMeasuredHeight(), false);
}
可以看到我们选择的是继承ImageView,这样只需要将图片设为src即可。
构造方法中获取我们的自定义边界颜色,当然可以不设置~~
重写测量的目的是为了获取一个和View一样大小的Bitmap便于我们操作。
接下来就是点击啦~
(二)onTouchEvent
@Override
public boolean onTouchEvent(MotionEvent event)
{
final int x = (int) event.getX();
final int y = (int) event.getY();
if (event.getAction() == MotionEvent.ACTION_DOWN)
{
//填色
fillColorToSameArea(x, y);
}
return super.onTouchEvent(event);
}
/**
-
根据x,y获得改点颜色,进行填充
-
@param x
-
@param y
*/
private void fillColorToSameArea(int x, int y)
{
Bitmap bm = mBitmap;
int pixel = bm.getPixel(x, y);
if (pixel == Color.TRANSPARENT || (hasBorderColor && mBorderColor == pixel))
{
return;
}
int newColor = randomColor();
int w = bm.getWidth();
int h = bm.getHeight();
//拿到该bitmap的颜色数组
int[] pixels = new int[w * h];
bm.getPixels(pixels, 0, w, 0, 0, w, h);
//填色
fillColor(pixels, w, h, pixel, newColor, x, y);
//重新设置bitmap
bm.setPixels(pixels, 0, w, 0, 0, w, h);
setImageDrawable(new BitmapDrawable(bm));
}
可以看到,我们在onTouchEvent中获取(x,y),然后拿到改点坐标:
-
获得点击点颜色,获得整个bitmap的像素数组
-
改变这个数组中的颜色
-
然后重新设置给bitmap,重新设置给ImageView
重点就是通过fillColor
去改变数组中的颜色
/**
-
@param pixels 像素数组
-
@param w 宽度
-
@param h 高度
-
@param pixel 当前点的颜色
-
@param newColor 填充色
-
@param i 横坐标
-
@param j 纵坐标
*/
private void fillColor(int[] pixels, int w, int h, int pixel, int newColor, int i, int j)
{
//步骤1:将种子点(x, y)入栈;
mStacks.push(new Point(i, j));
//步骤2:判断栈是否为空,
// 如果栈为空则结束算法,否则取出栈顶元素作为当前扫描线的种子点(x, y),
// y是当前的扫描线;
while (!mStacks.isEmpty())
{
/**
-
步骤3:从种子点(x, y)出发,沿当前扫描线向左、右两个方向填充,
-
直到边界。分别标记区段的左、右端点坐标为xLeft和xRight;
*/
Point seed = mStacks.pop();
//L.e("seed = " + seed.x + " , seed = " + seed.y);
int count = fillLineLeft(pixels, pixel, w, h, newColor, seed.x, seed.y);
int left = seed.x - count + 1;
count = fillLineRight(pixels, pixel, w, h, newColor, seed.x + 1, seed.y);
int right = seed.x + count;
/**
-
步骤4:
-
分别检查与当前扫描线相邻的y - 1和y + 1两条扫描线在区间[xLeft, xRight]中的像素,
-
从xRight开始向xLeft方向搜索,假设扫描的区间为AAABAAC(A为种子点颜色),
-
那么将B和C前面的A作为种子点压入栈中,然后返回第(2)步;
*/
//从y-1找种子
if (seed.y - 1 >= 0)
findSeedInNewLine(pixels, pixel, w, h, seed.y - 1, left, right);
//从y+1找种子
if (seed.y + 1 < h)
findSeedInNewLine(pixels, pixel, w, h, seed.y + 1, left, right);
}
}
可以看到我已经很清楚的将该算法的四个步骤标识到该方法中。好了,最后就是一些依赖的细节上的方法:
/**
-
在新行找种子节点
-
@param pixels
-
@param pixel
-
@param w
-
@param h
-
@param i
-
@param left
-
@param right
*/
private void findSeedInNewLine(int[] pixels, int pixel, int w, int h, int i, int left, int right)
{
/**
- 获得该行的开始索引
*/
int begin = i * w + left;
/**
- 获得该行的结束索引
*/
int end = i * w + right;
boolean hasSeed = false;
int rx = -1, ry = -1;
ry = i;
/**
- 从end到begin,找到种子节点入栈(AAABAAAB,则B前的A为种子节点)
*/
while (end >= begin)
{
if (pixels[end] == pixel)
{
if (!hasSeed)
{
rx = end % w;
mStacks.push(new Point(rx, ry));
hasSeed = true;
}
} else
{
hasSeed = false;
}
end–;
}
}
/**
-
往右填色,返回填充的个数
-
@return
*/
private int fillLineRight(int[] pixels, int pixel, int w, int h, int newColor, int x, int y)
{
int count = 0;
while (x < w)
{
//拿到索引
int index = y * w + x;
if (needFillPixel(pixels, pixel, index))
{
pixels[index] = newColor;
count++;
x++;
} else
{
break;
}
}
return count;
}
/**
-
往左填色,返回填色的数量值
-
@return
*/
private int fillLineLeft(int[] pixels, int pixel, int w, int h, int newColor, int x, int y)
{
int count = 0;
while (x >= 0)
{
//计算出索引
int index = y * w + x;
if (needFillPixel(pixels, pixel, index))
{
pixels[index] = newColor;
count++;
x–;
} else
{
break;
}
}
return count;
}
private boolean needFillPixel(int[] pixels, int pixel, int index)
{
if (hasBorderColor)
{
return pixels[index] != mBorderColor;
} else
{
return pixels[index] == pixel;
}
}
/**
-
返回一个随机颜色
-
@return
*/
private int randomColor()
{
Random random = new Random();
int color = Color.argb(255, random.nextInt(256), random.nextInt(256), random.nextInt(256));
return color;
}
ok,到此,代码就介绍完毕了~~~
最后贴下布局文件~~
最后
其实Android开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。
上面分享的百度、腾讯、网易、字节跳动、阿里等公司2021年的高频面试题,博主还把这些技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,上面只是以图片的形式给大家展示一部分。
【Android思维脑图(技能树)】
知识不体系?这里还有整理出来的Android进阶学习的思维脑图,给大家参考一个方向。
【Android高级架构视频学习资源】
**Android部分精讲视频领取学习后更加是如虎添翼!**进军BATJ大厂等(备战)!现在都说互联网寒冬,其实无非就是你上错了车,且穿的少(技能),要是你上对车,自身技术能力够强,公司换掉的代价大,怎么可能会被裁掉,都是淘汰末端的业务Curd而已!现如今市场上初级程序员泛滥,这套教程针对Android开发工程师1-6年的人员、正处于瓶颈期,想要年后突破自己涨薪的,进阶Android中高级、架构师对你更是如鱼得水,赶快领取吧!
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注Android)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
**,由于篇幅有限,上面只是以图片的形式给大家展示一部分。
【Android思维脑图(技能树)】
知识不体系?这里还有整理出来的Android进阶学习的思维脑图,给大家参考一个方向。
[外链图片转存中…(img-pWZsryMm-1713664351117)]
【Android高级架构视频学习资源】
**Android部分精讲视频领取学习后更加是如虎添翼!**进军BATJ大厂等(备战)!现在都说互联网寒冬,其实无非就是你上错了车,且穿的少(技能),要是你上对车,自身技术能力够强,公司换掉的代价大,怎么可能会被裁掉,都是淘汰末端的业务Curd而已!现如今市场上初级程序员泛滥,这套教程针对Android开发工程师1-6年的人员、正处于瓶颈期,想要年后突破自己涨薪的,进阶Android中高级、架构师对你更是如鱼得水,赶快领取吧!
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注Android)
[外链图片转存中…(img-vjvHt5nl-1713664351117)]
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!