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方法将我们新布局设置进去就可以了,快来试试吧。

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

目录
相关文章
|
2月前
|
缓存 Java Shell
Android 系统缓存扫描与清理方法分析
Android 系统缓存从原理探索到实现。
80 15
Android 系统缓存扫描与清理方法分析
|
2月前
|
Android开发
Android面试之Activity启动流程简述
Android面试之Activity启动流程简述
94 6
|
2月前
|
消息中间件 Android开发 索引
Android面试高频知识点(4) 详解Activity的启动流程
Android面试高频知识点(4) 详解Activity的启动流程
31 3
|
2月前
|
缓存 前端开发 Android开发
Android实战之如何截取Activity或者Fragment的内容?
本文首发于公众号“AntDream”,介绍了如何在Android中截取Activity或Fragment的屏幕内容并保存为图片。包括截取整个Activity、特定控件或区域的方法,以及处理包含RecyclerView的复杂情况。
26 3
|
2月前
|
Android开发
Android面试之Activity启动流程简述
Android面试之Activity启动流程简述
20 0
|
3月前
|
消息中间件 Android开发 索引
Android面试高频知识点(4) 详解Activity的启动流程
讲解Activity的启动流程了,Activity的启动流程相对复杂一下,涉及到了Activity中的生命周期方法,涉及到了Android体系的CS模式,涉及到了Android中进程通讯Binder机制等等, 首先介绍一下Activity,这里引用一下Android guide中对Activity的介绍:
59 4
|
3月前
|
Android开发 开发者 索引
Android实战经验之如何使用DiffUtil提升RecyclerView的刷新性能
本文介绍如何使用 `DiffUtil` 实现 `RecyclerView` 数据集的高效更新,避免不必要的全局刷新,尤其适用于处理大量数据场景。通过定义 `DiffUtil.Callback`、计算差异并应用到适配器,可以显著提升性能。同时,文章还列举了常见错误及原因,帮助开发者避免陷阱。
261 9
|
3月前
|
开发工具 Android开发 git
Android实战之组件化中如何进行版本控制和依赖管理
本文介绍了 Git Submodules 的功能及其在组件化开发中的应用。Submodules 允许将一个 Git 仓库作为另一个仓库的子目录,有助于保持模块独立、代码重用和版本控制。虽然存在一些缺点,如增加复杂性和初始化时间,但通过最佳实践可以有效利用其优势。
44 3
|
3月前
|
ARouter 测试技术 API
Android经典面试题之组件化原理、优缺点、实现方法?
本文介绍了组件化在Android开发中的应用,详细阐述了其原理、优缺点及实现方式,包括模块化、接口编程、依赖注入、路由机制等内容,并提供了具体代码示例。
51 2
|
2月前
|
Android开发
Android实战之如何快速实现自动轮播图
本文介绍了在 Android 中使用 `ViewPager2` 和自定义适配器实现轮播图的方法,包括添加依赖、布局配置、创建适配器及实现自动轮播等步骤。
87 0