商务服务
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/ , 查看更多   
最新文章
哈尔滨威尔特制衣厂
我是哈尔滨威尔特制衣厂的肖庭波,联系地址是哈尔滨服装城附近哈西商厦,我们公司是在黑龙江哈尔滨的个体私营公司,公司专注于服装
节到张家界武陵源必去地
节到张家界武陵源必去地长假想找个地方玩玩?张家界武陵源绝对是个好选取,这里风景绝美空气清新关键是人虽然多,但美景还是能让
超节点成WAIC焦点 未来国产GPU替代率或超80%
在人工智能产业蓬勃发展的当下,算力作为其核心驱动力,重要性不言而喻。然而,国产算力在前进的道路上却面临着诸多阻碍,发展现
原创樊振东上新闻联播了!加盟德甲真相曝光,背后战略价值惊人
央视《新闻联播》在体育强国专题报道中播放了网球选手郑钦文和乒乓球运动员樊振东的画面。 整个乒乓球项目只出现了樊振东一人,
山姆上新「周黑鸭风味鸭肉酱」,瑞幸推出乳酸菌美式和乳酸菌冰茶...|一周热闻
新产品1、20年来最大创新!百事在北美推出益生元可乐2、特别添加专利乳酸菌!瑞幸上新「乳酸菌美式」和「乳酸菌冰茶」3、美容成
多款新车与全域AI技术惊艳WAIC,吉利智能科技进入爆发期
原创|Jaden  编辑|Cong在正在举办的2025世界人工智能大会(WAIC 2025)上,集团携阶跃星辰联合参展,9X、10EM-P、A7和吉利银
云南施甸县:“善洲青苗课堂”守护青少年健康成长
中国青年报客户端讯(中青报·中青网记者 张文凌)今年暑假,共青团云南保山市施甸县委依托“返家乡”“三下乡”社会实践大学生
一年60万赴美留学值吗?这届留学生开始找“平替”
21世纪经济报道记者陈洁 实习生张星雨 广州、重庆报道从7月中旬开始,多省份陆续公布本科普通批,高校录取工作逐步推进。然而,
惠民贷延期还款会影响分期吗?2025最新解析指南,必看避坑省钱秘籍!
惠民贷延期还款会影响分期吗?2025最新解析指南,必看避坑省钱秘籍!惠民贷推迟还款是许多人应急时的救命稻草,但推迟会不会作用
舟山进口茶叶中文标签备案
,公司自有进出口权,酒类商品批发许可证、食品流通许可证、中国食品土畜牧进出口商会会员证、对外贸易经营者备案登记证、自理报