关于actionbar的overlay模式请参考 如何让android的actionbar浮动且透明 一文。这篇文章讲的是如何在这种模式下让actionbar不遮住顶部的内容。

这 一般是这样的场景,在一个ListView显示图片的界面中,当ListView向下滑动的时候,actionbar是是浮动在GridView上面一层 的,但是当ListView滚动到顶部,顶部的内容是完全显示出来的,当然这种情况一般ActionBar我们会做成透明效果。

其实很多人都能想到的是,将ListView加上一个高度和actionbar的高度相同的header不就行了吗?

但是,难点是如何得到actionbar的高度。

actionbar的高度其实是在android系统主题的资源文件中定义的,如果你没有主动去修改actionbar的高度,那么可以通过下面的代码来获取:

TypedArray actionbarSizeTypedArray = getActivity().obtainStyledAttributes(new int[] {android.R.attr.actionBarSize
});
float h = actionbarSizeTypedArray.getDimension(0, 0);

但是这种方式并不太规范,而且在android4.4之后,statusbar所在的区域也是可以显示内容的,这时你还得去计算statusbar的高度。

其 实FrameLayout 中boolean fitSystemWindows(Rect insets)方法的insets参数就包含了非内容区域的高度。fitSystemWindows会在加载的时候被调用,如果我们在ListView重 写fitSystemWindows不就可以知道该给ListView添加多高的HeaderView了吗?

但是一般我们不希望这样用 ListView,因为使用重写的ListView的几率实在太大了(下拉刷新ListView等),而采取另外的方法,把ListView和一个重写了 fitSystemWindows方法的FrameLayout放在同一个FrameLayout中,然后通过回调的方式来通知ListView已经获取 到了actionbar(或者+statusbar)的高度了。

我们将这个实现了fitSystemWindows方法的FrameLayout命名为:DrawInsetsFrameLayout

代码如下:

