赞
踩
PhoneStatusBar -->makeStatusBarView();
- try {
- boolean showNav = mWindowManagerService.hasNavigationBar();//向wms询问是否需要导航栏
- //if (DEBUG)
- Log.v(TAG, "hasNavigationBar=" + showNav);
- if (showNav) {
- createNavigationBarView(context);//创建导航栏
- }
- } catch (RemoteException ex) {
- // no window manager? good luck with that
mWindowManagerService.hasNavigationBar向framework 下面的config.xml中获取 com.android.internal.R.bool.config_showNavigationBar。
createNavigationBarView(context):
- protected void createNavigationBarView(Context context) {
- inflateNavigationBarView(context);//加载导航栏布局文件
- mNavigationBarView.setDisabledFlags(mDisabled1);//禁用某些功能switches[0]
- mNavigationBarView.setComponents(mRecents, getComponent(Divider.class));//添加控制按键。
- mNavigationBarView.setOnVerticalChangedListener(
- new NavigationBarView.OnVerticalChangedListener() {
- @Override
- public void onVerticalChanged(boolean isVertical) {
- if (mAssistManager != null) {
- mAssistManager.onConfigurationChanged();
- }
- mNotificationPanel.setQsScrimEnabled(!isVertical);
- }
- });
- mNavigationBarView.setOnTouchListener(new View.OnTouchListener() {
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- checkUserAutohide(v, event);
- return false;
- }});
- }
至此导航栏的UI界面是创建完成但是功能还未全部加载完成,比如按近期列表无效,所以还需要在PhoneStatusBar ->start()中加载addNavigationBar()。
- protected void addNavigationBar() {
- if (DEBUG) Log.v(TAG, "addNavigationBar: about to add " + mNavigationBarView);
- if (mNavigationBarView == null) return;
-
- prepareNavigationBarView();
-
- mWindowManager.addView(mNavigationBarView, getNavigationBarLayoutParams());//把这个添加到window窗口
- }
- private void prepareNavigationBarView() {
- mNavigationBarView.reorient();//方向的初始化
-
-
- ButtonDispatcher recentsButton = mNavigationBarView.getRecentsButton();
- //近期列表的监听
- recentsButton.setOnClickListener(mRecentsClickListener);
- recentsButton.setOnTouchListener(mRecentsPreloadOnTouchListener);
- recentsButton.setLongClickable(true);
- recentsButton.setOnLongClickListener(mRecentsLongClickListener);
-
- ButtonDispatcher backButton = mNavigationBarView.getBackButton();
- backButton.setLongClickable(true);
- backButton.setOnLongClickListener(mLongPressBackListener);
-
- ButtonDispatcher homeButton = mNavigationBarView.getHomeButton();
- homeButton.setOnTouchListener(mHomeActionListener);
- homeButton.setOnLongClickListener(mLongPressHomeListener);
-
-
- /// M: BMW restore button @{
- if (MultiWindowManager.isSupported()) {
- ButtonDispatcher restoreButton = mNavigationBarView.getRestoreButton();
- restoreButton.setOnClickListener(mRestoreClickListener);
-
-
- }
- /// @}
-
-
- mAssistManager.onConfigurationChanged();
- }
在上述的代码 recentsButton 、backButton、homeButton分别对应的是导航栏中的近期列表、返回键、Home键。如果继续追溯它们所添加的监听,并未发现back 和home的功能实现,只有近期列表的功能实现。那back 和home的功能实现是在哪里呢?后面会讲到。
导航栏的创建
- protected void inflateNavigationBarView(Context context) {
- mNavigationBarView = (NavigationBarView) View.inflate(
- context, R.layout.navigation_bar, null);
- }
navigation_bar.xml:
- <com.android.systemui.statusbar.phone.NavigationBarView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:systemui="http://schemas.android.com/apk/res-auto"
- android:layout_height="match_parent"
- android:layout_width="match_parent"
- android:background="@drawable/system_bar_background">
-
- <com.android.systemui.statusbar.phone.NavigationBarInflaterView
- android:id="@+id/navigation_inflater"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
-
- </com.android.systemui.statusbar.phone.NavigationBarView>
注: @drawable/system_bar_background 导航栏的背景控制
NavigationBarInflaterView
- public class NavigationBarInflaterView extends FrameLayout implements TunerService.Tunable {
-
- private static final String TAG = "NavBarInflater";
-
- public static final String NAV_BAR_VIEWS = "sysui_nav_bar";
-
- public static final String MENU_IME = "menu_ime";
- public static final String BACK = "back";
- public static final String HOME = "home";
- public static final String RECENT = "recent";
- public static final String NAVSPACE = "space";
- public static final String CLIPBOARD = "clipboard";
- public static final String KEY = "key";
- /// M: BMW @{
- public static final String RESTORE = "restore";
- /// @}
-
- public static final String GRAVITY_SEPARATOR = ";";
- public static final String BUTTON_SEPARATOR = ",";
-
- public static final String SIZE_MOD_START = "[";
- public static final String SIZE_MOD_END = "]";
-
- public static final String KEY_CODE_START = "(";
- public static final String KEY_IMAGE_DELIM = ":";
- public static final String KEY_CODE_END = ")";
-
- protected LayoutInflater mLayoutInflater;
- protected LayoutInflater mLandscapeInflater;
- private int mDensity;
-
- protected FrameLayout mRot0;
- protected FrameLayout mRot90;
-
- private SparseArray<ButtonDispatcher> mButtonDispatchers;
- private String mCurrentLayout;
-
- private View mLastRot0;
- private View mLastRot90;
-
- public NavigationBarInflaterView(Context context, AttributeSet attrs) {
- super(context, attrs);
- mDensity = context.getResources().getConfiguration().densityDpi;//dpi值
- createInflaters();
- }
-
- private void createInflaters() {
- mLayoutInflater = LayoutInflater.from(mContext);
- Configuration landscape = new Configuration();
- landscape.setTo(mContext.getResources().getConfiguration());
- landscape.orientation = Configuration.ORIENTATION_LANDSCAPE;//初始化方法是横向
- mLandscapeInflater = LayoutInflater.from(mContext.createConfigurationContext(landscape));
- }
-
- @Override
- protected void onConfigurationChanged(Configuration newConfig) {
- super.onConfigurationChanged(newConfig);
- if (mDensity != newConfig.densityDpi) {
- mDensity = newConfig.densityDpi;
- createInflaters();
- inflateChildren();
- clearViews();
- inflateLayout(mCurrentLayout);
- }
- }
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
- inflateChildren();
- clearViews();
- inflateLayout(getDefaultLayout());
- }
-
- private void inflateChildren() {
- removeAllViews();//移除此group上面的所有view
-
- //加载O度和90度布局
- mRot0 = (FrameLayout) mLayoutInflater.inflate(R.layout.navigation_layout, this, false);
- mRot0.setId(R.id.rot0);
- addView(mRot0);
- mRot90 = (FrameLayout) mLayoutInflater.inflate(R.layout.navigation_layout_rot90, this,
- false);
- mRot90.setId(R.id.rot90);
- addView(mRot90);
- if (getParent() instanceof NavigationBarView) {
- ((NavigationBarView) getParent()).updateRotatedViews();
- }
- }
-
- protected String getDefaultLayout() {
- /// M: BMW @{
- if (MultiWindowManager.isSupported()) {
- return mContext.getString(R.string.config_navBarLayout_float);
- }
- /// @}
- return mContext.getString(R.string.config_navBarLayout);
- }
-
- @Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
- TunerService.get(getContext()).addTunable(this, NAV_BAR_VIEWS);
- }
-
- @Override
- protected void onDetachedFromWindow() {
- TunerService.get(getContext()).removeTunable(this);
- super.onDetachedFromWindow();
- }
-
- @Override
- public void onTuningChanged(String key, String newValue) {
- if (NAV_BAR_VIEWS.equals(key)) {
- if (!Objects.equals(mCurrentLayout, newValue)) {
- clearViews();
- inflateLayout(newValue);
- }
- }
- }
-
- public void setButtonDispatchers(SparseArray<ButtonDispatcher> buttonDisatchers) {
- mButtonDispatchers = buttonDisatchers;
- for (int i = 0; i < buttonDisatchers.size(); i++) {
- initiallyFill(buttonDisatchers.valueAt(i));
- }
- }
-
- private void initiallyFill(ButtonDispatcher buttonDispatcher) {
- addAll(buttonDispatcher, (ViewGroup) mRot0.findViewById(R.id.ends_group));
- addAll(buttonDispatcher, (ViewGroup) mRot0.findViewById(R.id.center_group));
- addAll(buttonDispatcher, (ViewGroup) mRot90.findViewById(R.id.ends_group));
- addAll(buttonDispatcher, (ViewGroup) mRot90.findViewById(R.id.center_group));
- }
-
- private void addAll(ButtonDispatcher buttonDispatcher, ViewGroup parent) {
- for (int i = 0; i < parent.getChildCount(); i++) {
- // Need to manually search for each id, just in case each group has more than one
- // of a single id. It probably mostly a waste of time, but shouldn't take long
- // and will only happen once.
- if (parent.getChildAt(i).getId() == buttonDispatcher.getId()) {
- buttonDispatcher.addView(parent.getChildAt(i));
- } else if (parent.getChildAt(i) instanceof ViewGroup) {
- addAll(buttonDispatcher, (ViewGroup) parent.getChildAt(i));
- }
- }
- }
-
- protected void inflateLayout(String newLayout) {
- mCurrentLayout = newLayout;
- if (newLayout == null) {
- newLayout = getDefaultLayout();
- }
- String[] sets = newLayout.split(GRAVITY_SEPARATOR, 3);
- String[] start = sets[0].split(BUTTON_SEPARATOR);
- String[] center = sets[1].split(BUTTON_SEPARATOR);
- String[] end = sets[2].split(BUTTON_SEPARATOR);
- // Inflate these in start to end order or accessibility traversal will be messed up.
- inflateButtons(start, (ViewGroup) mRot0.findViewById(R.id.ends_group), false);
- inflateButtons(start, (ViewGroup) mRot90.findViewById(R.id.ends_group), true);
-
- inflateButtons(center, (ViewGroup) mRot0.findViewById(R.id.center_group), false);
- inflateButtons(center, (ViewGroup) mRot90.findViewById(R.id.center_group), true);
-
- addGravitySpacer((LinearLayout) mRot0.findViewById(R.id.ends_group));
- addGravitySpacer((LinearLayout) mRot90.findViewById(R.id.ends_group));
-
- inflateButtons(end, (ViewGroup) mRot0.findViewById(R.id.ends_group), false);
- inflateButtons(end, (ViewGroup) mRot90.findViewById(R.id.ends_group), true);
- }
-
- private void addGravitySpacer(LinearLayout layout) {
- layout.addView(new Space(mContext), new LinearLayout.LayoutParams(0, 0, 1));
- }
-
- private void inflateButtons(String[] buttons, ViewGroup parent, boolean landscape) {
- for (int i = 0; i < buttons.length; i++) {
- inflateButton(buttons[i], parent, landscape, i);
- }
- }
-
- private ViewGroup.LayoutParams copy(ViewGroup.LayoutParams layoutParams) {
- if (layoutParams instanceof LinearLayout.LayoutParams) {
- return new LinearLayout.LayoutParams(layoutParams.width, layoutParams.height,
- ((LinearLayout.LayoutParams) layoutParams).weight);
- }
- return new LayoutParams(layoutParams.width, layoutParams.height);
- }
-
- @Nullable
- protected View inflateButton(String buttonSpec, ViewGroup parent, boolean landscape,
- int indexInParent) {
- LayoutInflater inflater = landscape ? mLandscapeInflater : mLayoutInflater;
- float size = extractSize(buttonSpec);
- String button = extractButton(buttonSpec);
- View v = null;
- if (HOME.equals(button)) {
- v = inflater.inflate(R.layout.home, parent, false);
- if (landscape && isSw600Dp()) {
- setupLandButton(v);
- }
- } else if (BACK.equals(button)) {
- v = inflater.inflate(R.layout.back, parent, false);
- if (landscape && isSw600Dp()) {
- setupLandButton(v);
- }
- } else if (RECENT.equals(button)) {
- v = inflater.inflate(R.layout.recent_apps, parent, false);
- if (landscape && isSw600Dp()) {
- setupLandButton(v);
- }
- } else if (MENU_IME.equals(button)) {
- v = inflater.inflate(R.layout.menu_ime, parent, false);
- } else if (NAVSPACE.equals(button)) {
- v = inflater.inflate(R.layout.nav_key_space, parent, false);
- /// M: BMW @{
- if (MultiWindowManager.isSupported() && landscape && isSw600Dp()) {
- setupLandButton(v);
- }
- /// @}
- } else if (CLIPBOARD.equals(button)) {
- v = inflater.inflate(R.layout.clipboard, parent, false);
- /// M: BMW @{
- } else if (MultiWindowManager.isSupported() && RESTORE.equals(button)) {
- v = inflater.inflate(R.layout.restore, parent, false);
- if (landscape && isSw600Dp()) {
- setupLandButton(v);
- }
- /// @}
- } else if (button.startsWith(KEY)) {
- String uri = extractImage(button);
- int code = extractKeycode(button);
- v = inflater.inflate(R.layout.custom_key, parent, false);
- ((KeyButtonView) v).setCode(code);
- if (uri != null) {
- ((KeyButtonView) v).loadAsync(uri);
- }
- } else {
- return null;
- }
-
- if (size != 0) {
- ViewGroup.LayoutParams params = v.getLayoutParams();
- params.width = (int) (params.width * size);
- }
- parent.addView(v);
- addToDispatchers(v);
- View lastView = landscape ? mLastRot90 : mLastRot0;
- if (lastView != null) {
- v.setAccessibilityTraversalAfter(lastView.getId());
- }
- if (landscape) {
- mLastRot90 = v;
- } else {
- mLastRot0 = v;
- }
- return v;
- }
-
- public static String extractImage(String buttonSpec) {
- if (!buttonSpec.contains(KEY_IMAGE_DELIM)) {
- return null;
- }
- final int start = buttonSpec.indexOf(KEY_IMAGE_DELIM);
- String subStr = buttonSpec.substring(start + 1, buttonSpec.indexOf(KEY_CODE_END));
- return subStr;
- }
-
- public static int extractKeycode(String buttonSpec) {
- if (!buttonSpec.contains(KEY_CODE_START)) {
- return 1;
- }
- final int start = buttonSpec.indexOf(KEY_CODE_START);
- String subStr = buttonSpec.substring(start + 1, buttonSpec.indexOf(KEY_IMAGE_DELIM));
- return Integer.parseInt(subStr);
- }
-
- public static float extractSize(String buttonSpec) {
- if (!buttonSpec.contains(SIZE_MOD_START)) {
- return 1;
- }
- final int sizeStart = buttonSpec.indexOf(SIZE_MOD_START);
- String sizeStr = buttonSpec.substring(sizeStart + 1, buttonSpec.indexOf(SIZE_MOD_END));
- return Float.parseFloat(sizeStr);
- }
-
- public static String extractButton(String buttonSpec) {
- if (!buttonSpec.contains(SIZE_MOD_START)) {
- return buttonSpec;
- }
- return buttonSpec.substring(0, buttonSpec.indexOf(SIZE_MOD_START));
- }
-
- private void addToDispatchers(View v) {
- if (mButtonDispatchers != null) {
- final int indexOfKey = mButtonDispatchers.indexOfKey(v.getId());
- if (indexOfKey >= 0) {
- mButtonDispatchers.valueAt(indexOfKey).addView(v);
- } else if (v instanceof ViewGroup) {
- final ViewGroup viewGroup = (ViewGroup)v;
- final int N = viewGroup.getChildCount();
- for (int i = 0; i < N; i++) {
- addToDispatchers(viewGroup.getChildAt(i));
- }
- }
- }
- }
-
- private boolean isSw600Dp() {
- Configuration configuration = mContext.getResources().getConfiguration();
- return (configuration.smallestScreenWidthDp >= 600);
- }
-
- /**
- * This manually sets the width of sw600dp landscape buttons because despite
- * overriding the configuration from the overridden resources aren't loaded currently.
- */
- private void setupLandButton(View v) {
- Resources res = mContext.getResources();
- v.getLayoutParams().width = res.getDimensionPixelOffset(
- R.dimen.navigation_key_width_sw600dp_land);
- int padding = res.getDimensionPixelOffset(R.dimen.navigation_key_padding_sw600dp_land);
- v.setPadding(padding, v.getPaddingTop(), padding, v.getPaddingBottom());
- }
-
- private void clearViews() {
- if (mButtonDispatchers != null) {
- for (int i = 0; i < mButtonDispatchers.size(); i++) {
- mButtonDispatchers.valueAt(i).clear();
- }
- }
- clearAllChildren((ViewGroup) mRot0.findViewById(R.id.nav_buttons));
- clearAllChildren((ViewGroup) mRot90.findViewById(R.id.nav_buttons));
- }
-
- private void clearAllChildren(ViewGroup group) {
- for (int i = 0; i < group.getChildCount(); i++) {
- ((ViewGroup) group.getChildAt(i)).removeAllViews();
- }
- }
- }
分析:
1. 这段代码比较简单,文中也有做一些注释,主要功能就是把90度和0度的布局同时添加到ViewGroup中,那这个两个布局既然同时添加到ViewGroup,为什么我看到的只有一种布局文件呢?这是通过setVisibility(View.VISIBLE)来实现,这个功能的实现在NavigationBarView中的updateCurrentView()。
2.导航栏的三个按键的布局文件分别为:back.xml 、home.xml 、recent_apps.xml. 这个三个布局文件都是KeyButtonView ,而KeyButtonView继承ImageView,所以想修改返回键、Home、近期列表这三个键的UI,只需要更换对应的图片。
back.xml
- <com.android.systemui.statusbar.policy.KeyButtonView
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:systemui="http://schemas.android.com/apk/res-auto"
- android:id="@+id/back"
- android:layout_width="@dimen/navigation_key_width"
- android:layout_height="match_parent"
- android:layout_weight="0"
- android:src="@drawable/ic_sysbar_back"
- systemui:keyCode="4"
- android:scaleType="center"
- android:contentDescription="@string/accessibility_back"
- android:paddingStart="@dimen/navigation_key_padding"
- android:paddingEnd="@dimen/navigation_key_padding"
- />
由于三个布局文件很相近就不一 一列举,@drawable/ic_sysbar_back就是系统所使用的返回键图片,而keyCode=4与系统定义的KEY_BACK相同,因此系统才知道你按back键是让它返回上个界面而不是回到主界面。
KeyButtonView
- public class KeyButtonView extends ImageView {
-
- private int mContentDescriptionRes;
- private long mDownTime;
- private int mCode;
- private int mTouchSlop;
- private boolean mSupportsLongpress = true;
- private AudioManager mAudioManager;
- private boolean mGestureAborted;
- private boolean mLongClicked;
-
- private final Runnable mCheckLongPress = new Runnable() {
- public void run() {
- if (isPressed()) {
- // Log.d("KeyButtonView", "longpressed: " + this);
- if (isLongClickable()) {
- // Just an old-fashioned ImageView
- performLongClick();
- mLongClicked = true;
- } else if (mSupportsLongpress) {
- sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.FLAG_LONG_PRESS);
- sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
- mLongClicked = true;
- }
- }
- }
- };
-
- public KeyButtonView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public KeyButtonView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs);
-
- TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.KeyButtonView,
- defStyle, 0);
-
- mCode = a.getInteger(R.styleable.KeyButtonView_keyCode, 0);
-
- mSupportsLongpress = a.getBoolean(R.styleable.KeyButtonView_keyRepeat, true);
-
- TypedValue value = new TypedValue();
- if (a.getValue(R.styleable.KeyButtonView_android_contentDescription, value)) {
- mContentDescriptionRes = value.resourceId;
- }
-
- a.recycle();
-
-
- setClickable(true);
- mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
- mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
- setBackground(new KeyButtonRipple(context, this));
- }
-
- public void setCode(int code) {
- mCode = code;
- }
-
- public void loadAsync(String uri) {
- new AsyncTask<String, Void, Drawable>() {
- @Override
- protected Drawable doInBackground(String... params) {
- return Icon.createWithContentUri(params[0]).loadDrawable(mContext);
- }
-
- @Override
- protected void onPostExecute(Drawable drawable) {
- setImageDrawable(drawable);
- }
- }.execute(uri);
- }
-
- @Override
- protected void onConfigurationChanged(Configuration newConfig) {
- super.onConfigurationChanged(newConfig);
-
- if (mContentDescriptionRes != 0) {
- setContentDescription(mContext.getString(mContentDescriptionRes));
- }
- }
-
- @Override
- public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
- super.onInitializeAccessibilityNodeInfo(info);
- if (mCode != 0) {
- info.addAction(new AccessibilityNodeInfo.AccessibilityAction(ACTION_CLICK, null));
- if (mSupportsLongpress || isLongClickable()) {
- info.addAction(
- new AccessibilityNodeInfo.AccessibilityAction(ACTION_LONG_CLICK, null));
- }
- }
- }
-
- @Override
- protected void onWindowVisibilityChanged(int visibility) {
- super.onWindowVisibilityChanged(visibility);
- if (visibility != View.VISIBLE) {
- jumpDrawablesToCurrentState();
- }
- }
-
- @Override
- public boolean performAccessibilityActionInternal(int action, Bundle arguments) {
- if (action == ACTION_CLICK && mCode != 0) {
- sendEvent(KeyEvent.ACTION_DOWN, 0, SystemClock.uptimeMillis());
- sendEvent(KeyEvent.ACTION_UP, 0);
- sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
- playSoundEffect(SoundEffectConstants.CLICK);
- return true;
- } else if (action == ACTION_LONG_CLICK && mCode != 0) {
- sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.FLAG_LONG_PRESS);
- sendEvent(KeyEvent.ACTION_UP, 0);
- sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
- return true;
- }
- return super.performAccessibilityActionInternal(action, arguments);
- }
-
- public boolean onTouchEvent(MotionEvent ev) {
- final int action = ev.getAction();
- int x, y;
- if (action == MotionEvent.ACTION_DOWN) {
- mGestureAborted = false;
- }
- if (mGestureAborted) {
- return false;
- }
-
- switch (action) {
- case MotionEvent.ACTION_DOWN:
- mDownTime = SystemClock.uptimeMillis();
- mLongClicked = false;
- setPressed(true);
- if (mCode != 0) {
- sendEvent(KeyEvent.ACTION_DOWN, 0, mDownTime);//发送事件给inputmanager
- } else {
- // Provide the same haptic feedback that the system offers for virtual keys.
- performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
- }
- removeCallbacks(mCheckLongPress);
- postDelayed(mCheckLongPress, ViewConfiguration.getLongPressTimeout());//执行长按事件
- break;
- case MotionEvent.ACTION_MOVE:
- x = (int)ev.getX();
- y = (int)ev.getY();
- setPressed(x >= -mTouchSlop
- && x < getWidth() + mTouchSlop
- && y >= -mTouchSlop
- && y < getHeight() + mTouchSlop);
- break;
- case MotionEvent.ACTION_CANCEL:
- setPressed(false);
- if (mCode != 0) {
- sendEvent(KeyEvent.ACTION_UP, KeyEvent.FLAG_CANCELED);
- }
- removeCallbacks(mCheckLongPress);
- break;
- case MotionEvent.ACTION_UP:
- final boolean doIt = isPressed() && !mLongClicked;
- setPressed(false);
- if (mCode != 0) {
- if (doIt) {
- sendEvent(KeyEvent.ACTION_UP, 0);
- sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
- playSoundEffect(SoundEffectConstants.CLICK);
- } else {
- sendEvent(KeyEvent.ACTION_UP, KeyEvent.FLAG_CANCELED);
- }
- } else {
- // no key code, just a regular ImageView
- if (doIt) {
- performClick();
- }
- }
- removeCallbacks(mCheckLongPress);
- break;
- }
-
- return true;
- }
-
- public void playSoundEffect(int soundConstant) {
- mAudioManager.playSoundEffect(soundConstant, ActivityManager.getCurrentUser());
- };
-
- public void sendEvent(int action, int flags) {
- sendEvent(action, flags, SystemClock.uptimeMillis());
- }
-
- void sendEvent(int action, int flags, long when) {
- final int repeatCount = (flags & KeyEvent.FLAG_LONG_PRESS) != 0 ? 1 : 0;
- final KeyEvent ev = new KeyEvent(mDownTime, when, action, mCode, repeatCount,
- 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
- flags | KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY,
- InputDevice.SOURCE_KEYBOARD);
- InputManager.getInstance().injectInputEvent(ev,
- InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
- }
-
- public void abortCurrentGesture() {
- setPressed(false);
- mGestureAborted = true;
- }
- }
分析:
final KeyEvent ev = new KeyEvent(mDownTime, when, action, mCode, repeatCount,
0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
flags | KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY,
InputDevice.SOURCE_KEYBOARD); 中的mCode就是我们之前xml中所定义的。这样系统就能识别我们的意思。意义在于实现不同按键的功能
NavigationBarView
- public class NavigationBarView extends LinearLayout {
- final static boolean DEBUG = false;
- final static String TAG = "PhoneStatusBar/NavigationBarView";
-
- // slippery nav bar when everything is disabled, e.g. during setup
- final static boolean SLIPPERY_WHEN_DISABLED = true;
-
- final Display mDisplay;
- View mCurrentView = null;
- View[] mRotatedViews = new View[4];
-
- boolean mVertical;
- boolean mScreenOn;
-
- boolean mShowMenu;
- int mDisabledFlags = 0;
- int mNavigationIconHints = 0;
-
- private Drawable mBackIcon, mBackLandIcon, mBackAltIcon, mBackAltLandIcon;
- private Drawable mBackCarModeIcon, mBackLandCarModeIcon;
- private Drawable mBackAltCarModeIcon, mBackAltLandCarModeIcon;
- private Drawable mHomeDefaultIcon, mHomeCarModeIcon;
- private Drawable mRecentIcon;
- private Drawable mDockedIcon;
- private Drawable mImeIcon;
- private Drawable mMenuIcon;
- /// M: BMW @{
- private Drawable mRestoreIcon;
- private boolean mResizeMode;
- private boolean mRestoreShow;
- /// @}
-
- private NavigationBarGestureHelper mGestureHelper;
- private DeadZone mDeadZone;
- private final NavigationBarTransitions mBarTransitions;
-
- // workaround for LayoutTransitions leaving the nav buttons in a weird state (bug 5549288)
- final static boolean WORKAROUND_INVALID_LAYOUT = true;
- final static int MSG_CHECK_INVALID_LAYOUT = 8686;
-
- // performs manual animation in sync with layout transitions
- private final NavTransitionListener mTransitionListener = new NavTransitionListener();
-
- private OnVerticalChangedListener mOnVerticalChangedListener;
- private boolean mLayoutTransitionsEnabled = true;
- private boolean mWakeAndUnlocking;
- private boolean mCarMode = false;
- private boolean mDockedStackExists;
-
- private final SparseArray<ButtonDispatcher> mButtonDisatchers = new SparseArray<>();
- private Configuration mConfiguration;
-
- // MPlugin for Navigation Bar
- private INavigationBarPlugin mNavBarPlugin;
- /// M: BMW @{
- private KeyguardViewMediator mKeyguardViewMediator;
- /// @}
-
- private class NavTransitionListener implements TransitionListener {
- private boolean mBackTransitioning;
- private boolean mHomeAppearing;
- private long mStartDelay;
- private long mDuration;
- private TimeInterpolator mInterpolator;
-
- @Override
- public void startTransition(LayoutTransition transition, ViewGroup container,
- View view, int transitionType) {
- if (view.getId() == R.id.back) {
- mBackTransitioning = true;
- } else if (view.getId() == R.id.home && transitionType == LayoutTransition.APPEARING) {
- mHomeAppearing = true;
- mStartDelay = transition.getStartDelay(transitionType);
- mDuration = transition.getDuration(transitionType);
- mInterpolator = transition.getInterpolator(transitionType);
- }
- }
-
- @Override
- public void endTransition(LayoutTransition transition, ViewGroup container,
- View view, int transitionType) {
- if (view.getId() == R.id.back) {
- mBackTransitioning = false;
- } else if (view.getId() == R.id.home && transitionType == LayoutTransition.APPEARING) {
- mHomeAppearing = false;
- }
- }
-
- public void onBackAltCleared() {
- ButtonDispatcher backButton = getBackButton();
-
- // When dismissing ime during unlock, force the back button to run the same appearance
- // animation as home (if we catch this condition early enough).
- if (!mBackTransitioning && backButton.getVisibility() == VISIBLE
- && mHomeAppearing && getHomeButton().getAlpha() == 0) {
- getBackButton().setAlpha(0);
- ValueAnimator a = ObjectAnimator.ofFloat(backButton, "alpha", 0, 1);
- a.setStartDelay(mStartDelay);
- a.setDuration(mDuration);
- a.setInterpolator(mInterpolator);
- a.start();
- }
- }
- }
-
- private final OnClickListener mImeSwitcherClickListener = new OnClickListener() {
- @Override
- public void onClick(View view) {
- mContext.getSystemService(InputMethodManager.class)
- .showInputMethodPicker(true /* showAuxiliarySubtypes */);
- }
- };
-
- private class H extends Handler {
- public void handleMessage(Message m) {
- switch (m.what) {
- case MSG_CHECK_INVALID_LAYOUT:
- final String how = "" + m.obj;
- final int w = getWidth();
- final int h = getHeight();
- final int vw = getCurrentView().getWidth();
- final int vh = getCurrentView().getHeight();
-
- if (h != vh || w != vw) {
- Log.w(TAG, String.format(
- "*** Invalid layout in navigation bar (%s this=%dx%d cur=%dx%d)",
- how, w, h, vw, vh));
- if (WORKAROUND_INVALID_LAYOUT) {
- requestLayout();
- }
- }
- break;
- }
- }
- }
-
- public NavigationBarView(Context context, AttributeSet attrs) {
- super(context, attrs);
-
- mDisplay = ((WindowManager) context.getSystemService(
- Context.WINDOW_SERVICE)).getDefaultDisplay();
-
- mVertical = false;
- mShowMenu = false;
- mGestureHelper = new NavigationBarGestureHelper(context);//手势管理类
-
- mConfiguration = new Configuration();
- mConfiguration.updateFrom(context.getResources().getConfiguration());
- updateIcons(context, Configuration.EMPTY, mConfiguration);//加载更新图标
-
- // MPlugin Navigation Bar creation and initialization
- try {
- mNavBarPlugin = (INavigationBarPlugin) MPlugin.createInstance(
- INavigationBarPlugin.class.getName(), context);
- } catch (Exception e) {
- Log.e(TAG, "Catch INavigationBarPlugin exception: ", e);
- }
- if (mNavBarPlugin == null) {
- Log.d(TAG, "DefaultNavigationBarPlugin");
- mNavBarPlugin = new DefaultNavigationBarPlugin(context);
- }
-
- mBarTransitions = new NavigationBarTransitions(this);
- //返回键 、主页 、近期列表 三个按键的监听控制。
- mButtonDisatchers.put(R.id.back, new ButtonDispatcher(R.id.back));
- mButtonDisatchers.put(R.id.home, new ButtonDispatcher(R.id.home));
- mButtonDisatchers.put(R.id.recent_apps, new ButtonDispatcher(R.id.recent_apps));
- /// M: BMW @{
- if (MultiWindowManager.isSupported()) {
- mButtonDisatchers.put(R.id.restore, new ButtonDispatcher(R.id.restore));
- mKeyguardViewMediator = ((SystemUIApplication)context)
- .getComponent(KeyguardViewMediator.class);
- }
- /// @}
- mButtonDisatchers.put(R.id.menu, new ButtonDispatcher(R.id.menu));
- mButtonDisatchers.put(R.id.ime_switcher, new ButtonDispatcher(R.id.ime_switcher));
- }
-
- public BarTransitions getBarTransitions() {
- return mBarTransitions;
- }
-
- public void setComponents(RecentsComponent recentsComponent, Divider divider) {
- mGestureHelper.setComponents(recentsComponent, divider, this);
- }
-
- public void setOnVerticalChangedListener(OnVerticalChangedListener onVerticalChangedListener) {
- mOnVerticalChangedListener = onVerticalChangedListener;
- notifyVerticalChangedListener(mVertical);
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- if (mGestureHelper.onTouchEvent(event)) {
- return true;
- }
- if (mDeadZone != null && event.getAction() == MotionEvent.ACTION_OUTSIDE) {
- mDeadZone.poke(event);
- }
- return super.onTouchEvent(event);
- }
-
- @Override
- public boolean onInterceptTouchEvent(MotionEvent event) {
- return mGestureHelper.onInterceptTouchEvent(event);
- }
-
- public void abortCurrentGesture() {
- getHomeButton().abortCurrentGesture();
- }
-
- private H mHandler = new H();
-
- public View getCurrentView() {
- return mCurrentView;
- }
-
- public View[] getAllViews() {
- return mRotatedViews;
- }
- //TODO:: Temp remove plugin for build pass, need to add back
- public ButtonDispatcher getRecentsButton() {
- return mButtonDisatchers.get(R.id.recent_apps);
- }
-
- public ButtonDispatcher getMenuButton() {
- return mButtonDisatchers.get(R.id.menu);
- }
-
- public ButtonDispatcher getBackButton() {
- return mButtonDisatchers.get(R.id.back);
- }
-
- public ButtonDispatcher getHomeButton() {
- return mButtonDisatchers.get(R.id.home);
- }
-
- public ButtonDispatcher getImeSwitchButton() {
- return mButtonDisatchers.get(R.id.ime_switcher);
- }
-
- /// M: BMW @{
- public ButtonDispatcher getRestoreButton() {
- return mButtonDisatchers.get(R.id.restore);
- }
- /// @}
-
- private void updateCarModeIcons(Context ctx) {
- mBackCarModeIcon = ctx.getDrawable(R.drawable.ic_sysbar_back_carmode);
- mBackLandCarModeIcon = mBackCarModeIcon;
- mBackAltCarModeIcon = ctx.getDrawable(R.drawable.ic_sysbar_back_ime_carmode);
- mBackAltLandCarModeIcon = mBackAltCarModeIcon;
- mHomeCarModeIcon = ctx.getDrawable(R.drawable.ic_sysbar_home_carmode);
- }
-
- private void updateIcons(Context ctx, Configuration oldConfig, Configuration newConfig) {
- if (oldConfig.orientation != newConfig.orientation
- || oldConfig.densityDpi != newConfig.densityDpi) {
- mDockedIcon = ctx.getDrawable(R.drawable.ic_sysbar_docked);
- }
- if (oldConfig.densityDpi != newConfig.densityDpi) {
- mBackIcon = ctx.getDrawable(R.drawable.ic_sysbar_back);
- mBackLandIcon = mBackIcon;
- mBackAltIcon = ctx.getDrawable(R.drawable.ic_sysbar_back_ime);
- mBackAltLandIcon = mBackAltIcon;
-
- mHomeDefaultIcon = ctx.getDrawable(R.drawable.ic_sysbar_home);
- mRecentIcon = ctx.getDrawable(R.drawable.ic_sysbar_recent);
- mMenuIcon = ctx.getDrawable(R.drawable.ic_sysbar_menu);
- mImeIcon = ctx.getDrawable(R.drawable.ic_ime_switcher_default);
- /// M: BMW @{
- if (MultiWindowManager.isSupported()) {
- mRestoreIcon = ctx.getDrawable(R.drawable.ic_sysbar_restore);
- }
- /// @}
- updateCarModeIcons(ctx);
- }
- }
-
- @Override
- public void setLayoutDirection(int layoutDirection) {
- // Reload all the icons
- updateIcons(getContext(), Configuration.EMPTY, mConfiguration);
-
- super.setLayoutDirection(layoutDirection);
- }
-
- public void notifyScreenOn(boolean screenOn) {
- mScreenOn = screenOn;
- setDisabledFlags(mDisabledFlags, true);
- }
-
- public void setNavigationIconHints(int hints) {
- setNavigationIconHints(hints, false);
- }
-
- private Drawable getBackIconWithAlt(boolean carMode, boolean landscape) {
- return landscape
- ? carMode ? mBackAltLandCarModeIcon : mBackAltLandIcon
- : carMode ? mBackAltCarModeIcon : mBackAltIcon;
- }
-
- private Drawable getBackIcon(boolean carMode, boolean landscape) {
- return landscape
- ? carMode ? mBackLandCarModeIcon : mBackLandIcon
- : carMode ? mBackCarModeIcon : mBackIcon;
- }
-
- public void setNavigationIconHints(int hints, boolean force) {
- if (!force && hints == mNavigationIconHints) return;
- final boolean backAlt = (hints & StatusBarManager.NAVIGATION_HINT_BACK_ALT) != 0;
- if ((mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_BACK_ALT) != 0 && !backAlt) {
- mTransitionListener.onBackAltCleared();
- }
- if (DEBUG) {
- android.widget.Toast.makeText(getContext(),
- "Navigation icon hints = " + hints,
- 500).show();
- }
-
- mNavigationIconHints = hints;
-
- // We have to replace or restore the back and home button icons when exiting or entering
- // carmode, respectively. Recents are not available in CarMode in nav bar so change
- // to recent icon is not required.
- Drawable backIcon = (backAlt)
- ? getBackIconWithAlt(mCarMode, mVertical)
- : getBackIcon(mCarMode, mVertical);
- /// M: Support plugin customize.
- //getBackButton().setImageDrawable(backIcon);
- getBackButton().setImageDrawable(mNavBarPlugin.getBackImage(backIcon));//设置返回图标
-
- updateRecentsIcon();//最近列表图标
- /// M: BMW @{
- if (MultiWindowManager.isSupported()) {
- updateRestoreIcon();
- }
- /// @}
- //设置home图标
-
- if (mCarMode) {
- getHomeButton().setImageDrawable(mHomeCarModeIcon);
- } else {
- /// M: Support plugin customize.
- //getHomeButton().setImageDrawable(mHomeDefaultIcon);
- getHomeButton().setImageDrawable(mNavBarPlugin.getHomeImage(mHomeDefaultIcon));
- }
-
- final boolean showImeButton = ((hints & StatusBarManager.NAVIGATION_HINT_IME_SHOWN) != 0);
- getImeSwitchButton().setVisibility(showImeButton ? View.VISIBLE : View.INVISIBLE);
- getImeSwitchButton().setImageDrawable(mImeIcon);
-
- // Update menu button in case the IME state has changed.
- setMenuVisibility(mShowMenu, true);
- getMenuButton().setImageDrawable(mMenuIcon);
-
- setDisabledFlags(mDisabledFlags, true);
- }
-
- public void setDisabledFlags(int disabledFlags) {
- setDisabledFlags(disabledFlags, false);
- }
-
- public void setDisabledFlags(int disabledFlags, boolean force) {
- if (!force && mDisabledFlags == disabledFlags) return;
-
- mDisabledFlags = disabledFlags;
-
- final boolean disableHome = ((disabledFlags & View.STATUS_BAR_DISABLE_HOME) != 0);
-
- // Disable recents always in car mode.
- boolean disableRecent = (
- mCarMode || (disabledFlags & View.STATUS_BAR_DISABLE_RECENT) != 0);
- final boolean disableBack = ((disabledFlags & View.STATUS_BAR_DISABLE_BACK) != 0)
- && ((mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_BACK_ALT) == 0);
- final boolean disableSearch = ((disabledFlags & View.STATUS_BAR_DISABLE_SEARCH) != 0);
-
- if (SLIPPERY_WHEN_DISABLED) {
- setSlippery(disableHome && disableRecent && disableBack && disableSearch);
- }
-
- ViewGroup navButtons = (ViewGroup) getCurrentView().findViewById(R.id.nav_buttons);
- if (navButtons != null) {
- LayoutTransition lt = navButtons.getLayoutTransition();
- if (lt != null) {
- if (!lt.getTransitionListeners().contains(mTransitionListener)) {
- lt.addTransitionListener(mTransitionListener);
- }
- }
- }
- if (inLockTask() && disableRecent && !disableHome) {
- // Don't hide recents when in lock task, it is used for exiting.
- // Unless home is hidden, then in DPM locked mode and no exit available.
- disableRecent = false;
- }
-
- getBackButton().setVisibility(disableBack ? View.INVISIBLE : View.VISIBLE);
- getHomeButton().setVisibility(disableHome ? View.INVISIBLE : View.VISIBLE);
- getRecentsButton().setVisibility(disableRecent ? View.INVISIBLE : View.VISIBLE);
-
- /// M: BMW @{
- //hide restore when keyguard is showing
- if (MultiWindowManager.isSupported() && mKeyguardViewMediator != null) {
- boolean isKeyguardShowing = mKeyguardViewMediator.isShowing();
- mResizeMode = mRestoreShow && !isKeyguardShowing;
- updateRestoreIcon();
- }
- /// @}
- }
-
- private boolean inLockTask() {
- try {
- return ActivityManagerNative.getDefault().isInLockTaskMode();
- } catch (RemoteException e) {
- return false;
- }
- }
-
- public void setLayoutTransitionsEnabled(boolean enabled) {
- mLayoutTransitionsEnabled = enabled;
- updateLayoutTransitionsEnabled();
- }
-
- public void setWakeAndUnlocking(boolean wakeAndUnlocking) {
- setUseFadingAnimations(wakeAndUnlocking);
- mWakeAndUnlocking = wakeAndUnlocking;
- updateLayoutTransitionsEnabled();
- }
-
- private void updateLayoutTransitionsEnabled() {
- boolean enabled = !mWakeAndUnlocking && mLayoutTransitionsEnabled;
- ViewGroup navButtons = (ViewGroup) getCurrentView().findViewById(R.id.nav_buttons);
- LayoutTransition lt = navButtons.getLayoutTransition();
- if (lt != null) {
- if (enabled) {
- lt.enableTransitionType(LayoutTransition.APPEARING);
- lt.enableTransitionType(LayoutTransition.DISAPPEARING);
- lt.enableTransitionType(LayoutTransition.CHANGE_APPEARING);
- lt.enableTransitionType(LayoutTransition.CHANGE_DISAPPEARING);
- } else {
- lt.disableTransitionType(LayoutTransition.APPEARING);
- lt.disableTransitionType(LayoutTransition.DISAPPEARING);
- lt.disableTransitionType(LayoutTransition.CHANGE_APPEARING);
- lt.disableTransitionType(LayoutTransition.CHANGE_DISAPPEARING);
- }
- }
- }
-
- private void setUseFadingAnimations(boolean useFadingAnimations) {
- WindowManager.LayoutParams lp = (WindowManager.LayoutParams) getLayoutParams();
- if (lp != null) {
- boolean old = lp.windowAnimations != 0;
- if (!old && useFadingAnimations) {
- lp.windowAnimations = R.style.Animation_NavigationBarFadeIn;
- } else if (old && !useFadingAnimations) {
- lp.windowAnimations = 0;
- } else {
- return;
- }
- WindowManager wm = (WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE);
- wm.updateViewLayout(this, lp);
- }
- }
-
- public void setSlippery(boolean newSlippery) {
- WindowManager.LayoutParams lp = (WindowManager.LayoutParams) getLayoutParams();
- if (lp != null) {
- boolean oldSlippery = (lp.flags & WindowManager.LayoutParams.FLAG_SLIPPERY) != 0;
- if (!oldSlippery && newSlippery) {
- lp.flags |= WindowManager.LayoutParams.FLAG_SLIPPERY;
- } else if (oldSlippery && !newSlippery) {
- lp.flags &= ~WindowManager.LayoutParams.FLAG_SLIPPERY;
- } else {
- return;
- }
- WindowManager wm = (WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE);
- wm.updateViewLayout(this, lp);
- }
- }
-
- public void setMenuVisibility(final boolean show) {
- setMenuVisibility(show, false);
- }
-
- public void setMenuVisibility(final boolean show, final boolean force) {
- if (!force && mShowMenu == show) return;
-
- mShowMenu = show;
-
- // Only show Menu if IME switcher not shown.
- final boolean shouldShow = mShowMenu &&
- ((mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_IME_SHOWN) == 0);
-
- getMenuButton().setVisibility(shouldShow ? View.VISIBLE : View.INVISIBLE);
- }
-
- @Override
- public void onFinishInflate() {
- updateRotatedViews();
- ((NavigationBarInflaterView) findViewById(R.id.navigation_inflater)).setButtonDispatchers(
- mButtonDisatchers);
-
- getImeSwitchButton().setOnClickListener(mImeSwitcherClickListener);
-
- try {
- WindowManagerGlobal.getWindowManagerService().registerDockedStackListener(new Stub() {
- @Override
- public void onDividerVisibilityChanged(boolean visible) throws RemoteException {
- }
-
- @Override
- public void onDockedStackExistsChanged(final boolean exists) throws RemoteException {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- mDockedStackExists = exists;
- updateRecentsIcon();//最近列表图标变化的更改。
- }
- });
- }
-
- @Override
- public void onDockedStackMinimizedChanged(boolean minimized, long animDuration)
- throws RemoteException {
- }
-
- @Override
- public void onAdjustedForImeChanged(boolean adjustedForIme, long animDuration)
- throws RemoteException {
- }
-
- @Override
- public void onDockSideChanged(int newDockSide) throws RemoteException {
- }
- });
- } catch (RemoteException e) {
- Log.e(TAG, "Failed registering docked stack exists listener", e);
- }
-
-
- /// M: BMW restore button @{
- if (MultiWindowManager.isSupported()) {
- try {
- WindowManagerGlobal.getWindowManagerService()
- .registerFreeformStackListener(new IFreeformStackListener.Stub() {
- @Override
- public void onShowRestoreButtonChanged(final boolean isShown)
- throws RemoteException {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- //hide restore when keyguard is showing
- boolean isKeyguardShowing = false;
- if (mKeyguardViewMediator != null) {
- isKeyguardShowing = mKeyguardViewMediator.isShowing();
- }
- mRestoreShow = isShown;
- mResizeMode = isShown && !isKeyguardShowing;
- updateRestoreIcon();
- }
- });
- }
- });
- } catch (RemoteException e) {
- Log.e(TAG, "Failed registering freeform stack exists listener", e);
- }
-
- }
-
- /// @}
- }
-
- /// M: BMW restore button @{
- private void updateRestoreIcon() {
- if (MultiWindowManager.DEBUG)
- Log.d(TAG, "BMW, updateRestoreIcon, mResizeMode = " + mResizeMode);
- getRestoreButton().setImageDrawable(mRestoreIcon);
- getRestoreButton().setVisibility(mResizeMode ? View.VISIBLE : View.INVISIBLE);
- }
- /// @}
-
- void updateRotatedViews() {
- mRotatedViews[Surface.ROTATION_0] =
- mRotatedViews[Surface.ROTATION_180] = findViewById(R.id.rot0);
- mRotatedViews[Surface.ROTATION_270] =
- mRotatedViews[Surface.ROTATION_90] = findViewById(R.id.rot90);
-
- updateCurrentView();
- }
-
- private void updateCurrentView() {
- //获取旋转角度,在控制树之前会对所以的view进行gone
- final int rot = mDisplay.getRotation();
- for (int i=0; i<4; i++) {
- mRotatedViews[i].setVisibility(View.GONE);
- }
- mCurrentView = mRotatedViews[rot];
- mCurrentView.setVisibility(View.VISIBLE);
- for (int i = 0; i < mButtonDisatchers.size(); i++) {
- mButtonDisatchers.valueAt(i).setCurrentView(mCurrentView);
- }
- //加载时候的动画显示
- updateLayoutTransitionsEnabled();
- }
-
- private void updateRecentsIcon() {
- /// M: Support plugin customize.
- //getRecentsButton().setImageDrawable(mDockedStackExists ? mDockedIcon : mRecentIcon);
- getRecentsButton().setImageDrawable(
- mNavBarPlugin.getRecentImage(mDockedStackExists ? mDockedIcon : mRecentIcon));
- }
-
- public boolean isVertical() {
- return mVertical;
- }
-
- public void reorient() {
- updateCurrentView();
-
- getImeSwitchButton().setOnClickListener(mImeSwitcherClickListener);
-
- mDeadZone = (DeadZone) mCurrentView.findViewById(R.id.deadzone);//死亡区域
-
- // force the low profile & disabled states into compliance
- mBarTransitions.init();
- setDisabledFlags(mDisabledFlags, true /* force */);//禁用一些功能。
- setMenuVisibility(mShowMenu, true /* force */);//设置菜单的可见性
-
- if (DEBUG) {
- Log.d(TAG, "reorient(): rot=" + mDisplay.getRotation());
- }
-
- updateTaskSwitchHelper();
- setNavigationIconHints(mNavigationIconHints, true);//修改图标
- }
-
- private void updateTaskSwitchHelper() {
- boolean isRtl = (getLayoutDirection() == View.LAYOUT_DIRECTION_RTL);
- mGestureHelper.setBarState(mVertical, isRtl);
- }
-
- @Override
- protected void onSizeChanged(int w, int h, int oldw, int oldh) {
- if (DEBUG) Log.d(TAG, String.format(
- "onSizeChanged: (%dx%d) old: (%dx%d)", w, h, oldw, oldh));
-
- final boolean newVertical = w > 0 && h > w;//检查当前是水平还是竖直。
- //当方向变化时,
- if (newVertical != mVertical) {
- mVertical = newVertical;
- //Log.v(TAG, String.format("onSizeChanged: h=%d, w=%d, vert=%s", h, w, mVertical?"y":"n"));
- reorient();
- notifyVerticalChangedListener(newVertical);
- }
-
- postCheckForInvalidLayout("sizeChanged");
- super.onSizeChanged(w, h, oldw, oldh);
- }
-
- private void notifyVerticalChangedListener(boolean newVertical) {
- if (mOnVerticalChangedListener != null) {
- mOnVerticalChangedListener.onVerticalChanged(newVertical);
- }
- }
-
- @Override
- protected void onConfigurationChanged(Configuration newConfig) {
- super.onConfigurationChanged(newConfig);
- boolean uiCarModeChanged = updateCarMode(newConfig);
- updateTaskSwitchHelper();
- updateIcons(getContext(), mConfiguration, newConfig);
- updateRecentsIcon();
- if (uiCarModeChanged || mConfiguration.densityDpi != newConfig.densityDpi) {
- // If car mode or density changes, we need to reset the icons.
- setNavigationIconHints(mNavigationIconHints, true);
- }
- mConfiguration.updateFrom(newConfig);
- }
-
- /**
- * If the configuration changed, update the carmode and return that it was updated.
- */
- private boolean updateCarMode(Configuration newConfig) {
- boolean uiCarModeChanged = false;
- if (newConfig != null) {
- int uiMode = newConfig.uiMode & Configuration.UI_MODE_TYPE_MASK;
- if (mCarMode && uiMode != Configuration.UI_MODE_TYPE_CAR) {
- mCarMode = false;
- uiCarModeChanged = true;
- } else if (uiMode == Configuration.UI_MODE_TYPE_CAR) {
- mCarMode = true;
- uiCarModeChanged = true;
- }
- }
- return uiCarModeChanged;
- }
-
- /*
- @Override
- protected void onLayout (boolean changed, int left, int top, int right, int bottom) {
- if (DEBUG) Log.d(TAG, String.format(
- "onLayout: %s (%d,%d,%d,%d)",
- changed?"changed":"notchanged", left, top, right, bottom));
- super.onLayout(changed, left, top, right, bottom);
- }
- // uncomment this for extra defensiveness in WORKAROUND_INVALID_LAYOUT situations: if all else
- // fails, any touch on the display will fix the layout.
- @Override
- public boolean onInterceptTouchEvent(MotionEvent ev) {
- if (DEBUG) Log.d(TAG, "onInterceptTouchEvent: " + ev.toString());
- if (ev.getAction() == MotionEvent.ACTION_DOWN) {
- postCheckForInvalidLayout("touch");
- }
- return super.onInterceptTouchEvent(ev);
- }
- */
-
-
- private String getResourceName(int resId) {
- if (resId != 0) {
- final android.content.res.Resources res = getContext().getResources();
- try {
- return res.getResourceName(resId);
- } catch (android.content.res.Resources.NotFoundException ex) {
- return "(unknown)";
- }
- } else {
- return "(null)";
- }
- }
-
- private void postCheckForInvalidLayout(final String how) {
- mHandler.obtainMessage(MSG_CHECK_INVALID_LAYOUT, 0, 0, how).sendToTarget();
- }
-
- private static String visibilityToString(int vis) {
- switch (vis) {
- case View.INVISIBLE:
- return "INVISIBLE";
- case View.GONE:
- return "GONE";
- default:
- return "VISIBLE";
- }
- }
-
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.println("NavigationBarView {");
- final Rect r = new Rect();
- final Point size = new Point();
- mDisplay.getRealSize(size);
-
- pw.println(String.format(" this: " + PhoneStatusBar.viewInfo(this)
- + " " + visibilityToString(getVisibility())));
-
- getWindowVisibleDisplayFrame(r);
- final boolean offscreen = r.right > size.x || r.bottom > size.y;
- pw.println(" window: "
- + r.toShortString()
- + " " + visibilityToString(getWindowVisibility())
- + (offscreen ? " OFFSCREEN!" : ""));
-
- pw.println(String.format(" mCurrentView: id=%s (%dx%d) %s",
- getResourceName(getCurrentView().getId()),
- getCurrentView().getWidth(), getCurrentView().getHeight(),
- visibilityToString(getCurrentView().getVisibility())));
-
- pw.println(String.format(" disabled=0x%08x vertical=%s menu=%s",
- mDisabledFlags,
- mVertical ? "true" : "false",
- mShowMenu ? "true" : "false"));
-
- dumpButton(pw, "back", getBackButton());
- dumpButton(pw, "home", getHomeButton());
- dumpButton(pw, "rcnt", getRecentsButton());
- dumpButton(pw, "menu", getMenuButton());
-
- pw.println(" }");
- }
-
- private static void dumpButton(PrintWriter pw, String caption, ButtonDispatcher button) {
- pw.print(" " + caption + ": ");
- if (button == null) {
- pw.print("null");
- } else {
- pw.print(visibilityToString(button.getVisibility())
- + " alpha=" + button.getAlpha()
- );
- }
- pw.println();
- }
-
- public interface OnVerticalChangedListener {
- void onVerticalChanged(boolean isVertical);
- }
-
- }
分析:
1.在这里面我们可以控制不同方向的导航栏布局
2 导航栏的图片的显示。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。