最后
感谢您的阅读,在文末给大家准备一个福利。本人从事Android开发已经有十余年,算是一名资深的移动开发架构师了吧。根据我的观察发现,对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。
所以在此将我十年载,从萌新小白一步步成长为Android移动开发架构师的学习笔记,从Android四大组件到手写实现一个架构设计,我都有一一的对应笔记为你讲解。
当然我也为你们整理好了百度、阿里、腾讯、字节跳动等等互联网超级大厂的历年面试真题集锦。这也是我这些年来养成的习惯,一定要学会把好的东西,归纳整理,然后系统的消化吸收,这样才能极大的提高学习效率和成长进阶。碎片、零散化的东西,我觉得最没有价值的。就好比你给我一张扑克牌,我只会觉得它是一张废纸,但如果你给我一副扑克牌,它便有了它的价值。这和我们收集资料就要收集那些系统化的,是一个道理。
最后,赠与大家一句诗,共勉!
不驰于空想,不骛于虚声。不忘初心,方得始终。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
layout.addView(tvAnimation);
mPopupWindow.setContentView(layout);
//量测我们的动画的宽高
int w = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
int h = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
tvAnimation.measure(w, h);
mPopupWindow.setWidth(tvAnimation.getMeasuredWidth());
Log.e(TAG, "distance==== " + distance);
mPopupWindow.setHeight(distance + tvAnimation.getMeasuredHeight());
mPopupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
mPopupWindow.setFocusable(false);
mPopupWindow.setTouchable(false);
mPopupWindow.setOutsideTouchable(false);
}
这里面要注意的是我们要计算PopupWidow的高度和宽度,我们将 RelativeLayout 作为ViewGroup,用 AppCompatTextView作为动画控件,如果是图片则直接设置背景图片。
3.设置我们点赞View上方的动画:
/**
- 动画组合
*/
private void setPopAnimation() {
mAnimationSet = new AnimationSet(true);
TranslateAnimation translateAnim = new TranslateAnimation(0, 0, from_y, -to_y);
AlphaAnimation alphaAnim = new AlphaAnimation(from_alpha, to_alpha);
mAnimationSet.addAnimation(translateAnim);
mAnimationSet.addAnimation(alphaAnim);
mAnimationSet.setDuration(duration);
mAnimationSet.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
if (mPopupWindow != null && mPopupWindow.isShowing()) {
new Handler().post(new Runnable() {
@Override
public void run() {
mPopupWindow.dismiss();
}
});
}
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
}
4.设置我们点赞图片的动画效果:
/**
- 缩放动画
*/
private void setScaleAnimation() {
ObjectAnimator scaleX = ObjectAnimator.ofFloat(this, “scaleX”, 1f, 0.8f, 1.2f, 1f);
ObjectAnimator scaleY = ObjectAnimator.ofFloat(this, “scaleY”, 1f, 0.8f, 1.2f, 1f);
scaleX.setDuration(duration);
scaleY.setDuration(duration);
scaleX.setInterpolator(new AccelerateDecelerateInterpolator());
scaleY.setInterpolator(new AccelerateDecelerateInterpolator());
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.play(scaleX).with(scaleY);
animatorSet.start();
}
5.我们onDraw()方法之前我们还需要量测一下我们控件的大小,假如我们不量测宽高,我们在XML中引用我们的控件我们自己设定一个宽高,比实际的图片的宽高要大,最终显示的图片还是原图片大小,不会按照XML中设定的值放大或者缩小。
/**
-
量测点击控件的大小
-
@param widthMeasureSpec
-
@param heightMeasureSpec
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width;
int height;
int w_mode = MeasureSpec.getMode(widthMeasureSpec);
int w_size = MeasureSpec.getSize(widthMeasureSpec);
int h_mode = MeasureSpec.getMode(heightMeasureSpec);
int h_size = MeasureSpec.getSize(heightMeasureSpec);
if (w_mode == MeasureSpec.AT_MOST || w_mode == MeasureSpec.UNSPECIFIED) {
width = agreeDrawable.getIntrinsicWidth();
} else {
width = w_size;
}
if (h_mode == MeasureSpec.AT_MOST || h_mode == MeasureSpec.UNSPECIFIED) {
height = agreeDrawable.getIntrinsicHeight();
} else {
height = h_size;
}
setMeasuredDimension(width, height);
//根据量测的宽高,设置我们画的Drawable的大小
@SuppressLint(“DrawAllocation”)
Rect rect = new Rect(0, 0, width, height);
agreeDrawable.setBounds(rect);
}
6.画我们的图片:
@Override
protected void onDraw(Canvas canvas) {
//将我们的Drawable画到画布
agreeDrawable.draw(canvas);
}
7.当我们点击图片的时候触发动画:
@Override
public void onClick(View v) {
if (mPopupWindow != null && !mPopupWindow.isShowing()) {
int offsetY = -getHeight() - mPopupWindow.getHeight();
mPopupWindow.showAsDropDown(this, getWidth() / 2 - mPopupWindow.getWidth() / 2, offsetY);
mPopupWindow.update();
if (mAnimationSet == null) {
setPopAnimation();
}
tvAnimation.startAnimation(mAnimationSet);
setScaleAnimation();
//外部点击事件
if (clickListener != null) {
clickListener.onAgreeClick(v);
}
}
}
这里自定义了一个View的点击事件方法,供外部调用。
MainActivity中添加自定义控件和属性
<?xml version="1.0" encoding="utf-8"?><android.support.constraint.ConstraintLayout
xmlns:android=“http://schemas.android.com/apk/res/android”
xmlns:agreeview=“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=“com.lt.agreeview.MainActivity”>
<com.lt.agreeview.AgreeView
android:id=“@+id/agreeView4”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:layout_marginBottom=“8dp”
android:layout_marginTop=“8dp”
agreeview:animation=“text”
agreeview:animation_img=“@drawable/ic_favorite_black_24dp”
agreeview:distance=“100”
agreeview:from_y=“60”
agreeview:layout_constraintBottom_toBottomOf=“parent”
agreeview:layout_constraintEnd_toStartOf=“@+id/agreeView3”
agreeview:layout_constraintHorizontal_bias=“0.5”
agreeview:layout_constraintStart_toStartOf=“parent”
最后
最后这里放上我这段时间复习的资料,这个资料也是偶然一位朋友分享给我的,里面包含了腾讯、字节跳动、阿里、百度2019-2021面试真题解析,并且把每个技术点整理成了视频和PDF(知识脉络 + 诸多细节)。
还有 高级架构技术进阶脑图、高级进阶架构资料 帮助大家学习提升进阶,也可以分享给身边好友一起学习。
一起互勉~
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
高级架构技术进阶脑图、高级进阶架构资料 帮助大家学习提升进阶,也可以分享给身边好友一起学习。
[外链图片转存中…(img-umo2g4EV-1715248454977)]
[外链图片转存中…(img-VvQXn1oy-1715248454977)]
一起互勉~
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!