/** Copyright 2014 Google Inc.** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at**     http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/
package com.example.drawinsetsframelayoutdemo;
import <span style="width: auto; height: auto; float: none;" id="6_nwp"><a style="text-decoration: none;" mpid="6" target="_blank" href="http://cpro.baidu.com/cpro/ui/uijs.php?rs=1&u=http%3A%2F%2Fwww%2Ejcodecraeer%2Ecom%2Fa%2Fanzhuokaifa%2Fandroidkaifa%2F2014%2F0930%2F1720%2Ehtml&p=baidu&c=news&n=10&t=tpclicked3_hc&q=01072140_cpr&k=android&k0=android&kdi0=8&k1=style&kdi1=8&sid=1591b71c7abd51a3&ch=0&tu=u1921070&jk=3064ed901c653638&cf=29&rb=0&fv=16&stid=9&urlid=0&luki=1&seller_id=1&di=128" id="6_nwl"><span style="color:#0000ff;font-size:14px;width:auto;height:auto;float:none;">android</span></a></span>.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.FrameLayout;
/*** A layout that draws something in the insets passed to {@link #fitSystemWindows(Rect)}, i.e. the area above UI chrome* (status and navigation bars, overlay action bars).*/
public class DrawInsetsFrameLayout extends FrameLayout {private Drawable mInsetBackground;private Rect mInsets;private Rect mTempRect = new Rect();private OnInsetsCallback mOnInsetsCallback;public DrawInsetsFrameLayout(Context context) {super(context);init(context, null, 0);}public DrawInsetsFrameLayout(Context context, AttributeSet attrs) {super(context, attrs);init(context, attrs, 0);}public DrawInsetsFrameLayout(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);init(context, attrs, defStyle);}private void init(Context context, AttributeSet attrs, int defStyle) {final TypedArray a = context.obtainStyledAttributes(attrs,R.<span style="width: auto; height: auto; float: none;" id="7_nwp"><a style="text-decoration: none;" mpid="7" target="_blank" href="http://cpro.baidu.com/cpro/ui/uijs.php?rs=1&u=http%3A%2F%2Fwww%2Ejcodecraeer%2Ecom%2Fa%2Fanzhuokaifa%2Fandroidkaifa%2F2014%2F0930%2F1720%2Ehtml&p=baidu&c=news&n=10&t=tpclicked3_hc&q=01072140_cpr&k=style&k0=android&kdi0=8&k1=style&kdi1=8&sid=1591b71c7abd51a3&ch=0&tu=u1921070&jk=3064ed901c653638&cf=29&rb=0&fv=16&stid=9&urlid=0&luki=2&seller_id=1&di=128" id="7_nwl"><span style="color:#0000ff;font-size:14px;width:auto;height:auto;float:none;">style</span></a></span>able.DrawInsetsFrameLayout, defStyle, 0);if (a == null) {return;}mInsetBackground = a.getDrawable(R.styleable.DrawInsetsFrameLayout_insetBackground);a.recycle();setWillNotDraw(true);}@Overrideprotected boolean fitSystemWindows(Rect insets) {mInsets = new Rect(insets);setWillNotDraw(mInsetBackground == null);postInvalidateOnAnimation();if (mOnInsetsCallback != null) {mOnInsetsCallback.onInsetsChanged(insets);}return true; // consume insets
    }@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);int width = getWidth();int height = getHeight();if (mInsets != null && mInsetBackground != null) {// TopmTempRect.set(0, 0, width, mInsets.top);mInsetBackground.setBounds(mTempRect);mInsetBackground.draw(canvas);// BottommTempRect.set(0, height - mInsets.bottom, width, height);mInsetBackground.setBounds(mTempRect);mInsetBackground.draw(canvas);// LeftmTempRect.set(0, mInsets.top, mInsets.left, height - mInsets.bottom);mInsetBackground.setBounds(mTempRect);mInsetBackground.draw(canvas);// RightmTempRect.set(width - mInsets.right, mInsets.top, width, height - mInsets.bottom);mInsetBackground.setBounds(mTempRect);mInsetBackground.draw(canvas);}}@Overrideprotected void onAttachedToWindow() {super.onAttachedToWindow();if (mInsetBackground != null) {mInsetBackground.setCallback(this);}}@Overrideprotected void onDetachedFromWindow() {super.onDetachedFromWindow();if (mInsetBackground != null) {mInsetBackground.setCallback(null);}}/*** Allows the calling container to specify a callback for custom processing when insets change (i.e. when* {@link #fitSystemWindows(Rect)} is called. This is useful for setting padding on UI elements based on* UI chrome insets (e.g. a Google Map or a ListView). When using with ListView or GridView, remember to set* clipToPadding to false.*/public void setOnInsetsCallback(OnInsetsCallback onInsetsCallback) {mOnInsetsCallback = onInsetsCallback;}public static interface OnInsetsCallback {public void onInsetsChanged(Rect insets);}
}

其中最主要的就是fitSystemWindows方法,其他的不过是绘制DrawInsetsFrameLayout在actionbar部分的显示颜色而已。

如何使用DrawInsetsFrameLayout呢?

