商务服务
incallui android,Android M InCallUI动画简析手机动画「incallui android,Android M InCallUI动画简析」
2025-02-17 12:15

本篇回答下面几个问题

1. 显示动画的流程是怎样的

2. 为什么有些手机的动画不一样甚至没有动画

写这一篇主要用两个原因:

1. 发现Android M上新增了一个类CircularRevealFragment.java,那么新的东西就想看看它是干什么的

2. 我手机上没有打电话的动画

代码中两处动画,一处是InCallActivity显示动画,就是那个由一个点展开的动画,另一个是CallCard的动画,就是由下方升到上方的动画。

InCallActivity启动动画

在InCallActivity.java的internalResolveIntent()方法内(这个方法接收处理intent,必走),跳至 CircularRevealFragment.java

touchPoint即动画展开的那个点。可以看到这个touchPoint有两个取值的地方,这个有点类似于双保险,TouchPointManager中getPoint()取出来的值是点击的时候就保存到TouchPointManager中的,而(Point) extras.getParcelable(TouchPointManager.TOUCH_POINT);是在构造拨号的intent的时候存进去的

Point touchPoint = null;

if (TouchPointManager.getInstance().hasValidPoint()) {

// Use the most immediate touch point in the InCallUi if available

touchPoint = TouchPointManager.getInstance().getPoint();

} else {

// Otherwise retrieve the touch point from the call intent

if (call != null) {

touchPoint = (Point) extras.getParcelable(TouchPointManager.TOUCH_POINT);

}

}

// Start animation for new outgoing call

CircularRevealFragment.startCircularReveal(getFragmentManager(), touchPoint,

InCallPresenter.getInstance());

touchPoint每次点击的时候都应当set一次,举个DialtacsActivity.java里的例子,当然还有其他地方设置(能点的地方就应该设置一次)

@Override

public boolean dispatchTouchEvent(MotionEvent ev) {

if (ev.getAction() == MotionEvent.ACTION_DOWN) {

TouchPointManager.getInstance().setPoint((int) ev.getRawX(), (int) ev.getRawY());

}

return super.dispatchTouchEvent(ev);

}

CircularRevealFragment.java新增类

public static void startCircularReveal(FragmentManager fm, Point touchPoint,

onCircularRevealCompleteListener listener) {

if (fm.findFragmentByTag(TAG) == null) {

fm.beginTransaction().add(R.id.main,

new CircularRevealFragment(touchPoint, listener), TAG)

.commitAllowingStateLoss();

} else {

Log.w(TAG, "An instance of CircularRevealFragment already exists");

}

}

然后在 CircularRevealFragment.java的onResume()方法内

@Override

public void onResume() {

super.onResume();

if (!mAnimationStarted) {

// only run the animation once for each instance of the fragment

startOutgoingAnimation(InCallPresenter.getInstance().getThemeColors());//带了一个 ThemeColors展开动画

}

mAnimationStarted = true;

}

这里观察到一个现象,插卡和不插卡通话背景是不同的,双卡手机上两张卡拨打出去的动画背景可能也是不同的,就是因为上面的getThemeColors()返回的值也就是颜色不同。返回值的来源不具体跟了,设置这个颜色的地方在Settings>Sim Card 设置页点开sim卡有个颜色选择,背景色就是这里的颜色。

下面的方法新建动画并启动动画

public void startOutgoingAnimation(MaterialPalette palette) {

//略过本次不关心的

view.getViewTreeObserver().addonPreDrawListener(new onPreDrawListener() {

@Override

public boolean onPreDraw() {

final ViewTreeObserver vto = view.getViewTreeObserver();

if (vto.isAlive()) {

vto.removeonPreDrawListener(this);

}

final Animator animator = getRevealAnimator(mTouchPoint);//获得动画

animator.addListener(new AnimatorListenerAdapter() {

@Override

public void onAnimationEnd(Animator animation) {

view.setClipToOutline(false);

if (mListener != null) {

android.util.Log.i(TAG, "onAnimationEnd: animation a");

mListener.onCircularRevealComplete(getFragmentManager());//动画结束后调

}

}

});

android.util.Log.i(TAG, "onPreDraw: animation 3");

animator.start();//动画开始了

return false;

}

});

}

