总结
学习技术是一条慢长而艰苦的道路,不能靠一时激情,也不是熬几天几夜就能学好的,必须养成平时努力学习的习惯。所以:贵在坚持!
最后如何才能让我们在面试中对答如流呢?
答案当然是平时在工作或者学习中多提升自身实力的啦,那如何才能正确的学习,有方向的学习呢?有没有免费资料可以借鉴?为此我整理了一份Android学习资料路线:
这里是一部分我工作以来以及参与过的大大小小的面试收集总结出来的一套BAT大厂面试资料专题包,主要还是希望大家在如今大环境不好的情况下面试能够顺利一点,希望可以帮助到大家。
好了,今天的分享就到这里,如果你对在面试中遇到的问题,或者刚毕业及工作几年迷茫不知道该如何准备面试并突破现状提升自己,对于自己的未来还不够了解不知道给如何规划。来看看同行们都是如何突破现状,怎么学习的,来吸收他们的面试以及工作经验完善自己的之后的面试计划及职业规划。
最后,祝愿即将跳槽和已经开始求职的大家都能找到一份好的工作!
这些只是整理出来的部分面试题,后续会持续更新,希望通过这些高级面试题能够降低面试Android岗位的门槛,让更多的Android工程师理解Android系统,掌握Android系统。喜欢的话麻烦点击一个喜欢再关注一下~
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
快速体验 Demo
扫描二维码下载 Demo:
如果二维码图片不可见,点我下载 Demo 体验
使用
–
首先需要添加 Gradle 依赖:
//注意:1.6.0 之后的 API 大幅重构,不兼容之前的 API,但是扩展性更好,请酌情升级。
//注意:1.6.0 之后的 API 大幅重构,不兼容之前的 API,但是扩展性更好,请酌情升级。
//注意:1.6.0 之后的 API 大幅重构,不兼容之前的 API,但是扩展性更好,请酌情升级。
implementation ‘com.lxj:xpopup:1.6.7’
//重构之前的版本
//implementation ‘com.lxj:xpopup:1.5.2’
必须添加的依赖库:
//版本号在 26 以及以上即可
implementation ‘com.android.support:appcompat-v7:28.0.0’
implementation ‘com.android.support:recyclerview-v7:28.0.0’
implementation ‘com.android.support:design:28.0.0’
为了方便使用,已经内置了几种常见弹窗的实现:
new XPopup.Builder(getContext()).asConfirm(“我是标题”, “我是内容”,
new OnConfirmListener() {
@Override
public void onConfirm() {
toast(“click confirm”);
}
})
.show();
new XPopup.Builder(getContext()).asInputConfirm(“我是标题”, “请输入内容。”,
new OnInputConfirmListener() {
@Override
public void onConfirm(String text) {
toast("input text: " + text);
}
})
.show();
new XPopup.Builder(getContext())
//.maxWidth(600)
.asCenterList(“请选择一项”, new String[]{“条目 1”, “条目 2”, “条目 3”, “条目 4”},
new OnSelectListener() {
@Override
public void onSelect(int position, String text) {
toast("click " + text);
}
})
.show();
new XPopup.Builder(getContext())
.asLoading(“正在加载中”)
.show();
// 这种弹窗从 1.0.0 版本开始实现了优雅的手势交互和智能嵌套滚动
new XPopup.Builder(getContext())
.asBottomList(“请选择一项”, new String[]{“条目 1”, “条目 2”, “条目 3”, “条目 4”, “条目 5”},
new OnSelectListener() {
@Override
public void onSelect(int position, String text) {
toast("click " + text);
}
})
.show();
- 显示依附于某个 View 或者某个点的弹窗
new XPopup.Builder(getContext())
.atView(v) // 依附于所点击的 View,内部会自动判断在上方或者下方显示
.asAttachList(new String[]{“分享”, “编辑”, “不带 icon”},
new int[]{R.mipmap.ic_launcher, R.mipmap.ic_launcher},
new OnSelectListener() {
@Override
public void onSelect(int position, String text) {
toast("click " + text);
}
})
.show();
如果是想依附于某个 View 的触摸点,则需要先watch
该 View,然后当单击或长按触发的时候去显示:
// 必须在事件发生前,调用这个方法来监视 View 的触摸
final XPopup.Builder builder = new XPopup.Builder(getContext())
.watchView(view.findViewById(R.id.btnShowAttachPoint));
view.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
builder.asAttachList(new String[]{“置顶”, “复制”, “删除”}, null,
new OnSelectListener() {
@Override
public void onSelect(int position, String text) {
toast("click " + text);
}
})
.show();
return false;
}
});
asAttachList
方法内部是对 AttachPopupView 的封装,如果你的布局不是列表,可以继承 AttachPopupView 实现自己想要的布局。 AttachPopupView 会出现在目标的上方或者下方,如果你想要出现在目标的左边或者右边(像微信朋友圈那样点赞的弹窗),可以继承 HorizontalAttachPopupView,然后编写你的布局即可。
最简单示例如下:
public class CustomAttachPopup extends HorizontalAttachPopupView {
public CustomAttachPopup(@NonNull Context context) {
super(context);
}
@Override
protected int getImplLayoutId() {
return R.layout.custom_attach_popup;
}
@Override
protected void onCreate() {
super.onCreate();
findViewById(R.id.tv_zan).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
ToastUtils.showShort(“赞”);
}
});
findViewById(R.id.tv_comment).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
ToastUtils.showShort(“评论”);
}
});
}
}
- 关闭弹窗
dismiss();
- 自定义弹窗
当你自定义弹窗的时候,需要选择继承CenterPopupView
,BottomPopupView
,AttachPopupView/HorizontalAttachPopupView
,DrawerPopupView
,PartShadowPopupView
其中之一。假设需要自定义 Center 类型的弹窗:
class CustomPopup extends CenterPopupView{
//自定义弹窗本质是一个自定义 View,但是只需重写这个构造,其他的不用重写
public CustomPopup(@NonNull Context context) {
super(context);
}
// 返回自定义弹窗的布局
@Override
protected int getImplLayoutId() {
return R.layout.custom_popup;
}
// 执行初始化操作,比如:findView,设置点击,或者任何你弹窗内的业务逻辑
@Override
protected void onCreate() {
super.onCreate();
findViewById(R.id.tv_close).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
dismiss(); // 关闭弹窗
}
});
}
// 设置最大宽度,看需要而定
@Override
protected int getMaxWidth() {
return super.getMaxWidth();
}
// 设置最大高度,看需要而定
@Override
protected int getMaxHeight() {
return super.getMaxHeight();
}
// 设置自定义动画器,看需要而定
@Override
protected PopupAnimator getPopupAnimator() {
return super.getPopupAnimator();
}
}
使用自定义弹窗:
new XPopup.Builder(getContext())
.asCustom(new CustomPopup(getContext()))
.show();
- 自定义动画
自定义动画已经被设计得非常简单,动画和弹窗是无关的;这意味着你可以将动画设置给内置弹窗或者自定义弹窗。继承PopupAnimator
,实现 3 个方法:
-
如何初始化动画
-
动画如何开始
-
动画如何结束
比如:自定义一个旋转的动画:
class RotateAnimator extends PopupAnimator{
@Override
public void initAnimator() {
targetView.setScaleX(0);
targetView.setScaleY(0);
targetView.setAlpha(0);
targetView.setRotation(360);
}
@Override
public void animateShow() {
targetView.animate().rotation(0).scaleX(1).scaleY(1).alpha(1).setInterpolator(new FastOutSlowInInterpolator()).setDuration(animateDuration).start();
}
@Override
public void animateDismiss() {
targetView.animate().rotation(360).scaleX(0).scaleY(0).alpha(0).setInterpolator(new FastOutSlowInInterpolator()).setDuration(animateDuration).start();
}
}
使用自定义动画:
new XPopup.Builder(getContext())
.customAnimator(new RotateAnimator())
.asConfirm(“演示自定义动画”, “当前的动画是一个自定义的旋转动画,无论是自定义弹窗还是自定义动画,已经被设计得非常简单;这个动画代码只有 6 行即可完成!”, null)
.show();
- 显示 DrawerLayout 类型弹窗
对于 DrawerLayout 类型的弹窗,我只能帮你做好弹窗效果和手势交互。里面的 UI 和逻辑是无法帮你完成的,所以需要自定义一个弹窗,继承DrawerPopupView
。代码非常简单,如下:
public class CustomDrawerPopupView extends DrawerPopupView {
public CustomDrawerPopupView(@NonNull Context context) {
super(context);
}
@Override
protected int getImplLayoutId() {
return R.layout.custom_drawer_popup;
}
@Override
protected void onCreate() {
super.onCreate();
findViewById(R.id.btn).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getContext(), “nothing!!!”, Toast.LENGTH_SHORT).show();
}
});
}
}
使用自定义的 DrawerLayout 弹窗:
new XPopup.Builder(getContext())
.popupPosition(PopupPosition.Right)//右边
.hasStatusBarShadow(true) //启用状态栏阴影
.asCustom(new CustomDrawerPopupView(getContext()))
.show();
- 自定义局部阴影弹窗
这种效果从分类上看仍然是 Attach 类型,因为要依附于某个 View,在其上方或者下方显示。常见于列表条件筛选弹窗,比如京东或者淘宝的商品列表筛选。同样我只能帮你把复杂的交互效果做了,弹窗里面的 UI 和逻辑需要你自己继承PartShadowPopupView
来做,这当然非常简单。 最简单的示例如下:
public class CustomPartShadowPopupView extends PartShadowPopupView {
public CustomPartShadowPopupView(@NonNull Context context) {
super(context);
}
@Override
protected int getImplLayoutId() {
return R.layout.custom_part_shadow_popup; // 编写你自己的布局
}
@Override
protected void onCreate() {
super.onCreate();
// 实现一些 UI 的初始和逻辑处理
}
}
显示的时候仍然需要指定 atView 显示,内部会智能判断应该如何展示以及使用最佳的动画器:
new XPopup.Builder(getContext())
.atView(ll_container)
.asCustom(new CustomPartShadowPopupView(getContext()))
.show();
- 自定义 Bottom 类型的弹窗
自定义 Bottom 类型的弹窗会比较常见,默认 Bottom 弹窗带有手势交互和嵌套滚动;如果您不想要手势交互可以调用enableDrag(false)
方法关闭。
如果弹窗内有输入框,在弹出输入法的情况下,弹窗默认会贴附在输入法之上,并且保证不会盖住输入框;目前 Center 和 Bottom 类型弹窗有此效果。
请注意:弹窗的宽高是自适应的,大部分情况下都应该将弹窗布局的高设置为wrap_content
;除非你希望得到一个高度撑满的弹窗。
Demo 中有一个模仿知乎评论的实现,代码在这里:
public class ZhihuCommentPopup extends BottomPopupView {
VerticalRecyclerView recyclerView;
public ZhihuCommentPopup(@NonNull Context context) {
super(context);
}
@Override
protected int getImplLayoutId() {
return R.layout.custom_bottom_popup;
}
@Override
protected void onCreate() {
super.onCreate();
recyclerView = findViewById(R.id.recyclerView);
ArrayList strings = new ArrayList<>();
for (int i = 0; i < 30; i++) {
strings.add(“”);
}
CommonAdapter commonAdapter = new CommonAdapter(R.layout.adapter_zhihu_comment, strings) {
@Override
最后
以前一直是自己在网上东平西凑的找,找到的东西也是零零散散,很多时候都是看着看着就没了,时间浪费了,问题却还没得到解决,很让人抓狂。
后面我就自己整理了一套资料,还别说,真香!
资料有条理,有系统,还很全面,我不方便直接放出来,大家可以先看看有没有用得到的地方吧。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
i = 0; i < 30; i++) {
strings.add(“”);
}
CommonAdapter commonAdapter = new CommonAdapter(R.layout.adapter_zhihu_comment, strings) {
@Override
最后
以前一直是自己在网上东平西凑的找,找到的东西也是零零散散,很多时候都是看着看着就没了,时间浪费了,问题却还没得到解决,很让人抓狂。
后面我就自己整理了一套资料,还别说,真香!
资料有条理,有系统,还很全面,我不方便直接放出来,大家可以先看看有没有用得到的地方吧。
[外链图片转存中…(img-DELl1QE2-1715881147219)]
[外链图片转存中…(img-xYIGithH-1715881147219)]
[外链图片转存中…(img-2lrEeMQi-1715881147219)]
[外链图片转存中…(img-5lZRzNGc-1715881147220)]
[外链图片转存中…(img-ZnLjxbZL-1715881147220)]
[外链图片转存中…(img-FrWSkB3h-1715881147220)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!