把android 4.2平板的状态栏从底部挪到顶部 NavigationBar
来源:互联网 发布:大数据 智能交通 编辑:程序博客网 时间:2024/05/01 15:05
没在网上搜到相关文章,只能自己动手丰衣足食了,留下足迹以给后来人参考
需要修改的文件:
1、frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\tablet\TabletStatusBar.java
把该文件中类似 Gravity.BOTTOM 都改为 Gravity.TOP
2、frameworks\base\policy\src\com\android\internal\policy\impl\PhoneWindowManager.java
这个文件很重要,很多需要隐藏状态栏的大大们都没有想到隐藏个状态栏还需要改这个东西,造成出现问题:状态栏是隐藏了,可是底部还是有一个黑色条
这个黑色的条其实就是状态栏的位置了
函数 beginLayoutLw
if (mNavigationBarOnBottom) { // It's a system nav bar or a portrait screen; nav bar goes on bottom. int top = displayHeight - mNavigationBarHeightForRotation[displayRotation]; mTmpNavigationFrame.set(0, top, displayWidth, displayHeight); mStableBottom = mStableFullscreenBottom = mTmpNavigationFrame.top; if (navVisible) { mNavigationBar.showLw(true); mDockBottom = mTmpNavigationFrame.top; mRestrictedScreenHeight = mDockBottom - mDockTop; } else { // We currently want to hide the navigation UI. mNavigationBar.hideLw(true); } if (navVisible && !mNavigationBar.isAnimatingLw()) { // If the nav bar is currently requested to be visible, // and not in the process of animating on or off, then // we can tell the app that it is covered by it. mSystemBottom = mTmpNavigationFrame.top; }-》
if (mNavigationBarOnBottom) { // It's a system nav bar or a portrait screen; nav bar goes on bottom. int top = displayHeight - mNavigationBarHeightForRotation[displayRotation]; if (DEBUG_LAYOUT) Log.i(TAG, "mStatusBarHeight: " + mStatusBarHeight+ " mNavBarHeight:"+mNavBarHeight); mTmpNavigationFrame.set(0, 0, displayWidth, mNavBarHeight); mStableTop = mStableFullscreenTop = mTmpNavigationFrame.bottom; if (navVisible) { mNavigationBar.showLw(true); mDockTop = mTmpNavigationFrame.bottom; mRestrictedScreenHeight = mDockBottom - mDockTop; mRestrictedScreenTop = mNavBarHeight; } else { // We currently want to hide the navigation UI. mNavigationBar.hideLw(true); } if (navVisible && !mNavigationBar.isAnimatingLw()) { // If the nav bar is currently requested to be visible, // and not in the process of animating on or off, then // we can tell the app that it is covered by it. mSystemTop = mTmpNavigationFrame.bottom;
其中
mNavBarHeight 是新增的变量可以通过以下方法初始化
mNavBarHeight = mContext.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.navigation_bar_height);
3、frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\tablet\NotificationPanel.java
修改内部类 Choreographer的方法createAnimation 这处修改是为点击notification区域的弹出和隐藏动画的,修改前是向底部隐藏从底部出现,修改后是向顶部隐藏从顶部出现
if (appearing) { // we want to go from near-the-top to the top, unless we're half-open in the right // general vicinity end = 0; if (mNotificationCount == 0) { end += mContentFrameMissingTranslation; } start = HYPERSPACE_OFFRAMP+end; } else { start = y; end = y + HYPERSPACE_OFFRAMP; }
-》
if (appearing) { // we want to go from near-the-top to the top, unless we're half-open in the right // general vicinity end = 0; if (mNotificationCount == 0) { end += mContentFrameMissingTranslation; } start = - HYPERSPACE_OFFRAMP; } else { start = y; end = y - HYPERSPACE_OFFRAMP; }
4、frameworks\base\core\java\android\view\ViewRootImpl.java 这个是为了修改bug: 把状态栏从底部移动到顶部 隐藏状态栏后无法再显示状态栏
if(e1.getY()>dm.heightPixels-GESTURE_AREA_HEIGHT){ float y = e1.getY()-e2.getY();->
if(e1.getY()<GESTURE_AREA_HEIGHT){ float y = e2.getY()-e1.getY();
Index: styles.xml===================================================================--- styles.xml(revision 16)+++ styles.xml(revision 15)@@ -129,16 +129,15 @@ <style name="BrightnessDialogContainer" parent="@style/BaseBrightnessDialogContainer" /> <style name="Animation" />- + <style name="Animation.ShirtPocketPanel">- <item name="android:windowEnterAnimation">@*android:anim/grow_fade_in</item>- <item name="android:windowExitAnimation">@*android:anim/shrink_fade_out</item>+ <item name="android:windowEnterAnimation">@*android:anim/grow_fade_in_from_bottom</item>+ <item name="android:windowExitAnimation">@*android:anim/shrink_fade_out_from_bottom</item> </style> <style name="Animation.RecentPanel">- <item name="android:windowEnterAnimation">@*android:anim/grow_fade_in</item>- <item name="android:windowExitAnimation">@*android:anim/shrink_fade_out</item>+ <item name="android:windowEnterAnimation">@*android:anim/grow_fade_in_from_bottom</item>+ <item name="android:windowExitAnimation">@*android:anim/shrink_fade_out_from_bottom</item> </style> <!-- Standard animations for hiding and showing the status bar. -->@@ -169,7 +168,7 @@ <style name="ClingTitleText"> <item name="android:layout_width">wrap_content</item> <item name="android:layout_height">wrap_content</item>- <item name="android:layout_marginTop">5dp</item>+ <item name="android:layout_marginBottom">5dp</item> <item name="android:textSize">23sp</item> <item name="android:textColor">#49C0EC</item> <item name="android:shadowColor">#000000</item>Index: system_bar_notification_panel.xml===================================================================--- system_bar_notification_panel.xml(revision 16)+++ system_bar_notification_panel.xml(revision 15)@@ -21,16 +21,16 @@ android:id="@+id/content_parent" android:layout_height="match_parent" android:layout_width="match_parent"- android:gravity="right|top"+ android:gravity="right" > <!-- lift the panel up off the status bar while leaving a touchable are --> <Space android:id="@+id/system_bar_notification_panel_bottom_space"- android:layout_height="50dp"+ android:layout_height="56dp" android:layout_width="478dp" android:layout_alignParentRight="true"- android:layout_alignParentTop="true"+ android:layout_alignParentBottom="true" /> <LinearLayout@@ -40,8 +40,8 @@ android:layout_width="478dp" android:orientation="vertical" android:layout_alignParentRight="true"- android:layout_below="@id/system_bar_notification_panel_bottom_space"- android:paddingTop="8dp"+ android:layout_above="@id/system_bar_notification_panel_bottom_space"+ android:paddingBottom="8dp" > <include layout="@layout/system_bar_notification_panel_title"Index: system_bar.xml===================================================================--- system_bar.xml(revision 16)+++ system_bar.xml(revision 15)@@ -23,12 +23,11 @@ android:background="@drawable/system_bar_background" > <FrameLayout android:id="@+id/bar_contents_holder" android:layout_width="match_parent" android:layout_height="@*android:dimen/system_bar_height"- android:layout_gravity="top"+ android:layout_gravity="bottom" > <RelativeLayout android:id="@+id/bar_contents"@@ -136,7 +135,7 @@ android:id="@+id/bar_shadow_holder" android:layout_width="match_parent" android:layout_height="@*android:dimen/system_bar_height"- android:layout_gravity="top"+ android:layout_gravity="bottom" > <!-- lights out shade --> <RelativeLayout@@ -152,7 +151,7 @@ android:layout_height="48dip" android:src="@drawable/ic_sysbar_lights_out_dot_small" android:layout_alignParentLeft="true"- android:layout_alignParentTop="true"+ android:layout_alignParentBottom="true" /> <ImageView android:id="@+id/dot1"@@ -160,7 +159,7 @@ android:layout_height="48dip" android:src="@drawable/ic_sysbar_lights_out_dot_large" android:layout_toRightOf="@+id/dot0"- android:layout_alignParentTop="true"+ android:layout_alignParentBottom="true" /> <ImageView android:id="@+id/dot2"@@ -168,7 +167,7 @@ android:layout_height="48dip" android:src="@drawable/ic_sysbar_lights_out_dot_small" android:layout_toRightOf="@+id/dot1"- android:layout_alignParentTop="true"+ android:layout_alignParentBottom="true" /> <ImageView android:id="@+id/dot3"@@ -176,7 +175,7 @@ android:layout_height="48dip" android:src="@drawable/ic_sysbar_lights_out_dot_small" android:layout_alignParentRight="true"- android:layout_alignParentTop="true"+ android:layout_alignParentBottom="true" /> </RelativeLayout> </FrameLayout>
以下内容转自 : http://blog.csdn.net/yunnywu/article/details/7629760
android4.0系统可以运行于平板电脑和手机上面,这样对于状态栏来说,也是有不同风格的,从SystemUi的代码分类我就可以看出来,google考虑了不同情况下状态栏的显示等,
在源代码里面有这么两个文件夹需要注意:
com.android.systemui.statusbar.phone 这个是针对手机而需要的status bar
com.android.systemui.statusbar.tablet 这个是针对平板电脑而需要的staus bar(system bar)
首先状态栏是如何启动起来的呢?
我们都知道系统刚启动,在SystemServer会加载系统的各种服务,状态栏也不例外,就是在这个时候创建的,代码如下:
SystemServer.java
ActivityManagerService.self().systemReady(new Runnable() {
public void run() {
Slog.i(TAG, "Making services ready");
startSystemUi(contextF);
try {
if (batteryF != null) batteryF.systemReady();
} catch (Throwable e) {
reportWtf("making Battery Service ready", e);
}
static final void startSystemUi(Context context) {
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.android.systemui",
"com.android.systemui.SystemUIService"));
Slog.d(TAG, "Starting service: " + intent);
context.startService(intent);
}
通过上面的代码我就看到系统启动了com.android.systemui.SystemUIService 这个服务,在这个服务里面就会启动状态栏,
但是这里就会有个选择,是启动status bar呢 还是启动 system bar呢,android是这么决定的:
public void onCreate() {
// Pick status bar or system bar.
IWindowManager wm = IWindowManager.Stub.asInterface(
ServiceManager.getService(Context.WINDOW_SERVICE));
try {
SERVICES[0] = wm.canStatusBarHide() (1)
? R.string.config_statusBarComponent(2)
: R.string.config_systemBarComponent;(3)
} catch (RemoteException e) {
Slog.w(TAG, "Failing checking whether status bar can hide", e);
}
final int N = SERVICES.length;
mServices = new SystemUI[N];
for (int i=0; i<N; i++) {
Class cl = chooseClass(SERVICES[i]);
Slog.d(TAG, "loading: " + cl);
try {
mServices[i] = (SystemUI)cl.newInstance();
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (InstantiationException ex) {
throw new RuntimeException(ex);
}
mServices[i].mContext = this;
Slog.d(TAG, "running: " + mServices[i]);
mServices[i].start();
}
}
上面的(1) 出,会调用到phoneWIndowManager里面对应的那个函数,在那里面会根据配置文件,手机宽高等信息来判断使用哪一种bar,代码如下
public boolean canStatusBarHide() {
return mStatusBarCanHide;
}
if (width > height) {
shortSize = height;
.........
} else {
shortSize = width;
.......
}
// Determine whether the status bar can hide based on the size
// of the screen. We assume sizes > 600dp are tablets where we
// will use the system bar.
int shortSizeDp = shortSize
* DisplayMetrics.DENSITY_DEFAULT
/ DisplayMetrics.DENSITY_DEVICE;
mStatusBarCanHide = shortSizeDp < 600;
mStatusBarHeight = mContext.getResources().getDimensionPixelSize(
mStatusBarCanHide
? com.android.internal.R.dimen.status_bar_height
: com.android.internal.R.dimen.system_bar_height);
这里假如手机宽(高) 小于600dp,就认为是手机了,这样mStatusBarHide = true;
我们回到这里
SERVICES[0] = wm.canStatusBarHide()
? R.string.config_statusBarComponent;
: R.string.config_systemBarComponent;
这样SERVICES[0] = R.string.config_statusBarComponent (这个字符串就是 com.anroid.systemui.statusbar.phone)
实际上SERVERCES这个数组里面就两个元素,一个是我们上面的那个com.anroid.systemui.statusbar.phone ,另外一个是PowerUI,这个暂且不管,这个主要是根据电量等信息弹出一些提示框,比如电量低,或者充电器有问题等框。
接下来会调用com.anroid.systemui.statusbar.phone的start方法,注意com.anroid.systemui.statusbar.phone这个类不是一个服务,就是一个普通的类,start方法也是它的一个普通的方法而已。
在start方法里面就会创建状态栏那些界面对应的各种view,包括下拉状态栏后的view等,把这些view都创建好以后,就把这个view加载windowmanager里面就可以了,这样状态栏就可以显示出来了,代码如下:
final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
height,
WindowManager.LayoutParams.TYPE_STATUS_BAR,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
| WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
PixelFormat.OPAQUE);
// the status bar should be in an overlay if possible
final Display defaultDisplay
= ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
.getDefaultDisplay();
if (ActivityManager.isHighEndGfx(defaultDisplay)) {
lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
}
lp.gravity = getStatusBarGravity();
lp.setTitle("StatusBar");
lp.packageName = mContext.getPackageName();
lp.windowAnimations = R.style.Animation_StatusBar;
WindowManagerImpl.getDefault().addView(sb, lp); //这里的sb就是状态栏view
这里需要注意的是 平时看到的状态栏和下拉后的状态栏是两个东西,不要混到一起,而且这里也会创建两个view,一个是普通的状态栏view,另外一个下拉后的view,这两个view都要加载WindosManager里面,添加的代码基本一样,但是最重要的是那个参数里面的type是不一样的,一个是WindowManager.LayoutParams.TYPE_STATUS_BAR,而下拉的那个type是WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL;
- 把android 4.2平板的状态栏从底部挪到顶部 NavigationBar
- Android获取系统顶部状态栏(StatusBar)与底部工具栏(NavigationBar)的高度
- Android全屏(包含3种隐藏顶部状态栏及标题栏和一种隐藏Android 4.0平板底部状态栏的方法)
- Android全屏(包含3种隐藏顶部状态栏及标题栏和一种隐藏Android 4.0平板底部状态栏的方法)
- Android全屏(包含3种隐藏顶部状态栏及标题栏和一种隐藏Android 4.0平板底部状态栏的方法)
- Android全屏(包含3种隐藏顶部状态栏及标题栏和一种隐藏Android 4.0平板底部状态栏的方法)
- Android全屏(包含3种隐藏顶部状态栏及标题栏和一种隐藏Android 4.0平板底部状态栏的方法)
- Android全屏(包含3种隐藏顶部状态栏及标题栏和一种隐藏Android 4.0平板底部状态栏的方法)
- Android全屏(包含3种隐藏顶部状态栏及标题栏和一种隐藏Android 4.0平板底部状态栏的方法)
- 隐藏Android 4.0+平板底部状态栏的方法
- android 状态栏移动到底部
- js实现从底部跳到 顶部
- [Android] ScrollView滚动到底部和顶部的检测
- android去掉滑动到顶部和底部的阴影
- android去掉滑动到顶部和底部的阴影
- android 怎么把状态栏移到底部
- Android 获取系统顶部状态栏高度和底部导航栏的高度
- Android 获取系统顶部状态栏高度和底部导航栏的高度
- 实现冒泡排序、插入排序、选择排序、shell排序
- 动态SQL
- 根据两点经纬度计算距离
- ubuntu查看占用某端口的程序
- 【最长子序列 动态规划】
- 把android 4.2平板的状态栏从底部挪到顶部 NavigationBar
- 函数指针
- SqlDataReader的用法(重点:访问字段的值)
- Android读写文件
- Jboss 进入不了admin console页面的解决办法( Solution: Jboss stuck in loading admin console)
- SITTC教你云计算基础入门(一)
- Win7+Ubuntu双系统,恢复win7
- oracle的rowid和rdba庖丁解牛(不错,desc 包)
- oracle管道(pipelined function)函数用法