android.R.id.content指什么以及一个实例

android.R.id.content所指区域

android.R.id.content是一个FrameLayout,只有一个子元素,就是平时在onCreate方法中设置的setContentView。也即,当我们在Layout文件中设置一个布局文件时,实际上该布局被一个FrameLayout所包含。

为什么是一个FrameLayout,官方文档中解释如下

Generally, FrameLayout should be used to hold a single child view, because it can be difficult to organize child views in a way that’s scalable to different screen sizes without the children overlapping each other.

需要注意的是,在不同的SDK版本下,该FrameLayout所指的显示区域也不同。具体如下

  1. 在sdk 14+(native ActionBar),该显示区域指的是ActionBar下面的部分
  2. 在Support Library revision lower than 19,使用AppCompat,则显示区域包含ActionBar
  3. 在Support Library revision 19 (or greater),使用AppCompat,则显示区域不包含ActionBar,即行为与第一种情况相同。

所以如果不使用Support Library或使用Support Library的最新版本,则R.id.content所指的区域都是ActionBar以下

具体的解释参考StackOverflow上的回答

一个应用

以下应用为当ListView还没有数据时,显示一个ProgressBar

相关代码如下

setContentView(R.layout.activity_item_list);

setSupportActionBar(mToolbar);

ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);

ProgressBar progressBar= new ProgressBar(this);
progressBar.setLayoutParams(new FrameLayout.LayoutParams(
        FrameLayout.LayoutParams.WRAP_CONTENT,
        FrameLayout.LayoutParams.WRAP_CONTENT,
        Gravity.CENTER));

progressBar.setIndeterminate(true);
ViewGroup root = (ViewGroup) findViewById(android.R.id.content);

root.addView(progressBar);
    mListView.setEmptyView(progressBar);

其中R.layout.activity_item_list的层次关系如下

LinearLayout
- ActionBar
- ListView

整个ItemListActivity的层次关系如下

FrameLayout
 - LinearLayout
   - ActionBar
   - ListView
 - progressBar

因为FrameLayout是栈的结构,所以LinearLayout会遮盖掉ProgressBar

当调用listview的setEmptyView时会判断传入的参数是否为null,如果不是,则将listview本身设置为View.GONE,并将传入的View设置为View.VISIBLE(以上见setEmptyView的源码),因为FrameLayout的栈结构,所以在ListView填充数据前,层次结构为

FrameLayout
 - LinearLayout
   - ActionBar
 - progressBar

显示的效果就是ActionBar在上面,progressBar在内容区

当有内容时,显示出ListView,并遮盖了progressBar

注意progressBar的LayoutParams用的是FrameLayout.LayoutParams,因为其父View是FrameLayout