最后
跳槽季整理面试题已经成了我多年的习惯!在这里我和身边一些朋友特意整理了一份快速进阶为Android高级工程师的系统且全面的学习资料。涵盖了Android初级——Android高级架构师进阶必备的一些学习技能。
附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题(含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
@GlideModule
public final class MyAppGlideModule extends AppGlideModule {}
执行 Make Module ‘app’ ,工具栏貌似锤子的图标,很遗憾报错了,按照官方文档进行操作还有错吗???
不要慌,仔细查看控制台的错误信息,编译失败。gradle配置targetSdkVersion 29 对应的是google的AndroidX,那么可能是这个原因,无法加载android.support.annotation包下api,那么谷歌官方肯定针对这个问题提供了相关的依赖包
androidx.annotation:annotation:1.0.0
最后添加下面的依赖到gradle并执行Make Module ‘app’,很高兴编译成功了,折腾了一小会总算可以继续往下走了,多大的事貌似就被针扎了一下,接下来调用GlieApp中静态放心加载图片:
annotationProcessor ‘androidx.annotation:annotation:1.0.0’
加载图片工具类:
public static void loadImagePic(Context context, String url, ImageView imageView) {
GlideApp.with(context)
.load(url)
.error(R.drawable.ic_launcher_background)
.placeholder(R.drawable.ic_launcher_background)
.into(imageView);
}
- 2、创建列表布局文件 activity_main.xml
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android=“http://schemas.android.com/apk/res/android”
xmlns:app=“http://schemas.android.com/apk/res-auto”
xmlns:tools=“http://schemas.android.com/tools”
android:layout_width=“match_parent”
android:layout_height=“match_parent”
tools:context=“.MainActivity”>
<GridView
android:id=“@+id/gvPic”
android:layout_width=“match_parent”
android:layout_height=“wrap_content”
android:horizontalSpacing=“10dp”
android:layout_marginLeft=“10dp”
android:layout_marginRight=“10dp”
android:layout_marginTop=“80dp”
android:numColumns=“4”
tools:ignore=“MissingPrefix” />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
- 3、创建列表每一项布局文件gv_camera_pic_item.xml:
<RelativeLayout xmlns:android=“http://schemas.android.com/apk/res/android”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:orientation=“vertical”>
<ImageView
android:id=“@+id/ivCameraPicDefault”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:background=“@drawable/iv_camera_round_bg”
android:scaleType=“center”
android:src=“@drawable/ic_camera” />
<ImageView
android:id=“@+id/ivCameraPic”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:visibility=“gone” />
<ImageView
android:id=“@+id/ivDelete”
android:layout_width=“40dp”
android:layout_height=“40dp”
android:layout_alignParentTop=“true”
android:layout_alignParentRight=“true”
android:background=“@drawable/ic_delete”
android:visibility=“gone” />
- 4、创建列表适配器:
适配器配器构造函数:启动Activity完成初始化就将picDefaultId相机图片添加到数组队列中,添加点击事件是方便点击相机图标进行选择手相册图片或拍照:
ImageAdapter(Context c, int picDefaultId, GvItemClick gvItemClick),
点击默认相机图标就会在图片数组中添加成功选择或者拍照的图片;
点击新增图片右上角的删除图标,对当前在该数组存在的图片进行逐个删除.
changeAdapterAddData(Integer picId)和changeAdapteRemoverData(int i)
计算每张图片需要的宽与高,运用这个算法获取的宽度,然后动态为ImageView添加布局参数。
public int getGvItemWidth(Context context) {
Display display = ((Activity) context).getWindowManager().getDefaultDisplay();
int width = display.getWidth();
//int height = display.getHeight();
return (width - dip2px(context, 50)) / 4;
}
public class ImageAdapter extends BaseAdapter {
private Context mContext;
private List mPics = new ArrayList<>();
private GvItemClick mGvItemClick;
public ImageAdapter(Context c, int picDefaultId, GvItemClick gvItemClick) {
mContext = c;
mPics.add(picDefaultId);
this.mGvItemClick = gvItemClick;
}
/**
-
刷新列表数据
-
@param picId
*/
public void changeAdapterAddData(Integer picId) {
mPics.add(0, picId);
//mPics.addAll(0, picIds);
notifyDataSetChanged();
}
public void changeAdapteRemoverData(int i) {
mPics.remove(i);
//mPics.addAll(0, picIds);
notifyDataSetChanged();
}
@Override
public int getCount() {
return mPics.size();
}
@Override
public Object getItem(int position) {
return mPics.size() > 0 ? mPics.get(position) : null;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = null;
if (convertView == null) {
convertView = View.inflate(mContext, R.layout.gv_camera_pic_item, null);
viewHolder = new ViewHolder();
viewHolder.ivCameraPic = convertView.findViewById(R.id.ivCameraPic);
viewHolder.ivCameraPicDefault = convertView.findViewById(R.id.ivCameraPicDefault);
viewHolder.ivDelete = convertView.findViewById(R.id.ivDelete);
//设置每一项宽和高
int width = getGvItemWidth(mContext);
viewHolder.ivCameraPic.setLayoutParams(new RelativeLayout.LayoutParams(width, width));
viewHolder.ivCameraPicDefault.setLayoutParams(new RelativeLayout.LayoutParams(width, width));
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
//End item
if (position == getCount() - 1) {
viewHolder.ivDelete.setVisibility(View.GONE);
viewHolder.ivCameraPicDefault.setVisibility(View.VISIBLE);
viewHolder.ivCameraPic.setVisibility(View.GONE);
viewHolder.ivCameraPicDefault.setImageResource(mPics.get(position));
} else {
viewHolder.ivDelete.setVisibility(View.VISIBLE);
viewHolder.ivCameraPicDefault.setVisibility(View.GONE);
viewHolder.ivCameraPic.setVisibility(View.VISIBLE);
viewHolder.ivCameraPic.setImageResource(mPics.get(position));
}
viewHolder.ivDelete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mGvItemClick != null)
mGvItemClick.gvItemClick(R.id.ivDelete, position);
}
});
viewHolder.ivCameraPicDefault.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mGvItemClick != null)
mGvItemClick.gvItemClick(R.id.ivCameraPicDefault, position);
}
});
return convertView;
}
public static interface GvItemClick {
void gvItemClick(int viewId, int postion);
}
/**
-
获取gv每一项宽度
-
@param context
-
@return
*/
public int getGvItemWidth(Context context) {
Display display = ((Activity) context).getWindowManager().getDefaultDisplay();
int width = display.getWidth();
//int height = display.getHeight();
return (width - dip2px(context, 50)) / 4;
}
public class ViewHolder {
ImageView ivDelete;
ImageView ivCameraPic;
ImageView ivCameraPicDefault;
}
/**
最后
为了方便有学习需要的朋友,我把资料都整理成了视频教程(实际上比预期多花了不少精力)
当程序员容易,当一个优秀的程序员是需要不断学习的,从初级程序员到高级程序员,从初级架构师到资深架构师,或者走向管理,从技术经理到技术总监,每个阶段都需要掌握不同的能力。早早确定自己的职业方向,才能在工作和能力提升中甩开同龄人。
- 无论你现在水平怎么样一定要 持续学习 没有鸡汤,别人看起来的毫不费力,其实费了很大力,这四个字就是我的建议!!
- 我希望每一个努力生活的IT工程师,都会得到自己想要的,因为我们很辛苦,我们应得的。
当程序员容易,当一个优秀的程序员是需要不断学习的,从初级程序员到高级程序员,从初级架构师到资深架构师,或者走向管理,从技术经理到技术总监,每个阶段都需要掌握不同的能力。早早确定自己的职业方向,才能在工作和能力提升中甩开同龄人。
无论你现在水平怎么样一定要 持续学习 没有鸡汤,别人看起来的毫不费力,其实费了很大力,没有人能随随便便成功。
加油,共勉。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
学习 没有鸡汤,别人看起来的毫不费力,其实费了很大力,这四个字就是我的建议!!
- 我希望每一个努力生活的IT工程师,都会得到自己想要的,因为我们很辛苦,我们应得的。
当程序员容易,当一个优秀的程序员是需要不断学习的,从初级程序员到高级程序员,从初级架构师到资深架构师,或者走向管理,从技术经理到技术总监,每个阶段都需要掌握不同的能力。早早确定自己的职业方向,才能在工作和能力提升中甩开同龄人。
无论你现在水平怎么样一定要 持续学习 没有鸡汤,别人看起来的毫不费力,其实费了很大力,没有人能随随便便成功。
加油,共勉。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!