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