看了下公司的系统代码对于根布局decor_layout.xml的修改, 有所获.
前些时候才开始做系统开发的时候, 总想改改系统的源码, 至于原因: 人总是想装装, 在踩过几个别人修改的坑后, 还是觉得在不改源码的基础上, 尽量纳源码为自己所用还是挺好的.
代码如下:
1 public void wrapDecor(Activity activity) { 2 3 mWindow = activity.getWindow(); 4 if(mWindow == null){ 5 Log.e(TAG, "Window is null"); 6 return; 7 } 8 9 View decorView = mWindow.getDecorView(); 10 if (decorView == null) { 11 Log.e(TAG, "DecorView is null"); 12 return; 13 } 14 15 ViewGroup contentView = (ViewGroup) decorView.findViewById(android.R.id.content); 16 if (contentView == null) { 17 Log.e(TAG, "DecorView is null, have you called wrapDecor after Activity#super.onCreate?"); 18 return; 19 } 20 21 final int childCount = contentView.getChildCount(); 22 if (childCount == 0) { 23 // Maybe called before Activity#setContentView 24 mPotentialErrorFlag |= FLAG_POTENTIAL_ERROR_SET_CONTENT; 25 } 26 27 View[] children = new View[childCount]; 28 for (int i = 0; i < childCount; i++) { 29 children[i] = contentView.getChildAt(i); 30 } 31 32 contentView.removeAllViews(); 33 34 LayoutInflater inflater = LayoutInflater.from(activity); 35 36 //===================== begin ======================== 37 38 // 此处即为自定义的decor_layout.xml文件 39 View wrapper = inflater.inflate(R.layout.decor_layout, null); 40 41 ViewGroup rawContentView = (ViewGroup) wrapper.findViewById(R.id.content); 42 if (childCount > 0) { 43 for (View child : children) { 44 rawContentView.addView(child); 45 } 46 } 47 //change for listActivity, add view first then setContenView 48 activity.setContentView(wrapper); 49 50 //===================== end ======================= 51 52 // 获取自定义decor_layout中的控件 53 mOptionsKey = wrapper.findViewById(R.id.feature_bar_options); 54 55 // 此处获取的是ActionBar的控件, 由于项目中需要大量使用到ActionBar, 56 // 此处对覆盖ActionBar对OptionMenu的控制 57 ActionBarView actionBarView = (ActionBarView) decorView.findViewById( 58 com.android.internal.R.id.action_bar); 59 if (actionBarView != null) { 60 // 覆盖ActionBar对OptionMenu的控制 61 actionBarView.setOverrideOverflowButton(mOptionsKey); 62 } else { 63 Log.d(TAG, "actionBarView is null"); 64 if (mWindow != null) { 65 Log.d(TAG, "Attempt to invoke setShouldOverrideResources access PhoneWindow"); 66 mWindow.setShouldOverrideResources(true); 67 } else { 68 Log.d(TAG, "mWindow is empty, pls check it"); 69 } 70 } 71 }
该段代码的核心, 就在上面的 begin 和 end 之间, 代码挺简单, 使用到包装的思想, 也就是包装设计模式.