InCallTouchUi继承FrameLayout,Phone是通过InCallScreen管理整个界面,通过电话不同状态来显示需要的界面。该类主要管理来电接听、挂断、静音控制、多通电话切换、录音、键盘显示等功能。
1、InCallTouchUi通过构造能加载布局同时初始化PhoneApp对象:
public InCallTouchUi(Context context, AttributeSet attrs) { super(context, attrs); if (DBG) log("InCallTouchUi constructor..."); if (DBG) log("- this = " + this); if (DBG) log("- context " + context + ", attrs " + attrs); // Inflate our contents, and add it (to ourself) as a child. LayoutInflater inflater = LayoutInflater.from(context); inflater.inflate( R.layout.incall_touch_ui, // resource this, // root true); mApp = PhoneApp.getInstance(); }
2、在onFinishInflate()获取子控件的引用,这里需要注意MultiWaveView,该控件是自定义控件,及我们见到的滑动接听和挂断,在framework层进行处理,我们看看它是如何显示和隐藏:
//ringingCall) 理所就是当Call状态为响铃状态时显示 private void showIncomingCallWidget(Call ringingCall) { //部分代码省略,其他为显示动画 mIncomingCallWidget.setVisibility(View.VISIBLE); } //隐藏方法 private void hideIncomingCallWidget() { //部分代码省略,其他为显示动画 mIncomingCallWidget.setVisibility(View.GONE); } //有啦显示和隐藏方法,看在哪通过状态控制 void updateState(CallManager cm) { //通过CallManager获取当前状态 Phone.State state = cm.getState(); //showIncomingCallControls)是boolean状态标识 if (showIncomingCallControls) { if (DBG) log("- updateState: showing incoming call widget..."); showIncomingCallWidget(ringingCall); mApp.notificationMgr.statusBarHelper.enableSystemBarNavigation(false); } else { hideIncomingCallWidget(); mApp.notificationMgr.statusBarHelper.enableSystemBarNavigation(true); } //判断电话状态 if ((ringingCall.getState() != Call.State.IDLE) && !fgCallState.isDialing()) { if (ringingCall.getState().isAlive()) { if (DBG) log("- updateState: RINGING! Showing incoming call controls..."); showIncomingCallControls = true; } long now = SystemClock.uptimeMillis(); if (now < mLastIncomingCallActionTime + 500) { log("updateState: Too soon after last action; not drawing!"); showIncomingCallControls = false; } } else { // Ok, show the regular in-call touch UI (with some exceptions): if (mInCallScreen.okToShowInCallTouchUi()) { showInCallControls = true; } else { if (DBG) log("- updateState: NOT OK to show touch UI; disabling..."); } } } //如果我们要修改接听和挂断样式,就可以在这里进行一些改动
3、InCallTouchUi基本不处理具体实现操作,它是如何传递点击事件,在onClick点击方法中,这是对mInCallControls事件处理:
//事件处理传递到InCallScreen
mInCallScreen.handleOnscreenButtonClick(id); //传递inCallScreen;对象到InCallTouchUi void setInCallScreenInstance(InCallScreen inCallScreen) { mInCallScreen = inCallScreen; }
4、看看如何使滑动接听和挂断:
//MultiWaveView实现啦OnTriggerListener public void onTrigger(View v, int whichHandle) { if (DBG) log("onDialTrigger(whichHandle = " + whichHandle + ")..."); // On any action by the user, hide the widget: hideIncomingCallWidget(); // ...and also prevent it from reappearing right away. // (This covers up a slow response from the radio for some // actions; see updateState().) mLastIncomingCallActionTime = SystemClock.uptimeMillis(); // The InCallScreen actually implements all of these actions. // Each possible action from the incoming call widget corresponds // to an R.id value; we pass those to the InCallScreen's "button // click" handler (even though the UI elements aren't actually // buttons; see InCallScreen.handleOnscreenButtonClick().) if (mInCallScreen == null) { Log.wtf(LOG_TAG, "onTrigger(" + whichHandle + ") from incoming-call widget, but null mInCallScreen!"); return; } switch (whichHandle) { case ANSWER_CALL_ID: //接听 if (DBG) log("ANSWER_CALL_ID: answer!"); mInCallScreen.handleOnscreenButtonClick(R.id.incomingCallAnswer); break; case SEND_SMS_ID: //短信 if (DBG) log("SEND_SMS_ID!"); mInCallScreen.handleOnscreenButtonClick(R.id.incomingCallRespondViaSms); break; case DECLINE_CALL_ID: //挂断 if (DBG) log("DECLINE_CALL_ID: reject!"); mInCallScreen.handleOnscreenButtonClick(R.id.incomingCallReject); break; default: Log.wtf(LOG_TAG, "onDialTrigger: unexpected whichHandle value: " + whichHandle); break; } // Regardless of what action the user did, be sure to clear out // the hint text we were displaying while the user was dragging. mInCallScreen.updateIncomingCallWidgetHint(0, 0); }
如果大家需要对来电接听、挂断,及通话界面修改及功能添加可围绕这几部分操作,其具体布局在incalltouchui.xml.中间联系人图片及通话时间号码显示则位于CallCard.