好的诸位下面就是动画生成的地方,注意动画类型,这里携带了touchPoint

private Animator getRevealAnimator(Point touchPoint) {

final Activity activity = getActivity();

final View view = activity.getWindow().getDecorView();

final Display display = activity.getWindowManager().getDefaultDisplay();

final Point size = new Point();

display.getSize(size);

int startX = size.x / 2;

int startY = size.y / 2;

if (touchPoint != null) {

startX = touchPoint.x;

startY = touchPoint.y;

}

final Animator valueAnimator = ViewAnimationUtils.createCircularReveal(view,

startX, startY, 0, Math.max(size.x, size.y));

valueAnimator.setDuration(getResources().getInteger(R.integer.reveal_animation_duration));//设置动画时长

return valueAnimator;

}

好的InCallActivity的动画显示完以后,下面接着CallCardFragment的动画。

CallCard动画

在动画执行完InCallActivity的启动动画以后,通过mListener.onCircularRevealComplete(getFragmentManager());调用CallCardFragement.java中的 animateForNewOutgoingCall()

InCallPresenter.java

public void onCircularRevealComplete(FragmentManager fm) {

if (mInCallActivity != null) {

mInCallActivity.showCallCardFragment(true);//显示CallCard

mInCallActivity.getCallCardFragment().animateForNewOutgoingCall();//CallCardFragment中显示动画

CircularRevealFragment.endCircularReveal(mInCallActivity.getFragmentManager());

}

}

CallCardFragment.java

关注一下动画类型

@Override

public void animateForNewOutgoingCall() {

//略过本次不关心的

observer.addonGlobalLayoutListener(new onGlobalLayoutListener() {

@Override

public void onGlobalLayout() {

//略过本次不关心的

final Animator animator = getShrinkAnimator(parent.getHeight(), originalHeight);//注意动画类型

animator.addListener(new AnimatorListenerAdapter() {

@Override

public void onAnimationEnd(Animator animation) {

mPrimaryCallCardContainer.setTag(R.id.view_tag_callcard_actual_height,

null);

setViewStatePostAnimation(listener);

mIsAnimating = false;

InCallPresenter.getInstance().onShrinkAnimationComplete();//动画结束后

}

});

animator.start();//开始动画

}

});

}

getShrinkAnimator()动画生成

private Animator getShrinkAnimator(int startHeight, int endHeight) {

final ObjectAnimator shrinkAnimator =

ObjectAnimator.ofInt(mPrimaryCallCardContainer, "bottom", startHeight, endHeight);

shrinkAnimator.setDuration(mShrinkAnimationDuration);//设置动画时长

shrinkAnimator.addListener(new AnimatorListenerAdapter() {

@Override

public void onAnimationStart(Animator animation) {

mFloatingActionButton.setEnabled(true);

}

});

shrinkAnimator.setInterpolator(AnimUtils.EASE_IN);

return shrinkAnimator;

}

动画时长来源

mShrinkAnimationDuration = getResources().getInteger(R.integer.shrink_animation_duration);

好了现在我们回头看看文章开头的两个问题是否得到了解答。

前面的流程基本上就是动画生成,设置属性,显示动画的流程

非要话个图的话大概就是下面这样

0818b9ca8b590ca3270a3433284dd417.png

如果我们把Android M上的动画代码跟Android L上的代码做对比的话会发现,Android L也有这两个类型的动画,都在CallCardFragment.java里,通过mAnimatorSet.playSequentially(revealAnimator, shrinkAnimator);顺序播放两个动画。

第二个问题的答案貌似还不明显,为什么有些手机的动画不一样

我们观察到的不同有两点:1.背景颜色不同,2.有些似乎没有动画。

第1点不重点解答,上文也提到过颜色取值自SIM卡设置里面选择的颜色,而且颜色不同起码有动画嘛