package com.example.drawinsetsframelayoutdemo;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import <span style="width: auto; height: auto; float: none;" id="5_nwp"><a style="text-decoration: none;" mpid="5" target="_blank" href="http://cpro.baidu.com/cpro/ui/uijs.php?rs=1&u=http%3A%2F%2Fwww%2Ejcodecraeer%2Ecom%2Fa%2Fanzhuokaifa%2Fandroidkaifa%2F2014%2F0930%2F1720%2Ehtml&p=baidu&c=news&n=10&t=tpclicked3_hc&q=01072140_cpr&k=android&k0=android&kdi0=8&k1=style&kdi1=8&sid=1591b71c7abd51a3&ch=0&tu=u1921070&jk=3064ed901c653638&cf=29&rb=0&fv=16&stid=9&urlid=0&luki=1&seller_id=1&di=128" id="5_nwl"><span style="color:#0000ff;font-size:14px;width:auto;height:auto;float:none;">android</span></a></span>.app.Activity;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.view.ViewGroup.LayoutParams;
import android.widget.AbsListView;
import android.widget.ListView;
import android.widget.SimpleAdapter;
public class MainActivity extends Activity {private ListView listView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);listView= (ListView) findViewById(R.id.listview);String[] from = { "Text", "Button" };int[] to = { R.id.text, R.id.button };List<Map<String, ?>> list = new ArrayList<Map<String, ?>>();for (int i = 0; i < 103; i++) {Map<String, String> m = new HashMap<String, String>();m.put("Text", "Text" + i);m.put("Button", "Button" + i);list.add(m);}SimpleAdapter adapter = new SimpleAdapter(this, list, R.layout.listitem, from, to);listView.setAdapter(adapter);DrawInsetsFrameLayout drawInsetsFrameLayout = (DrawInsetsFrameLayout) findViewById(R.id.my_draw_insets_layout);drawInsetsFrameLayout.setOnInsetsCallback(new DrawInsetsFrameLayout.OnInsetsCallback() {@Overridepublic void onInsetsChanged(Rect insets) {// Update the map padding (inset the compass, zoom buttons, attribution, etc.)Log.i("", "insets.top = " + insets.top);View headerView = new View(MainActivity.this);AbsListView.LayoutParams params = new AbsListView.LayoutParams(LayoutParams.FILL_PARENT, insets.top);headerView.setLayoutParams(params);headerView.setBackgroundColor(0x33000000);listView.addHeaderView(headerView);}});}}

设置actionbar风格的xml文件:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:<span style="width: auto; height: auto; float: none;" id="1_nwp"><a style="text-decoration: none;" mpid="1" target="_blank" href="http://cpro.baidu.com/cpro/ui/uijs.php?rs=1&u=http%3A%2F%2Fwww%2Ejcodecraeer%2Ecom%2Fa%2Fanzhuokaifa%2Fandroidkaifa%2F2014%2F0930%2F1720%2Ehtml&p=baidu&c=news&n=10&t=tpclicked3_hc&q=01072140_cpr&k=android&k0=android&kdi0=8&k1=style&kdi1=8&sid=1591b71c7abd51a3&ch=0&tu=u1921070&jk=3064ed901c653638&cf=29&rb=0&fv=16&stid=9&urlid=0&luki=1&seller_id=1&di=128" id="1_nwl"><span style="color:#0000ff;font-size:14px;width:auto;height:auto;float:none;">android</span></a></span>="http://schemas.android.com/apk/res/android"xmlns:yourapp="http://schemas.android.com/apk/res-auto"android:layout_width="fill_parent"android:layout_height="fill_parent"><ListViewandroid:id="@+id/listview"android:layout_width="match_parent"android:layout_height="match_parent"/><com.example.drawinsetsframelayoutdemo.DrawInsetsFrameLayout<span style="width: auto; height: auto; float: none;" id="2_nwp"><a style="text-decoration: none;" mpid="2" target="_blank" href="http://cpro.baidu.com/cpro/ui/uijs.php?rs=1&u=http%3A%2F%2Fwww%2Ejcodecraeer%2Ecom%2Fa%2Fanzhuokaifa%2Fandroidkaifa%2F2014%2F0930%2F1720%2Ehtml&p=baidu&c=news&n=10&t=tpclicked3_hc&q=01072140_cpr&k=android&k0=android&kdi0=8&k1=style&kdi1=8&sid=1591b71c7abd51a3&ch=0&tu=u1921070&jk=3064ed901c653638&cf=29&rb=0&fv=16&stid=9&urlid=0&luki=1&seller_id=1&di=128" id="2_nwl"><span style="color:#0000ff;font-size:14px;width:auto;height:auto;float:none;">android</span></a></span>:id="@+id/my_draw_insets_layout"android:layout_width="match_parent"android:layout_height="match_parent"yourapp:insetBackground="#9000" />
</FrameLayout>

效果图:

转载于:https://www.cnblogs.com/zhujiabin/p/4251085.html

Android ActionBar的Overlay模式如何不遮盖顶部内容的问题相关推荐

  1. Android actionBar与Fragment结合使用Demo2

    上一篇文章介绍了ActionBar的使用,这里介绍ActionBar的还有一种用法.达到的效果和曾经的GroupActivity或TabHost是一样的,可作为导航来使用. 实现效果图: 源码: 布局 ...

  2. android actionbar tab,ActionBar+Fragment实现Tab

    还是从Tab的几个组成部分来分析:Tab标签页(ActionBar.Tab),Tab所切换内容部分content( Fragment实现) 1.新建每个Fragment, layout,Tab的内容部 ...

  3. Android freeform多窗口模式和Desktop电脑模式使能

    Android freeform多窗口模式和Desktop电脑模式使能相关code: DecorView DecorCaptionView ActivityTaskManagerService 即AT ...

  4. android action bar 风格,Android ActionBar使用教程

    ActionBar的引入方式: 有几种,从 Android 3.0(API lever 11) 开始,所有使用 Theme.Holo 主题(或者它的子类)的 Activity 都包含了 action ...

  5. Android ActionBar完全解析,使用官方推荐的最佳导航栏(下) .

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/25466665 本篇文章主要内容来自于Android Doc,我翻译之后又做了些加工 ...

  6. 无法为新的Android ActionBar支持找到Theme.AppCompat.Light

    本文翻译自:Can't Find Theme.AppCompat.Light for New Android ActionBar Support I am trying to implement th ...

  7. Android ActionBar完全解析,使用官方推荐的最佳导航栏(下)

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/25466665 本篇文章主要内容来自于Android Doc,我翻译之后又做了些加工 ...

  8. Android ActionBar完全解析,使用官方推荐的最佳导航栏(上)

    本篇文章主要内容来自于Android Doc,我翻译之后又做了些加工,英文好的朋友也可以直接去读原文. http://developer.android.com/guide/topics/ui/act ...

  9. 范例解析:学习Android的IPC主板模式

    一.认识Android的IPC主板模式 系统架构设计最关键的任务就是组合(或称整合),而且最好是能与众不同.深具创新性组合.Android就擅用了主板模式,以通用性接口实践跨进程的IPC通信机制.由于 ...

最新文章

  1. java异步执行任务
  2. vs2008.net 单元测试NUnit
  3. Orleans MultiClient 多个Silo复合客户端
  4. 【测试】使用Fiddler4实现手机抓包
  5. 单片机跑马灯代码示例
  6. OBJ格式模型详细介绍
  7. 怎么复制黑苹果config配置_Catia中端电脑配置推荐(黑苹果)
  8. linux查看cpu与内存
  9. alter table添加表约束
  10. 笔记本创建wifi热点
  11. linux gpu 地址空间,显卡内存和进程的虚拟地址空间
  12. 写一段vba代码,把excel中所有工作簿中的图片删除
  13. C语言初步入门学习大略
  14. 用计算机电脑怎么做ppt软件,电脑做ppt的软件叫什么
  15. vue文件下载:把文件流保存到本地
  16. 小程序商城制作一个需要多少钱?一般包括哪些费用?
  17. 自己理解三叉树TernarySearchTrie
  18. 平安好医生技术栈的分析
  19. CRM数据分析是什么
  20. gensim相关功能函数及其案例

热门文章

  1. 访问某个xml的url并将网页转成字节流
  2. 写篇技术博客被简书锁定是一种什么样的体验
  3. 感谢贫穷,是贫穷限制了人们的善良
  4. Hough(霍夫变换) 基于Opencv2.4.9 和VS2012平台下编写
  5. java非负整数怎么设_使用JAVA将非负十进制整数n转换成b进制,递归方法与非递归方法...
  6. JVM的7种垃圾收集器
  7. 4个不错的Flash开源项目
  8. 去掉图片黑背景输出为透明png(算法和工具)
  9. Visual C# 资源文件编程--使用资源文件
  10. Spark的三种运行模式