前言:
通常我们有时候会直接使用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中实现了如下代码:
@Override protected 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方法将我们新布局设置进去就可以了,快来试试吧。
有疑问或者看不懂、看不明白的请留言。