前言:
通常我们有时候会直接使用ADT工具直接新建一个Activity页,而这个Activity我们又无法更改它的父类,那遇到这种情况该如何处理呢?其实很简单,好,看如何来解决这个问题:
先来看看这个问题出现的情况,我们以SettingsActivity举例:
上图是SettingActivity的继承关系,在PreferenceActivity的内部被引用了一些internal包内的文件,普通情况下我们是无法访问这些文件的,所以我们不能通过复制ListActivity、PreferenceActivity中源代码的方式来为ListActivity更改它的父类(这里我为什么要说更改父类呢,在一般情况下,我们的项目中是有一个通用的ActionBarActivity的,通过继承它便可以自动添加ActionBar到Activity中),所以这样情况下我们就需要在SettingActivity的布局与根布局中间嵌套一层ViewGroup了,就像下面这样:
这个图可能有些丑,我来描述一下是什么情况:
我们通常在Activity中使用setContentView方法会将我们的布局文件添加到mContentRoot这个ViewGroup中去,现在呢,我们想办法把在原来的自定义布局与mContentRoot中见嵌套一个线性布局,并且线性布局中间包含我们的自定义ActionBar,这样就可以实现我们的添加ActionBar的功能。
下面看一下自动生成的与我们处理之后的效果:
左边是我通过ADT工具直接生成的SettingsActivity界面,由于我的Application设置的主题是没有ActionBar的,所以,这里没有显示系统提供的ActionBar,我想大家都明白的。
右边这张图就是我们实现之后的效果,是不是挺赞的,来看看是如何实现的:
我们在SettingsActivity中实现了如下代码:
@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setupActionBar();}/*** Set up the {@link android.app.ActionBar}, if the API is available.*/@TargetApi(Build.VERSION_CODES.HONEYCOMB)private void setupActionBar() {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {// Show the Up button in the action bar.try {Field mContentParentField = getWindow().getClass().getDeclaredField("mContentParent");mContentParentField.setAccessible(true);Object mContentParent = mContentParentField.get(getWindow());if (mContentParent instanceof ViewGroup) {LinearLayout ll = new LinearLayout(this);ll.setOrientation(LinearLayout.VERTICAL);ll.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT));LayoutInflater.from(this).inflate(R.layout.custom_action_bar_layout, ll);ViewGroup temp = (ViewGroup) mContentParent;int childCount = temp.getChildCount();for (int i = 0; i < childCount; i++) {View view = temp.getChildAt(i);temp.removeView(view);ll.addView(view);}setContentView(ll);}} catch (NoSuchFieldException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();}}}
这里的意思就是把mContentParent中的内容遍历出来,然后添加到新的容器ll当中,当然在ll创建之后就添加了自定义ActionBar,最后再通过setContentView方法将我们新布局设置进去就可以了,快来试试吧。
有疑问或者看不懂、看不明白的请留言。