[XDA-University] Ticklefish:
*** How To Center The Clock In The Status Bar...Part 1 ***​

(I first wrote about this on the 12th of July, 2012...as you might have guessed!)​

Centering the clock in the status bar is one of the most popular XML mods in xda. It may seem like it's really difficult to do, but it's actually incredibly easy.

As long as you read this post, that is...

We're going to change the status bar which is part of the System User Interface, so we need to edit status_bar.xml in SystemUI.apk.

(As in the previous post, this isn't 100% certain. If you're using a multi-sim device, you might need msim_status_bar.xml. If you're not using a stock rom, you might need to get your XML file from a different apk.)

What I'm about to show you may seem more complicated than anything else I've shown you so far, but it does make sense. As you gain more experience modding XML, it'll start to seem very simple indeed.

So this is the XML that I'm going to be using:

<?xml version="1.0" encoding="utf-8"?>
<com.android.systemui.statusbar.phone.PhoneStatusBarView android:orientation="vertical" android:background="@drawable/status_bar_background" android:focusable="true" android:descendantFocusability="afterDescendants"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui">
<LinearLayout android:orientation="horizontal" android:id="@id/icons" android:paddingLeft="6.0dip" android:paddingRight="6.0dip" android:layout_width="fill_parent" android:layout_height="fill_parent">
<LinearLayout android:orientation="horizontal" android:layout_width="0.0dip" android:layout_height="fill_parent" android:layout_weight="1.0">
<com.android.systemui.statusbar.StatusBarIconView android:id="@id/moreIcon" android:layout_width="@dimen/status_bar_icon_size" android:layout_height="fill_parent" android:visibility="gone" android:src="@drawable/stat_notify_more" />
<com.android.systemui.statusbar.phone.IconMerger android:orientation="horizontal" android:id="@id/notificationIcons" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center_vertical" android:layout_alignParentLeft="true" />
</LinearLayout>
<LinearLayout android:orientation="horizontal" android:id="@id/statusIcons" android:layout_width="wrap_content" android:layout_height="fill_parent" android:gravity="center_vertical" />
<ImageView android:id="@id/stat_no_sim" android:paddingLeft="4.0dip" android:layout_width="wrap_content" android:layout_height="wrap_content" android:visibility="gone" android:layout_gravity="center_vertical" />
<LinearLayout android:orientation="horizontal" android:id="@id/signal_battery_cluster" android:paddingLeft="2.0dip" android:layout_width="wrap_content" android:layout_height="fill_parent" android:gravity="center">
<include android:id="@id/signal_cluster" android:layout_width="wrap_content" android:layout_height="wrap_content" layout="@layout/signal_cluster_view" />
<ImageView android:id="@id/battery" android:paddingLeft="8.0dip" android:layout_width="wrap_content" android:layout_height="wrap_content" />
</LinearLayout>
<com.android.systemui.statusbar.policy.Clock android:id="@id/clock" android:paddingLeft="6.0dip" android:layout_width="wrap_content" android:layout_height="fill_parent" android:gravity="left|center" android:textAppearance="@style/TextAppearance.StatusBar.Clock" android:singleLine="true" />
</LinearLayout>
<LinearLayout android:orientation="horizontal" android:id="@id/ticker" android:paddingLeft="6.0dip" android:layout_width="fill_parent" android:layout_height="fill_parent" android:animationCache="false">
<ImageSwitcher android:id="@id/tickerIcon" android:layout_width="@dimen/status_bar_icon_size" android:layout_height="@dimen/status_bar_icon_size" android:layout_marginRight="4.0dip">
<com.android.systemui.statusbar.AnimatedImageView android:layout_width="@dimen/status_bar_icon_size" android:layout_height="@dimen/status_bar_icon_size" android:scaleType="center" />
<com.android.systemui.statusbar.AnimatedImageView android:layout_width="@dimen/status_bar_icon_size" android:layout_height="@dimen/status_bar_icon_size" android:scaleType="center" />
</ImageSwitcher>
<com.android.systemui.statusbar.phone.TickerView android:id="@id/tickerText" android:paddingRight="10.0dip" android:layout_width="0.0dip" android:layout_height="wrap_content" android:layout_weight="1.0" android:paddingTop="2.0dip">
<TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:textAppearance="@style/TextAppearance.StatusBar.PhoneTicker" android:singleLine="true" />
<TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:textAppearance="@style/TextAppearance.StatusBar.PhoneTicker" android:singleLine="true" />
</com.android.systemui.statusbar.phone.TickerView>
</LinearLayout>
</com.android.systemui.statusbar.phone.PhoneStatusBarView>

This is stock Xperia Ice-Cream Sandwich XML but you can do this mod on any version of Android from Eclair to Lollipop. (And possibly Cupcake and Donut too if anybody still uses those...)

And you can do this mod on nearly any rom as well. It's that simple.

The part of this XML that we want to affect is the part that contains what we normally see on the status bar. In the code above, this is the @id/icons LinearLayout:

<LinearLayout android:orientation="horizontal" android:id="@id/icons" android:paddingLeft="6.0dip" android:paddingRight="6.0dip" android:layout_width="fill_parent" android:layout_height="fill_parent">
<LinearLayout android:orientation="horizontal" android:layout_width="0.0dip" android:layout_height="fill_parent" android:layout_weight="1.0">
<com.android.systemui.statusbar.StatusBarIconView android:id="@id/moreIcon" android:layout_width="@dimen/status_bar_icon_size" android:layout_height="fill_parent" android:visibility="gone" android:src="@drawable/stat_notify_more" />
<com.android.systemui.statusbar.phone.IconMerger android:orientation="horizontal" android:id="@id/notificationIcons" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center_vertical" android:layout_alignParentLeft="true" />
</LinearLayout>
<LinearLayout android:orientation="horizontal" android:id="@id/statusIcons" android:layout_width="wrap_content" android:layout_height="fill_parent" android:gravity="center_vertical" />
<ImageView android:id="@id/stat_no_sim" android:paddingLeft="4.0dip" android:layout_width="wrap_content" android:layout_height="wrap_content" android:visibility="gone" android:layout_gravity="center_vertical" />
<LinearLayout android:orientation="horizontal" android:id="@id/signal_battery_cluster" android:paddingLeft="2.0dip" android:layout_width="wrap_content" android:layout_height="fill_parent" android:gravity="center">
<include android:id="@id/signal_cluster" android:layout_width="wrap_content" android:layout_height="wrap_content" layout="@layout/signal_cluster_view" />
<ImageView android:id="@id/battery" android:paddingLeft="8.0dip" android:layout_width="wrap_content" android:layout_height="wrap_content" />
</LinearLayout>
<com.android.systemui.statusbar.policy.Clock android:id="@id/clock" android:paddingLeft="6.0dip" android:layout_width="wrap_content" android:layout_height="fill_parent" android:gravity="left|center" android:textAppearance="@style/TextAppearance.StatusBar.Clock" android:singleLine="true" />
</LinearLayout>

The @id/ticker LinearLayout controls what is seen on the status bar when you get a notification. We don't need to worry about that...yet...

*** The Simple Method ***​

This was first pointed out to me by my good friend and very skilled developer [MENTION=3989065]serajr[/MENTION], so big thanks to him.

The Simple Method is very simple, very quick and is very easy to do. But it does have one slight flaw which I'll mention later..

This is the clock code:

<com.android.systemui.statusbar.policy.Clock
android:id="@id/clock"
[color="red"]android:paddingLeft="6.0dip"
android:layout_width="wrap_content"[/color]
android:layout_height="fill_parent"
[color="red"]android:gravity="left|center"[/color]
android:textAppearance="@style/TextAppearance.StatusBar.Clock"
android:singleLine="true"
/>

The first part of the Simple Method is to change the width of the space this clock occupies and how it's positioned. This is done by editing the red lines like this:

<com.android.systemui.statusbar.policy.Clock
android:id="@id/clock"
[color="red"]android:layout_width="fill_parent"[/color]
android:layout_height="fill_parent"
[color="red"]android:gravity="center"[/color]
android:textAppearance="@style/TextAppearance.StatusBar.Clock"
android:singleLine="true"
/>

Then we need to move the clock line to outside this Layout. The reason for that is centering anything inside a LinearLayout is

very

difficult.

It's not impossible though as we'll see in the next Method.

So our @id/icons Layout now looks like this:

[COLOR=red]<com.android.systemui.statusbar.policy.Clock android:id="@id/clock" android:paddingLeft="6.0dip" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center" android:textAppearance="@style/TextAppearance.StatusBar.Clock" android:singleLine="true" />[/COLOR]
<LinearLayout android:orientation="horizontal" android:id="@id/icons" android:paddingLeft="6.0dip" android:paddingRight="6.0dip" android:layout_width="fill_parent" android:layout_height="fill_parent">
<LinearLayout android:orientation="horizontal" android:layout_width="0.0dip" android:layout_height="fill_parent" android:layout_weight="1.0">
<com.android.systemui.statusbar.StatusBarIconView android:id="@id/moreIcon" android:layout_width="@dimen/status_bar_icon_size" android:layout_height="fill_parent" android:visibility="gone" android:src="@drawable/stat_notify_more" />
<com.android.systemui.statusbar.phone.IconMerger android:orientation="horizontal" android:id="@id/notificationIcons" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center_vertical" android:layout_alignParentLeft="true" />
</LinearLayout>
<LinearLayout android:orientation="horizontal" android:id="@id/statusIcons" android:layout_width="wrap_content" android:layout_height="fill_parent" android:gravity="center_vertical" />
<ImageView android:id="@id/stat_no_sim" android:paddingLeft="4.0dip" android:layout_width="wrap_content" android:layout_height="wrap_content" android:visibility="gone" android:layout_gravity="center_vertical" />
<LinearLayout android:orientation="horizontal" android:id="@id/signal_battery_cluster" android:paddingLeft="2.0dip" android:layout_width="wrap_content" android:layout_height="fill_parent" android:gravity="center">
<include android:id="@id/signal_cluster" android:layout_width="wrap_content" android:layout_height="wrap_content" layout="@layout/signal_cluster_view" />
<ImageView android:id="@id/battery" android:paddingLeft="8.0dip" android:layout_width="wrap_content" android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>

Our clock now occupies the whole statusbar and, because of its gravity attribute, sits in the exact middle of it.

​

So far so good, but there is a problem.

All the contents of the "@id/icons" LinearLayout are pushed out of the top of the screen when a notification comes in..but the clock now isn't part of that, so it won't and we get overlapping. The notification text can't be seen properly and it looks stupid.

​

To fix this, we need to add a background to the "@id/ticker" LinearLayout. This will cover up the clock when there's a new notification and we get no overlapping. We'll use the same background as the normal status bar, defined at the top of the xml, but you could make it anything if you want to be artistic.

So the new code looks like this:

<com.android.systemui.statusbar.policy.Clock android:id="@id/clock" android:paddingLeft="6.0dip" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center" android:textAppearance="@style/TextAppearance.StatusBar.Clock" android:singleLine="true" />
<LinearLayout android:orientation="horizontal" android:id="@id/icons" android:paddingLeft="6.0dip" android:paddingRight="6.0dip" android:layout_width="fill_parent" android:layout_height="fill_parent">
<LinearLayout android:orientation="horizontal" android:layout_width="0.0dip" android:layout_height="fill_parent" android:layout_weight="1.0">
<com.android.systemui.statusbar.StatusBarIconView android:id="@id/moreIcon" android:layout_width="@dimen/status_bar_icon_size" android:layout_height="fill_parent" android:visibility="gone" android:src="@drawable/stat_notify_more" />
<com.android.systemui.statusbar.phone.IconMerger android:orientation="horizontal" android:id="@id/notificationIcons" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center_vertical" android:layout_alignParentLeft="true" />
</LinearLayout>
<LinearLayout android:orientation="horizontal" android:id="@id/statusIcons" android:layout_width="wrap_content" android:layout_height="fill_parent" android:gravity="center_vertical" />
<ImageView android:id="@id/stat_no_sim" android:paddingLeft="4.0dip" android:layout_width="wrap_content" android:layout_height="wrap_content" android:visibility="gone" android:layout_gravity="center_vertical" />
<LinearLayout android:orientation="horizontal" android:id="@id/signal_battery_cluster" android:paddingLeft="2.0dip" android:layout_width="wrap_content" android:layout_height="fill_parent" android:gravity="center">
<include android:id="@id/signal_cluster" android:layout_width="wrap_content" android:layout_height="wrap_content" layout="@layout/signal_cluster_view" />
<ImageView android:id="@id/battery" android:paddingLeft="8.0dip" android:layout_width="wrap_content" android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
<LinearLayout [COLOR=red]android:background="@drawable/status_bar_background"[/COLOR] android:orientation="horizontal" android:id="@id/ticker" android:paddingLeft="6.0dip" android:layout_width="fill_parent" android:layout_height="fill_parent" android:animationCache="false">

This is very quick to do but it doesn't work with a transparent statusbar, since the background would be then transparent and won't blank out the clock.

So it won't work for KitKat and Lollipop either...

Plus, if you want to be fussy, it's not quite a perfect fix as the clock doesn't actually move and the other icons do which can look a little strange. I'm a perfectionist and this always annoyed me.

So that's why there's a second Method we could use instead..