Android如何给无法更改继承关系的Activity更换ActionBar(setContentView方法实战)-阿里云开发者社区

开发者社区> 开发与运维> 正文
登录阅读全文

Android如何给无法更改继承关系的Activity更换ActionBar(setContentView方法实战)

简介: 前言: 通常我们有时候会直接使用ADT工具直接新建一个Activity页,而这个Activity我们又无法更改它的父类,那遇到这种情况该如何处理呢?其实很简单,好,看如何来解决这个问题: 先来看看这个问题出现的情况,我们以SettingsActivity举例: 上图是Setting...

前言:

通常我们有时候会直接使用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方法将我们新布局设置进去就可以了,快来试试吧。

有疑问或者看不懂、看不明白的请留言。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:
开发与运维
使用钉钉扫一扫加入圈子
+ 订阅

集结各类场景实战经验,助你开发运维畅行无忧

其他文章