第2点有又两种情况:1)没用动画;2)动画时间极短,以至于看起来像没有动画。

注意到两次设置动画时间的代码分别是

//InCallActivity或者说叫CircularRevealFragment

valueAnimator.setDuration(getResources().getInteger(R.integer.reveal_animation_duration));

//CallCardFragment

mShrinkAnimationDuration = getResources().getInteger(R.integer.shrink_animation_duration);

那么这两个值的来源呢?

0818b9ca8b590ca3270a3433284dd417.png

从上图中可以看到,这个动画时长默认是333ms的,但是在有些配置文件里面是1,而且都改成了1!从他们所在的文件夹可以看到,这个配置是针对中国移动sim卡的修改(mcc mnc 匹配到中国移动),难道是针对中国移动定制机的修改?苦了我刷CM系统的人们(AOSP没这个配置)。

是哪个家伙做了这样的修改(黑线脸)

0818b9ca8b590ca3270a3433284dd417.png

提交者就不贴出来了,他针对中国移动新增了这4个文件配置动画时长。。

    以上就是本篇文章【incallui android,Android M InCallUI动画简析手机动画「incallui android,Android M InCallUI动画简析」】的全部内容了,欢迎阅览 ! 文章地址:http://www78564.xrbh.cn/news/34519.html 
     文章      相关文章      动态      同类文章      热门文章      栏目首页      网站地图      返回首页 迅博思语移动站 http://www78564.xrbh.cn/mobile/ , 查看更多   
最新文章
LG 推出三款 OLED GX9s 智能显示器:21:9 曲面屏,内置 webOS
IT之家 4 月 21 日消息,LG 电子本月 3 日向美国市场发布了三款 LG UltraGear OLED GX9s 系列智能显示器。这三款显示器均采用
北斗导航苹果版北斗导航手机版下载「北斗导航苹果版」
北斗导航苹果版是一款专业的手机导航软件,使用的是中国自有的地基授时系统进行定位导航,可在全球范围内全天候、全天时为各类用
盒马、京东、拼多多,官宣放大招!
4月11日,盒马宣布,面向中国外贸企业开放入驻通道,绿色通道24小时专人加急处理,简化认证流程,缩短审核认证周期。除了24小时
买手机要看哪些配置?怎么挑选手机主要看什么?手机配置「买手机要看哪些配置?怎么挑选手机主要看什么?」
网购消费查券省钱上【百佣】App,只需3步操作,同一个商品用券更便宜。在购买手机时,了解手机配置是非常重要的。本文将介绍买手
给力!长沙县、长沙经开区政企合力放大招,就地过年成优选长沙手机「给力!长沙县、长沙经开区政企合力放大招,就地过年成优选」
记者获悉,为深入贯彻落实党中央、国务院、省、市关于2021年春节期间疫情防控“就地过年”倡导,1月22日,长沙县人民政府、 长沙
戈雅夏日皮肤突袭,铠无双限定皮肤巨帅,瑶双喜临门
最近王者荣耀给公孙离出了一款新皮肤,公孙离的这款新皮肤,也是一款FMVP皮肤。这款皮肤的质量还是非常不错的,而且价格也不贵,
阅见伊犁|广州读书月公布广州、伊犁等六地共读书单
四月的风拂过珠江,木棉的火焰点燃了岭南的春意;同一阵风掠过天山,伊犁河谷的杏花正以漫山遍野的雪白回应。4月1日,在“书香羊
红米Turbo4发布,性价比是否能超越真我Neo7?红米手机4「红米Turbo4发布,性价比是否能超越真我Neo7?」
近日,红米正式发布了其最新中端手机——红米Turbo4,起售价1999元。这款手机在多方面进行了升级,尤其在防尘防水、定位技术和电
应对手机没电的实用技巧与应变策略分享手机没电了怎么办「应对手机没电的实用技巧与应变策略分享」
  在这个信息化的时代,手机几乎成了我们生活中不可或缺的一部分。无论是工作、学习,还是社交、娱乐,手机都扮演着重要的角色