FORUMS
Remove All Ads from XDA

XML 101 - XML Modding Made Easy!

5,966 posts
Thanks Meter: 7,305
 
By Ticklefish, Recognized Themer on 5th November 2014, 04:01 PM
Post Reply Email Thread

If you're modding Android, eventually you're going to have to edit some XML.

Want to center the clock in your statusbar? Rearrange the icons in your navbar? Change the layout of your notification screen? Get rid of a carrier label? Change the colour of some text?

Then you need to edit some XML files.

And you might not have any idea how...

Well, don't worry. The purpose of this thread is to show you just easy XML-editing can be. Once you've read it, you'll be one step closer to being an XML expert!

This guide is meant for noobs, experienced modders and everyone in between. Hopefully everybody can learn something..

Here's what this thread has to offer so far:
- Introduction (This Post)

- How To Delete A Line (Yes, Really) - http://forum.xda-developers.com/show...13&postcount=2

- Some Useful Codes To Know - http://forum.xda-developers.com/show...22&postcount=3

- How To Change The Colour Of The Status Bar Clock - http://forum.xda-developers.com/show...23&postcount=4

- How To Put An Invisible Softkey In The Status Bar - http://forum.xda-developers.com/show...35&postcount=5

- How To Center The Clock In The Status Bar...Part 1 - http://forum.xda-developers.com/show...57&postcount=6

- How To Center The Clock In The Status Bar...Part 2 - http://forum.xda-developers.com/show...68&postcount=7

- Centering The Clock In Xperia KitKat - http://forum.xda-developers.com/show...&postcount=297

- android:layout_gravity, android:gravity AND android:layout_weight - http://forum.xda-developers.com/show...80&postcount=8

- Do NOT Edit "public.xml"!! - http://forum.xda-developers.com/show...94&postcount=9
I also encourage others to post guides as well:
- How To Remove "am/pm" From The Clock On Pre-4.2 Roms (by @KronicSkillz) - http://forum.xda-developers.com/show...6&postcount=17
- How To Swap The Notification And Status Bar Icons (by @Anmol0022) - http://forum.xda-developers.com/show...&postcount=115
- How To Hide A Centered Status Bar Clock When A Lollipop Device Is Locked (by @S0bes) - http://forum.xda-developers.com/show...&postcount=172
There will be more coming soon!!


*** What Is XML? ***


'XML' stands for 'eXtensible Markup Language'. But you don't need to know that.

What you need to know is that XML is used by Google to define the layout of Android applications.

Look at your statusbar. It's Java that controls how your statusbar works, but it's XML that controls where everything on it is.

(If you want to edit the Java, you can try building the app from source. Or look at editing smali. Smali is harder to understand than XML but there's a great guide by @Goldie here: http://forum.xda-developers.com/gala...-mods-t2488033)

*** Where Can I Find An App's XML? ***


To edit an app's XML, you first need to be able to access it. To do that, you need to decompile the .apk file. If you don't decompile, any XML you try editing won't work.

There are enough tutorials on xda to tell you how to do this that I don't need to fill up space here telling you about it.
But I always recommend using Tickle My Android (http://forum.xda-developers.com/show....php?t=1633333) for any decompiling and recompiling.

*** What Does XML Look Like? ***


This is the line of XML that displays the clock on my phone's statusbar:

Code:
<com.android.systemui.statusbar.policy.Clock android:textAppearance="@style/TextAppearance.StatusBar.Clock" android:gravity="start|center" android:id="@id/clock" android:layout_width="wrap_content" android:layout_height="fill_parent" android:singleLine="true" android:paddingStart="6.0dip" />
One of the great things about XML is that it ignores whitespace. Or, in other words, we can do stuff like this:

Code:
<com.android.systemui.statusbar.policy.Clock
    android:textAppearance="@style/TextAppearance.StatusBar.Clock"
    android:gravity="start|center"
    android:id="@id/clock"
    android:layout_width="wrap_content"
    android:layout_height="fill_parent"
    android:singleLine="true"
    android:paddingStart="6.0dip"
 />
Looks a bit more sensible, doesn't it? In theory, you can do this to every single line in a XML file but that'd be time-consuming and a bit pointless.

XML consists of two parts: 'tags' and 'attributes'. Google also like to talk about 'Views' and 'ViewGroups', but we won't worry about that for now.

Essentially, a tag is something you see (even if it's invisible) and an attribute affects the way that tag works. Let's look at that code again with the tags and attributes highlighted..

Code:
<com.android.systemui.statusbar.policy.Clock
    android:textAppearance="@style/TextAppearance.StatusBar.Clock"
    android:gravity="start|center"
    android:id="@id/clock"
    android:layout_width="wrap_content"
    android:layout_height="fill_parent"
    android:singleLine="true"
    android:paddingStart="6.0dip"
 />
Hopefully that code is starting to make a bit more sense. If not, don't worry. The more you edit XML, the more you'll understand it.

We can change those attributes, remove some and add others. And at the end of it all, that clock can look completely different.

And that's before we start moving the line to somewhere else in the XML file and adding other tags. With a little work, and a little patience, we can make a massive difference to our Android device.

*** What Do I Need To Know To Start Modding XML Myself? ***


This is the 'status_bar.xml' from my rom. I have an Xperia Z, runnning stock Sony-themed KitKat, modified by myself and this XML file can be found in 'system/priv-app/SystemUI.apk'.

Code:
<?xml version="1.0" encoding="utf-8"?>
<com.android.systemui.statusbar.phone.PhoneStatusBarView android:orientation="vertical" android:id="@id/status_bar" android:background="@drawable/system_bar_background" android:focusable="true" android:fitsSystemWindows="true" android:descendantFocusability="afterDescendants"
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui">
    <FrameLayout android:id="@id/ongoing_call_bg_parent_layout" android:background="@color/ongoing_call_bg_color" android:visibility="gone" android:layout_width="fill_parent" android:layout_height="fill_parent">
        <ImageView android:layout_gravity="left" android:id="@id/ongoing_call_glow" android:layout_width="wrap_content" android:layout_height="wrap_content" />
    </FrameLayout>
    <ImageView android:id="@id/notification_lights_out" android:paddingBottom="2.0dip" android:visibility="gone" android:layout_width="@dimen/status_bar_icon_size" android:layout_height="fill_parent" android:src="@drawable/ic_sysbar_lights_out_dot_small" android:scaleType="center" android:paddingStart="6.0dip" />
    <com.sonymobile.systemui.statusbar.operator.OperatorLabel android:textAppearance="@style/TextAppearance.StatusBar.Clock" android:ellipsize="marquee" android:gravity="start|center" android:id="@id/operator" android:visibility="gone" android:layout_width="wrap_content" android:layout_height="fill_parent" android:singleLine="true" android:paddingStart="6.0dip" android:paddingEnd="4.0dip" />
    <LinearLayout android:orientation="horizontal" android:id="@id/status_bar_contents" android:layout_width="fill_parent" android:layout_height="fill_parent" android:paddingStart="6.0dip" android:paddingEnd="6.0dip">
        <RelativeLayout android:layout_width="fill_parent" android:layout_height="fill_parent">
            <com.panel.Button android:id="@id/button" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_alignParentStart="true" />
            <LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_alignParentStart="true">
                <com.android.systemui.statusbar.StatusBarIconView android:id="@id/moreIcon" android:visibility="gone" android:layout_width="@dimen/status_bar_icon_size" android:layout_height="fill_parent" android:src="@drawable/stat_notify_more" />
                <com.android.systemui.statusbar.phone.IconPartitioner android:id="@id/notification_icon_area" android:layout_width="0.0dip" android:layout_height="fill_parent" android:layout_weight="1.0">
                    <com.android.systemui.statusbar.phone.IconMerger android:gravity="center_vertical" android:orientation="horizontal" android:id="@id/notificationIcons" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_alignParentStart="true" />
                    <LinearLayout android:orientation="horizontal" android:id="@id/system_icon_area" android:layout_width="wrap_content" android:layout_height="fill_parent">
                        <com.panel.Panel android:id="@id/panel" android:layout_width="wrap_content" android:layout_height="fill_parent">
                            <LinearLayout android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="fill_parent" />
                            <LinearLayout android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="fill_parent">
                                <com.android.systemui.statusbar.policy.Traffic android:textAppearance="@style/TextAppearance.StatusBar.Clock" android:gravity="start|center" android:id="@id/traffic" android:layout_width="wrap_content" android:layout_height="fill_parent" android:singleLine="true" />
                            </LinearLayout>
                        </com.panel.Panel>
                        <LinearLayout android:gravity="center_vertical" android:orientation="horizontal" android:id="@id/statusIcons" android:layout_width="wrap_content" android:layout_height="fill_parent" />
                    </LinearLayout>
                </com.android.systemui.statusbar.phone.IconPartitioner>
                <LinearLayout android:gravity="center" android:orientation="horizontal" android:id="@id/signal_battery_cluster" android:layout_width="wrap_content" android:layout_height="fill_parent" android:paddingStart="2.0dip">
                    <include android:id="@id/signal_cluster" android:layout_width="wrap_content" android:layout_height="wrap_content" layout="@layout/signal_cluster_view" />
                    <LinearLayout android:id="@id/battery" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_marginStart="4.0dip">
                        <ImageView android:layout_gravity="center_vertical" android:id="@id/status" android:layout_width="wrap_content" android:layout_height="wrap_content" />
                        <com.erryy.BatteryText android:textAppearance="@style/TextAppearance.StatusBar.Clock" android:gravity="start|center" android:layout_width="wrap_content" android:layout_height="fill_parent" android:paddingStart="1.0dip" />
                        <LinearLayout android:id="@id/battery_meter" android:layout_width="0.0dip" android:layout_height="0.0dip">
                            <ImageView android:layout_gravity="center_vertical" android:id="@id/battery_icon" android:layout_width="wrap_content" android:layout_height="wrap_content" />
                            <ImageView android:layout_gravity="center_vertical" android:id="@id/stamina_icon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/somc_sys_powersaver" />
                        </LinearLayout>
                        <FrameLayout android:id="@id/battery_percent" android:layout_width="wrap_content" android:layout_height="fill_parent">
                            <com.sonymobile.systemui.statusbar.BatteryImage android:layout_gravity="start|center" android:id="@id/battery_percent_bg" android:layout_width="wrap_content" android:layout_height="wrap_content" />
                        </FrameLayout>
                    </LinearLayout>
                </LinearLayout>
                <com.android.systemui.statusbar.policy.Clock android:textAppearance="@style/TextAppearance.StatusBar.Clock" android:gravity="start|center" android:id="@id/clock" android:layout_width="wrap_content" android:layout_height="fill_parent" android:singleLine="true" android:paddingStart="6.0dip" />
            </LinearLayout>
        </RelativeLayout>
    </LinearLayout>
    <LinearLayout android:orientation="horizontal" android:id="@id/ticker" android:animationCache="false" android:layout_width="fill_parent" android:layout_height="fill_parent" android:paddingStart="6.0dip">
        <ImageSwitcher android:id="@id/tickerIcon" android:layout_width="@dimen/status_bar_icon_size" android:layout_height="@dimen/status_bar_icon_size" android:layout_marginEnd="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:paddingTop="2.0dip" android:layout_width="0.0dip" android:layout_height="wrap_content" android:layout_weight="1.0" android:paddingEnd="10.0dip">
            <TextView android:textAppearance="@style/TextAppearance.StatusBar.PhoneTicker" android:layout_width="fill_parent" android:layout_height="wrap_content" android:singleLine="true" android:textAlignment="viewStart" />
            <TextView android:textAppearance="@style/TextAppearance.StatusBar.PhoneTicker" android:layout_width="fill_parent" android:layout_height="wrap_content" android:singleLine="true" android:textAlignment="viewStart" />
        </com.android.systemui.statusbar.phone.TickerView>
    </LinearLayout>
    <ImageView android:layout_gravity="top|left|center" android:id="@id/rounded_corner_ul" android:visibility="gone" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/rounded_corner_ul" />
    <ImageView android:layout_gravity="top|right|center" android:id="@id/rounded_corner_ur" android:visibility="gone" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/rounded_corner_ur" />
</com.android.systemui.statusbar.phone.PhoneStatusBarView>
If you understand every single line, tag and attribute then you can skip the next three posts. You're clearly an expert and I should probably be calling you 'Sir'...

If you don't, then read on. Hopefully you can see that, even though there's a lot of code there, it's all just tags and attributes. That's all that XML is. It's easier than it looks.

I have a few more things to tell you, then I'll show you a few example mods. Then it'd be time for you to practice editing XML for yourself.
The Following 69 Users Say Thank You to Ticklefish For This Useful Post: [ View ] Gift Ticklefish Ad-Free
 
 
5th November 2014, 04:03 PM |#2  
*** How To Delete A Line (Yes, Really) ***


That's right.

I'm dedicating an entire post to teach you how to use the DELETE button.

I'm nuts, right?

Actually...no. (Although my therapist would disagree!)

Let's have a look at that status_bar.xml again:

Code:
<?xml version="1.0" encoding="utf-8"?>
<com.android.systemui.statusbar.phone.PhoneStatusBarView android:orientation="vertical" android:id="@id/status_bar" android:background="@drawable/system_bar_background" android:focusable="true" android:fitsSystemWindows="true" android:descendantFocusability="afterDescendants"
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui">
    <FrameLayout android:id="@id/ongoing_call_bg_parent_layout" android:background="@color/ongoing_call_bg_color" android:visibility="gone" android:layout_width="fill_parent" android:layout_height="fill_parent">
        <ImageView android:layout_gravity="left" android:id="@id/ongoing_call_glow" android:layout_width="wrap_content" android:layout_height="wrap_content" />
    </FrameLayout>
    <ImageView android:id="@id/notification_lights_out" android:paddingBottom="2.0dip" android:visibility="gone" android:layout_width="@dimen/status_bar_icon_size" android:layout_height="fill_parent" android:src="@drawable/ic_sysbar_lights_out_dot_small" android:scaleType="center" android:paddingStart="6.0dip" />
    <com.sonymobile.systemui.statusbar.operator.OperatorLabel android:textAppearance="@style/TextAppearance.StatusBar.Clock" android:ellipsize="marquee" android:gravity="start|center" android:id="@id/operator" android:visibility="gone" android:layout_width="wrap_content" android:layout_height="fill_parent" android:singleLine="true" android:paddingStart="6.0dip" android:paddingEnd="4.0dip" />
    <LinearLayout android:orientation="horizontal" android:id="@id/status_bar_contents" android:layout_width="fill_parent" android:layout_height="fill_parent" android:paddingStart="6.0dip" android:paddingEnd="6.0dip">
        <RelativeLayout android:layout_width="fill_parent" android:layout_height="fill_parent">
            <com.panel.Button android:id="@id/button" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_alignParentStart="true" />
            <LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_alignParentStart="true">
                <com.android.systemui.statusbar.StatusBarIconView android:id="@id/moreIcon" android:visibility="gone" android:layout_width="@dimen/status_bar_icon_size" android:layout_height="fill_parent" android:src="@drawable/stat_notify_more" />
                <com.android.systemui.statusbar.phone.IconPartitioner android:id="@id/notification_icon_area" android:layout_width="0.0dip" android:layout_height="fill_parent" android:layout_weight="1.0">
                    <com.android.systemui.statusbar.phone.IconMerger android:gravity="center_vertical" android:orientation="horizontal" android:id="@id/notificationIcons" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_alignParentStart="true" />
                    <LinearLayout android:orientation="horizontal" android:id="@id/system_icon_area" android:layout_width="wrap_content" android:layout_height="fill_parent">
                        <com.panel.Panel android:id="@id/panel" android:layout_width="wrap_content" android:layout_height="fill_parent">
                            <LinearLayout android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="fill_parent" />
                            <LinearLayout android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="fill_parent">
                                <com.android.systemui.statusbar.policy.Traffic android:textAppearance="@style/TextAppearance.StatusBar.Clock" android:gravity="start|center" android:id="@id/traffic" android:layout_width="wrap_content" android:layout_height="fill_parent" android:singleLine="true" />
                            </LinearLayout>
                        </com.panel.Panel>
                        <LinearLayout android:gravity="center_vertical" android:orientation="horizontal" android:id="@id/statusIcons" android:layout_width="wrap_content" android:layout_height="fill_parent" />
                    </LinearLayout>
                </com.android.systemui.statusbar.phone.IconPartitioner>
                <LinearLayout android:gravity="center" android:orientation="horizontal" android:id="@id/signal_battery_cluster" android:layout_width="wrap_content" android:layout_height="fill_parent" android:paddingStart="2.0dip">
                    <include android:id="@id/signal_cluster" android:layout_width="wrap_content" android:layout_height="wrap_content" layout="@layout/signal_cluster_view" />
                    <LinearLayout android:id="@id/battery" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_marginStart="4.0dip">
                        <ImageView android:layout_gravity="center_vertical" android:id="@id/status" android:layout_width="wrap_content" android:layout_height="wrap_content" />
                        <com.erryy.BatteryText android:textAppearance="@style/TextAppearance.StatusBar.Clock" android:gravity="start|center" android:layout_width="wrap_content" android:layout_height="fill_parent" android:paddingStart="1.0dip" />
                        <LinearLayout android:id="@id/battery_meter" android:layout_width="0.0dip" android:layout_height="0.0dip">
                            <ImageView android:layout_gravity="center_vertical" android:id="@id/battery_icon" android:layout_width="wrap_content" android:layout_height="wrap_content" />
                            <ImageView android:layout_gravity="center_vertical" android:id="@id/stamina_icon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/somc_sys_powersaver" />
                        </LinearLayout>
                        <FrameLayout android:id="@id/battery_percent" android:layout_width="wrap_content" android:layout_height="fill_parent">
                            <com.sonymobile.systemui.statusbar.BatteryImage android:layout_gravity="start|center" android:id="@id/battery_percent_bg" android:layout_width="wrap_content" android:layout_height="wrap_content" />
                        </FrameLayout>
                    </LinearLayout>
                </LinearLayout>
                <com.android.systemui.statusbar.policy.Clock android:textAppearance="@style/TextAppearance.StatusBar.Clock" android:gravity="start|center" android:id="@id/clock" android:layout_width="wrap_content" android:layout_height="fill_parent" android:singleLine="true" android:paddingStart="6.0dip" />
            </LinearLayout>
        </RelativeLayout>
    </LinearLayout>
    <LinearLayout android:orientation="horizontal" android:id="@id/ticker" android:animationCache="false" android:layout_width="fill_parent" android:layout_height="fill_parent" android:paddingStart="6.0dip">
        <ImageSwitcher android:id="@id/tickerIcon" android:layout_width="@dimen/status_bar_icon_size" android:layout_height="@dimen/status_bar_icon_size" android:layout_marginEnd="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:paddingTop="2.0dip" android:layout_width="0.0dip" android:layout_height="wrap_content" android:layout_weight="1.0" android:paddingEnd="10.0dip">
            <TextView android:textAppearance="@style/TextAppearance.StatusBar.PhoneTicker" android:layout_width="fill_parent" android:layout_height="wrap_content" android:singleLine="true" android:textAlignment="viewStart" />
            <TextView android:textAppearance="@style/TextAppearance.StatusBar.PhoneTicker" android:layout_width="fill_parent" android:layout_height="wrap_content" android:singleLine="true" android:textAlignment="viewStart" />
        </com.android.systemui.statusbar.phone.TickerView>
    </LinearLayout>
    <ImageView android:layout_gravity="top|left|center" android:id="@id/rounded_corner_ul" android:visibility="gone" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/rounded_corner_ul" />
    <ImageView android:layout_gravity="top|right|center" android:id="@id/rounded_corner_ur" android:visibility="gone" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/rounded_corner_ur" />
</com.android.systemui.statusbar.phone.PhoneStatusBarView>
This is the XML that defines the layout of my phone's statusbar. Let's say that I wanted to stop the status icons from showing. That's the line in red above.

I'd just delete it right?

Code:
<?xml version="1.0" encoding="utf-8"?>
<com.android.systemui.statusbar.phone.PhoneStatusBarView android:orientation="vertical" android:id="@id/status_bar" android:background="@drawable/system_bar_background" android:focusable="true" android:fitsSystemWindows="true" android:descendantFocusability="afterDescendants"
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui">
    <FrameLayout android:id="@id/ongoing_call_bg_parent_layout" android:background="@color/ongoing_call_bg_color" android:visibility="gone" android:layout_width="fill_parent" android:layout_height="fill_parent">
        <ImageView android:layout_gravity="left" android:id="@id/ongoing_call_glow" android:layout_width="wrap_content" android:layout_height="wrap_content" />
    </FrameLayout>
    <ImageView android:id="@id/notification_lights_out" android:paddingBottom="2.0dip" android:visibility="gone" android:layout_width="@dimen/status_bar_icon_size" android:layout_height="fill_parent" android:src="@drawable/ic_sysbar_lights_out_dot_small" android:scaleType="center" android:paddingStart="6.0dip" />
    <com.sonymobile.systemui.statusbar.operator.OperatorLabel android:textAppearance="@style/TextAppearance.StatusBar.Clock" android:ellipsize="marquee" android:gravity="start|center" android:id="@id/operator" android:visibility="gone" android:layout_width="wrap_content" android:layout_height="fill_parent" android:singleLine="true" android:paddingStart="6.0dip" android:paddingEnd="4.0dip" />
    <LinearLayout android:orientation="horizontal" android:id="@id/status_bar_contents" android:layout_width="fill_parent" android:layout_height="fill_parent" android:paddingStart="6.0dip" android:paddingEnd="6.0dip">
        <RelativeLayout android:layout_width="fill_parent" android:layout_height="fill_parent">
            <com.panel.Button android:id="@id/button" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_alignParentStart="true" />
            <LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_alignParentStart="true">
                <com.android.systemui.statusbar.StatusBarIconView android:id="@id/moreIcon" android:visibility="gone" android:layout_width="@dimen/status_bar_icon_size" android:layout_height="fill_parent" android:src="@drawable/stat_notify_more" />
                <com.android.systemui.statusbar.phone.IconPartitioner android:id="@id/notification_icon_area" android:layout_width="0.0dip" android:layout_height="fill_parent" android:layout_weight="1.0">
                    <com.android.systemui.statusbar.phone.IconMerger android:gravity="center_vertical" android:orientation="horizontal" android:id="@id/notificationIcons" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_alignParentStart="true" />
                    <LinearLayout android:orientation="horizontal" android:id="@id/system_icon_area" android:layout_width="wrap_content" android:layout_height="fill_parent">
                        <com.panel.Panel android:id="@id/panel" android:layout_width="wrap_content" android:layout_height="fill_parent">
                            <LinearLayout android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="fill_parent" />
                            <LinearLayout android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="fill_parent">
                                <com.android.systemui.statusbar.policy.Traffic android:textAppearance="@style/TextAppearance.StatusBar.Clock" android:gravity="start|center" android:id="@id/traffic" android:layout_width="wrap_content" android:layout_height="fill_parent" android:singleLine="true" />
                            </LinearLayout>
                        </com.panel.Panel>
                        <LinearLayout android:gravity="center_vertical" android:orientation="horizontal" android:id="@id/statusIcons" android:layout_width="wrap_content" android:layout_height="fill_parent" />
                    </LinearLayout>
                </com.android.systemui.statusbar.phone.IconPartitioner>
                <LinearLayout android:gravity="center" android:orientation="horizontal" android:id="@id/signal_battery_cluster" android:layout_width="wrap_content" android:layout_height="fill_parent" android:paddingStart="2.0dip">
                    <include android:id="@id/signal_cluster" android:layout_width="wrap_content" android:layout_height="wrap_content" layout="@layout/signal_cluster_view" />
                    <LinearLayout android:id="@id/battery" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_marginStart="4.0dip">
                        <com.erryy.BatteryText android:textAppearance="@style/TextAppearance.StatusBar.Clock" android:gravity="start|center" android:layout_width="wrap_content" android:layout_height="fill_parent" android:paddingStart="1.0dip" />
                        <LinearLayout android:id="@id/battery_meter" android:layout_width="0.0dip" android:layout_height="0.0dip">
                            <ImageView android:layout_gravity="center_vertical" android:id="@id/battery_icon" android:layout_width="wrap_content" android:layout_height="wrap_content" />
                            <ImageView android:layout_gravity="center_vertical" android:id="@id/stamina_icon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/somc_sys_powersaver" />
                        </LinearLayout>
                        <FrameLayout android:id="@id/battery_percent" android:layout_width="wrap_content" android:layout_height="fill_parent">
                            <com.sonymobile.systemui.statusbar.BatteryImage android:layout_gravity="start|center" android:id="@id/battery_percent_bg" android:layout_width="wrap_content" android:layout_height="wrap_content" />
                        </FrameLayout>
                    </LinearLayout>
                </LinearLayout>
                <com.android.systemui.statusbar.policy.Clock android:textAppearance="@style/TextAppearance.StatusBar.Clock" android:gravity="start|center" android:id="@id/clock" android:layout_width="wrap_content" android:layout_height="fill_parent" android:singleLine="true" android:paddingStart="6.0dip" />
            </LinearLayout>
        </RelativeLayout>
    </LinearLayout>
    <LinearLayout android:orientation="horizontal" android:id="@id/ticker" android:animationCache="false" android:layout_width="fill_parent" android:layout_height="fill_parent" android:paddingStart="6.0dip">
        <ImageSwitcher android:id="@id/tickerIcon" android:layout_width="@dimen/status_bar_icon_size" android:layout_height="@dimen/status_bar_icon_size" android:layout_marginEnd="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:paddingTop="2.0dip" android:layout_width="0.0dip" android:layout_height="wrap_content" android:layout_weight="1.0" android:paddingEnd="10.0dip">
            <TextView android:textAppearance="@style/TextAppearance.StatusBar.PhoneTicker" android:layout_width="fill_parent" android:layout_height="wrap_content" android:singleLine="true" android:textAlignment="viewStart" />
            <TextView android:textAppearance="@style/TextAppearance.StatusBar.PhoneTicker" android:layout_width="fill_parent" android:layout_height="wrap_content" android:singleLine="true" android:textAlignment="viewStart" />
        </com.android.systemui.statusbar.phone.TickerView>
    </LinearLayout>
    <ImageView android:layout_gravity="top|left|center" android:id="@id/rounded_corner_ul" android:visibility="gone" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/rounded_corner_ul" />
    <ImageView android:layout_gravity="top|right|center" android:id="@id/rounded_corner_ur" android:visibility="gone" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/rounded_corner_ur" />
</com.android.systemui.statusbar.phone.PhoneStatusBarView>
No.

Try this and as soon as Android tries to run your modified apk, it'll FC. Even if that's the only change that you've made to it.

Why?

Well, it's not because you deleted the status icon line...it's because you deleted the line's 'id'

Let's have another look at the status icon line:

Code:
<ImageView 
    android:layout_gravity="center_vertical"
    android:id="@id/status"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" 
/>
Some of these attributes we'll discuss later, the one we're concerned with right now is 'android:id="@id/status"'

The attribute 'android:id' is used as a reference. Sometimes they just provide a reminder of what the line does, sometimes they are used by the apk's Java code.

We've deleted the reference to the status icons, but not the Java/smali code that defines which icons should be shown.

The apk will run, work out which status icons to show, can't find where they should go, report an error and Android will force the app to close.

Which is annoying.

There are three ways we can fix this and stop the status icons from showing without the app FC'ing on us:

1. We could work out what the hex reference is that's associated with that id, track it through the smali and edit the code as needed. Which is a lot of work. A lot of work.

2. We could try to make the status icons invisible by setting their height and width to 0.
Code:
<ImageView 
    android:layout_gravity="center_vertical"
    android:id="@id/status"
    android:layout_width="0.0dip"
    android:layout_height="0.0dip" 
/>
This works but isn't ideal. Android is still using processing time and power to show those icons, we just can't see them. We're only talking about a handful of icons on the statusbar and the difference in the drain on the processor is negligible, but it's still not best practice.

3. We can change the lines 'visibility by adding a new attribute..
Code:
<ImageView 
    android:visibility="gone"
    android:layout_gravity="center_vertical"
    android:id="@id/status"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" 
/>
This makes Android ignore this line completely. It's not visible to us because Android just doesn't bother drawing it.

Setting the height and width to 0 isn't the best solution for hiding something but there are times when changing the visibility doesn't work. You may find lines of XML that already have 'android:visibility="gone"' in them. Some ROM's have the option to hide/show certain parts of their UI while running.

So a line with 'android:visibility="gone"' can be forced to become visible. Changing the height and width to zero stops it from ever becoming visible.

If the last paragraph didn't really make sense, don't worry about it. For most of the mods you're likely to do, you can use either option 2 or option 3 to stop things from showing. It's up to you.

Basically, if you want to remove a line with an 'android:id' attribute in it..

Don't Delete It...Hide It!
The Following 38 Users Say Thank You to Ticklefish For This Useful Post: [ View ] Gift Ticklefish Ad-Free
5th November 2014, 04:03 PM |#3  
*** Some Useful Codes To Know ***


This object of this thread is to help you understand and master XML but I'm not going to explain what every tag and attribute means.

I don't have the space nor the time to do so. There are a lot of Android XML codes available.

And I don't need to, either. Google got there first. This is a link to their developers website: http://developer.android.com/reference/packages.html. Do a search for any Android XML tag or attribute you're unsure about and you'll be given a lot of information about it from the people that created it. I visit this site nearly every day.

But there are some things I think you could do with knowing about right now. And those are LinearLayout, RelativeLayout, FrameLayout, android:layout_width and android:layout_height.

*** LinearLayout, RelativeLayout And FrameLayout ***


In Android, a 'Layout' is a collection of tags or 'objects' arranged together in a particular manner. These are essential to get an app laid out correctly.

A 'LinearLayout' is a collection of objects laid out in a line. The first object within the Layout sits at the top or the left of that Layout. LinearLayouts can be vertical or horizontal, according to their 'androidrientation' attribute.
The second object sits underneath or to the right of that Layout.

This is a sample LinearLayout taken from my SystemUI.apk's navigation_bar.xml:

Code:
<LinearLayout android:orientation="horizontal" android:id="@id/nav_buttons" android:clipChildren="false" android:clipToPadding="false" android:layout_width="fill_parent" android:layout_height="fill_parent" android:animateLayoutChanges="true">
    <View android:visibility="invisible" android:layout_width="40.0dip" android:layout_height="fill_parent" android:layout_weight="0.0" />
    <com.android.systemui.statusbar.policy.KeyButtonView android:id="@id/back" android:layout_width="@dimen/navigation_key_width" android:layout_height="fill_parent" android:src="@drawable/ic_sysbar_back" android:layout_weight="0.0" android:contentDescription="@string/accessibility_back" android:layout_marginStart="@dimen/navigation_key_outer_margin" systemui:keyCode="4" systemui:glowBackground="@drawable/ic_sysbar_highlight" />
    <View android:visibility="invisible" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1.0" />
    <com.android.systemui.statusbar.policy.KeyButtonView android:id="@id/home" android:layout_width="@dimen/navigation_key_width" android:layout_height="fill_parent" android:src="@drawable/ic_sysbar_home" android:layout_weight="0.0" android:contentDescription="@string/accessibility_home" systemui:keyCode="3" systemui:keyRepeat="false" systemui:glowBackground="@drawable/ic_sysbar_highlight" />
    <View android:visibility="invisible" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1.0" />
    <com.android.systemui.statusbar.policy.KeyButtonView android:id="@id/recent_apps" android:layout_width="@dimen/navigation_key_width" android:layout_height="fill_parent" android:src="@drawable/ic_sysbar_recent" android:layout_weight="0.0" android:contentDescription="@string/accessibility_recent" android:layout_marginEnd="@dimen/navigation_key_outer_margin" systemui:keyCode="187" systemui:glowBackground="@drawable/ic_sysbar_highlight" />
    <com.android.systemui.statusbar.policy.KeyButtonView android:id="@id/menu" android:visibility="invisible" android:layout_width="@dimen/navigation_menu_key_width" android:layout_height="fill_parent" android:src="@drawable/ic_sysbar_menu" android:layout_weight="0.0" android:contentDescription="@string/accessibility_menu" systemui:keyCode="82" systemui:glowBackground="@drawable/ic_sysbar_highlight" />
</LinearLayout>
Here the tags that display my different softkeys are arranged in a horizontal line, which looks something like this:


A 'RelativeLayout' also arranges objects in a line, but lets you put them in different places relative to each other and the Layout. There's a wonderful example of this here: http://www.mkyong.com/android/androi...ayout-example/. This explains this sort of Layout far better than I ever could.
RelativeLayouts are very flexible, but it can get quite complicated keeping track of what's supposed to be going where.

A 'FrameLayout' arranges objects in a frame. Which doesn't explain things well.
Think of it as creating a photo frame. Every object in that FrameLayout is placed into the middle of the frame, laid on top of the object before it. FrameLayouts can be very useful if you want to put multiple objects in the same place. My rom uses a FrameLayout to overlay my data connection icons on top of my signal icons. Here's one from my signal_cluster_view.xml:

Code:
    <FrameLayout android:id="@id/wifi_combo" android:layout_width="wrap_content" android:layout_height="wrap_content">
        <ImageView android:layout_gravity="bottom|center" android:id="@id/wifi_signal" android:layout_width="wrap_content" android:layout_height="wrap_content" />
        <ImageView android:layout_gravity="bottom|center" android:id="@id/wifi_inout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/somc_sys_signal_wifi_activity" />
    </FrameLayout>
For more detailed info on these Layouts, have a look at Google's developer site. The link is in the text above.

(There's another Layout available in Android. It's called a TableLayout but I haven't mentioned it because you'll rarely, if ever, see it when you're modding your apk's. In over two years of being a Recognized Themer, I've been asked about it once.)

*** android:layout_height And android:layout_width ***


In the Layouts above, we had some tags inside other tags. This is known as 'nesting' and is fine as long as you remember to include the correct 'end tag'.

Code:
    <FrameLayout android:id="@id/wifi_combo" android:layout_width="wrap_content" android:layout_height="wrap_content">
        <ImageView android:layout_gravity="bottom|center" android:id="@id/wifi_signal" android:layout_width="wrap_content" android:layout_height="wrap_content" />
        <ImageView android:layout_gravity="bottom|center" android:id="@id/wifi_inout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/somc_sys_signal_wifi_activity" />
    </FrameLayout>
That '</FrameLayout>' in red is the end tag for this FrameLayout. Every line between this line and the first one are considered to be nested within the Layout.

Note that the first line, because the tag doesn't end there, finishes in a '>', not a '/>' as usual.

In programming terms, the FrameLayout in that example is considered the 'parent' and the two ImageView lines are considered the 'children'.

Let's have another look at my clock XML:

Code:
<com.android.systemui.statusbar.policy.Clock
    android:textAppearance="@style/TextAppearance.StatusBar.Clock"
    android:gravity="start|center"
    android:id="@id/clock"
    android:layout_width="wrap_content"
    android:layout_height="fill_parent"
    android:singleLine="true"
    android:paddingStart="6.0dip"
/>
This clock can be thought of as being inside a 'layout'. Not a 'Layout' with a capital, just a lower-case layout. This may seem odd, but just go with it.

Here the clock layout's height, or the 'layout_height', is set to "fill_parent". This means the clock's layout occupies a section of space on the screen the same height as the parent Layout (with a capital L). This ultimately means the clock occupies a section of space the same height as the statusbar.
This doesn't mean, the clock is the same height as the statusbar. To make the clock itself the same height, we'd have to change the size of the text. Think of it like the difference between the size of a painting and the size of its canvas..

The width of the clock, or the 'layout_width', is set to "wrap_content". This means the clocks 'layout' is exactly as wide as the content inside it. In other words, it's the exact same width as the clock itself.

It's important to know the difference between wrap_content and fill_parent and just as important to understand that these control the space an object uses, not the size of the object itself.

*** Now For The Fun Part ***


Brain starting to hurt? I know mine is and I understand XML fairly well. (Although I should stress I'm no expert.)

Let's start putting everything I've talked about into practice, shall we? Read on to the next post to start modding!
The Following 19 Users Say Thank You to Ticklefish For This Useful Post: [ View ] Gift Ticklefish Ad-Free
5th November 2014, 04:03 PM |#4  
*** How To Change The Colour Of The Status Bar Clock ***


For our first mod, we're going to do something fairly simple. We're going to change the colour of something.




Changing the colour of the clock on the status bar may be an easy mod but it's one that can make a dramatic difference to the look of your Android device. And it serves as a nice introduction to how easy it is to mod XML.

To do this, we'll need to edit status_bar.xml inside SystemUI.apk.
If you're using a multi-sim phone, you might need to edit msim_status_bar.xml.
If you're using a non-stock rom, you might need to decompile a different apk to get the relevant XML file.

This is what the status_bar.xml looks like in stock KitKat:

Code:
<com.android.systemui.statusbar.phone.PhoneStatusBarView android:id="@+id/status_bar" android:background="@drawable/system_bar_background" android:orientation="vertical" android:focusable="true" android:descendantFocusability="afterDescendants" android:fitsSystemWindows="true"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui">
    <ImageView android:id="@+id/notification_lights_out" android:layout_width="@dimen/status_bar_icon_size" android:layout_height="match_parent" android:paddingStart="6dip" android:paddingBottom="2dip" android:src="@drawable/ic_sysbar_lights_out_dot_small" android:scaleType="center" android:visibility="gone" />
    <LinearLayout android:id="@+id/status_bar_contents" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingStart="6dip" android:paddingEnd="6dip" android:orientation="horizontal" >
        <LinearLayout android:id="@+id/notification_icon_area" android:layout_width="0dip" android:layout_height="match_parent" android:layout_weight="1" android:orientation="horizontal" >
            <com.android.systemui.statusbar.StatusBarIconView android:id="@+id/moreIcon" android:layout_width="@dimen/status_bar_icon_size" android:layout_height="match_parent" android:src="@drawable/stat_notify_more" android:visibility="gone" />
            <com.android.systemui.statusbar.phone.IconMerger android:id="@+id/notificationIcons" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignParentStart="true" android:gravity="center_vertical" android:orientation="horizontal"/>  
        </LinearLayout>
        <LinearLayout android:id="@+id/system_icon_area" android:layout_width="wrap_content" android:layout_height="match_parent" android:orientation="horizontal">
            <LinearLayout android:id="@+id/statusIcons" android:layout_width="wrap_content" android:layout_height="match_parent" android:gravity="center_vertical" android:orientation="horizontal"/>    
            <LinearLayout android:id="@+id/signal_battery_cluster" android:layout_width="wrap_content" android:layout_height="match_parent" android:paddingStart="2dp" android:orientation="horizontal" android:gravity="center" >
                <include layout="@layout/signal_cluster_view" android:id="@+id/signal_cluster" android:layout_width="wrap_content" android:layout_height="wrap_content" />
                <com.android.systemui.BatteryMeterView android:id="@+id/battery" android:layout_height="16dp" android:layout_width="10.5dp" android:layout_marginBottom="0.33dp" android:layout_marginStart="4dip" />
            </LinearLayout>
            <com.android.systemui.statusbar.policy.Clock android:id="@+id/clock" android:textAppearance="@style/TextAppearance.StatusBar.Clock" android:layout_width="wrap_content" android:layout_height="match_parent" android:singleLine="true" android:paddingStart="6dip" android:gravity="center_vertical|start" />
        </LinearLayout>
    </LinearLayout>
    <LinearLayout android:id="@+id/ticker" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingStart="6dip" android:animationCache="false" android:orientation="horizontal" >
        <ImageSwitcher android:id="@+id/tickerIcon" android:layout_width="@dimen/status_bar_icon_size" android:layout_height="@dimen/status_bar_icon_size" android:layout_marginEnd="4dip" >
            <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:layout_width="0dip" android:layout_weight="1" android:layout_height="wrap_content" android:paddingTop="2dip" android:paddingEnd="10dip">
            <TextView android:textAppearance="@style/TextAppearance.StatusBar.PhoneTicker" android:layout_width="match_parent" android:layout_height="wrap_content" android:singleLine="true" />
            <TextView android:textAppearance="@style/TextAppearance.StatusBar.PhoneTicker" android:layout_width="match_parent" android:layout_height="wrap_content" android:singleLine="true" />
        </com.android.systemui.statusbar.phone.TickerView>
    </LinearLayout>
</com.android.systemui.statusbar.phone.PhoneStatusBarView>
Here's the Gingerbread status_bar.xml:

Code:
<com.android.systemui.statusbar.StatusBarView android:orientation="vertical" android:background="@drawable/gradient" android:focusable="true" android:descendantFocusability="afterDescendants"
  xmlns:android="http://schemas.android.com/apk/res/android">
    <LinearLayout android:orientation="horizontal" android:id="@id/icons" android:layout_width="fill_parent" android:layout_height="fill_parent">
        <com.android.systemui.statusbar.IconMerger android:gravity="center_vertical" android:orientation="horizontal" android:id="@id/notificationIcons" android:paddingLeft="6.0dip" android:layout_width="0.0dip" android:layout_height="fill_parent" android:layout_weight="1.0" android:layout_alignParentLeft="true" />
        <LinearLayout android:gravity="center_vertical" android:orientation="horizontal" android:id="@id/statusIcons" android:paddingRight="6.0dip" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_alignParentRight="true" />
        <com.android.systemui.statusbar.Clock android:textAppearance="@*android:style/TextAppearance.StatusBar.Icon" android:textSize="16.0sp" android:gravity="center_vertical" android:id="@id/clock" android:paddingRight="6.0dip" android:layout_width="wrap_content" android:layout_height="fill_parent" android:singleLine="true" />
    </LinearLayout>
    <LinearLayout android:orientation="horizontal" android:id="@id/ticker" android:paddingLeft="6.0dip" android:animationCache="false" android:layout_width="fill_parent" android:layout_height="fill_parent">
        <ImageSwitcher android:id="@id/tickerIcon" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_marginRight="8.0dip">
            <com.android.systemui.statusbar.AnimatedImageView android:layout_width="25.0dip" android:layout_height="25.0dip" />
            <com.android.systemui.statusbar.AnimatedImageView android:layout_width="25.0dip" android:layout_height="25.0dip" />
        </ImageSwitcher>
        <com.android.systemui.statusbar.TickerView android:id="@id/tickerText" android:paddingTop="2.0dip" android:paddingRight="10.0dip" android:layout_width="0.0dip" android:layout_height="wrap_content" android:layout_weight="1.0">
            <TextView android:textAppearance="@*android:style/TextAppearance.StatusBar.Ticker" android:layout_width="fill_parent" android:layout_height="wrap_content" android:singleLine="true" />
            <TextView android:textAppearance="@*android:style/TextAppearance.StatusBar.Ticker" android:layout_width="fill_parent" android:layout_height="wrap_content" android:singleLine="true" />
        </com.android.systemui.statusbar.TickerView>
    </LinearLayout>
    <com.android.systemui.statusbar.DateView android:textAppearance="@*android:style/TextAppearance.StatusBar.Icon" android:gravity="left|center" android:id="@id/date" android:background="#ff000000" android:paddingLeft="6.0px" android:paddingRight="6.0px" android:layout_width="wrap_content" android:layout_height="fill_parent" android:singleLine="true" />
</com.android.systemui.statusbar.StatusBarView>
Android XML has changed a lot over the years but one thing has always stayed the same. There's always been a clock. And it's always been a piece of text.

Here's the KitKat clock line:

Code:
<com.android.systemui.statusbar.policy.Clock 
    android:id="@+id/clock"
    android:textAppearance="@style/TextAppearance.StatusBar.Clock"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:singleLine="true"
    android:paddingStart="6dip"
    android:gravity="center_vertical|start" 
/>
As far as Android is concerned, the clock is just a piece of text that changes every minute. And because it's text, you can use text attributes on it. One such attribute is 'android:textColor'.

Let's say we want to change our clock from the normal, boring white to a rich green. Here's what the code needs to look like:

Code:
<com.android.systemui.statusbar.policy.Clock
    android:textColor="#ff00ff00"
    android:id="@+id/clock"
    android:textAppearance="@style/TextAppearance.StatusBar.Clock"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:singleLine="true"
    android:paddingStart="6dip"
    android:gravity="center_vertical|start" 
/>
See that new attribute I've put in? This changes the colour of the text in this tag to 'ff00ff00'. Which is an ARGB code for completely opaque green.

"ARGB" is short for "Alpha Red Green Blue" and uses hexadecimal codes. Alpha, for those who might not know, is a transparency value.
So the colour I've set the clock to is "not transparent at all" - "not red at all" - "completely green" - "not blue at all".

You can use an RGB code instead, which would give us a colour '00ff00, but I prefer sticking to ARGB at all times to keep it simple. You never know when you might want to mess around with transparency!

Save, recompile, flash and your clock is now a lovely shade of green. Simple!

This attribute can be used on any text in your apk, not just the clock. You can change the colour of the date, the carrier label, your notification text...anything at all as long it's regarded as text by Android!

*** How To Change The Colour Of The Status Bar Clock - The Advanced Method ***


Okay, so this is where it starts to get a bit more complicated.

What if there was a particular colour that you really liked, that you wanted to use for a lot of the text in your app, but which had an ARGB code that wasn't easy to remember? What if you wanted to use 'ffdb7093' (picked at random from www.color-hex.com)?

I can't remember that code and I've only just written it!

Well, the good news is that I don't have to remember it. Inside your decompiled app will be a folder called "values". Inside that, have a look at "colors.xml"

Code:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="system_bar_background_opaque">#ff000000</color>

...and so on for a few lines..

    <color name="battery_text_color_critical">#ffcb2026</color>
</resources>
These are predefined colours that our app can use. So let's add a new one..

Code:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="my_colour">#ffdb7093</color>
    <color name="system_bar_background_opaque">#ff000000</color>

...and so on for a few lines..

    <color name="battery_text_color_critical">#ffcb2026</color>
</resources>
...change our clock XML....

Code:
<com.android.systemui.statusbar.policy.Clock
    android:textColor="@color/my_colour"
    android:id="@+id/clock"
    android:textAppearance="@style/TextAppearance.StatusBar.Clock"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:singleLine="true"
    android:paddingStart="6dip"
    android:gravity="center_vertical|start" 
/>
...add that attribute to any other text lines we want to change...

Code:
<TextView
    android:textColor="@color/my_colour"
    android:textAppearance="@style/TextAppearance.StatusBar.PhoneTicker"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:singleLine="true"
/>
...save, recompile, flash and suddenly the clock and the notification text have changed to what color-hex.com describes as "Pale Violet Red". Nice!

Don't like it? Then you can just change the one line in colors.xml without having to worry about any other lines of XML.

*** How To Change The Colour Of The Status Bar Clock - The Even More Advanced Method ***


When you decompiled SystemUI.apk, you may have noticed that you needed to install framework-res.apk to your PC first.

This is because SystemUI.apk uses certain resources that are contained within framework-res.apk and you need to make those available for the apk to be decompiled fully. Amongst those resources are some colours that are accessible by SystemUI.apk, as well as any other app that can access framework-res.apk.

In other words, we can add our colour to framework-res.apk and it can be used by SystemUI.apk, Phone.apk, settings.apk...and lots of other apps!

Add your colour to 'framework-res.apk/res/values/colors.xml':

Code:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="my_colour">#ffdb7093</color>
    <color name="darker_gray">#ffaaaaaa</color>

...and so on for several lines..

    <color name="webviewchromium_autofill_dark_divider_color">#ffc0c0c0</color>
</resources>
Then add a textColour attribute to the lines you want to change in the apk files you want to change. But use a slightly different format than before..

Code:
<com.android.systemui.statusbar.policy.Clock
    android:textColor="@android:color/my_colour"
    android:id="@+id/clock"
    android:textAppearance="@style/TextAppearance.StatusBar.Clock"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:singleLine="true"
    android:paddingStart="6dip"
    android:gravity="center_vertical|start" 
/>
It'll take a while but the result is that you'll change the colour of lots of pieces of text in your rom. And, should you decide to change that colour again, all you need to do is edit one line. Very nice!

Hopefully this all makes sense. It does to me but I've been experimenting with Android XML for about three years now.. If it doesn't make any sense, feel free to ask for help. This is probably the simplest XML mod you can do and it's only going to get more complicated from here!
The Following 18 Users Say Thank You to Ticklefish For This Useful Post: [ View ] Gift Ticklefish Ad-Free
5th November 2014, 04:04 PM |#5  
*** How To Put An Invisible Softkey In The Status Bar ***


Softkeys are the buttons that are found in the navigation bar at the bottom of the screen. They are normally buttons for BACK, HOME, RECENT APPS and MENU. Although it's not unusual to find some roms with a SEARCH softkey or even some volume controls.

The status bar is the bit at the top of the screen that shows the clock, battery level, signal strength, etc.

Because phones and tablets are getting bigger and bigger, it'd be quite handy to put at least one softkey in it so we don't have to haul our finger all the way to the other end of the screen (trust me, every second counts!).

How hard is it to use something that's in one XML file (navigation_bar.xml) inside a different XML file (status_bar.xml)?

Actually, it's not hard at all!

As with a lot of things to do with the system user interface, we need to decompile our SystemUI.apk. Here's what the stock KitKat navigation_bar.xml looks like:

Code:
<com.android.systemui.statusbar.phone.NavigationBarView android:layout_height="match_parent" android:layout_width="match_parent" android:background="@drawable/system_bar_background"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui">
    <FrameLayout android:id="@+id/rot0" android:layout_height="match_parent" android:layout_width="match_parent" >
        <LinearLayout android:layout_height="match_parent" android:layout_width="match_parent" android:orientation="horizontal" android:clipChildren="false" android:clipToPadding="false" android:id="@+id/nav_buttons" android:animateLayoutChanges="true" >
            <View android:layout_width="40dp" android:layout_height="match_parent" android:layout_weight="0" android:visibility="invisible" />
            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back" android:layout_width="@dimen/navigation_key_width" android:layout_height="match_parent" android:src="@drawable/ic_sysbar_back" systemui:keyCode="4" android:layout_weight="0" android:scaleType="center" systemui:glowBackground="@drawable/ic_sysbar_highlight" android:contentDescription="@string/accessibility_back" />
            <View android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:visibility="invisible" />
            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home" android:layout_width="@dimen/navigation_key_width" android:layout_height="match_parent" android:src="@drawable/ic_sysbar_home" systemui:keyCode="3" systemui:keyRepeat="false" android:layout_weight="0" systemui:glowBackground="@drawable/ic_sysbar_highlight" android:contentDescription="@string/accessibility_home" />
            <View android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:visibility="invisible" />
            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/recent_apps" android:layout_width="@dimen/navigation_key_width" android:layout_height="match_parent" android:src="@drawable/ic_sysbar_recent" android:layout_weight="0" systemui:glowBackground="@drawable/ic_sysbar_highlight" android:contentDescription="@string/accessibility_recent" />
            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu" android:layout_width="@dimen/navigation_menu_key_width" android:layout_height="match_parent" android:src="@drawable/ic_sysbar_menu" systemui:keyCode="82" android:layout_weight="0" android:visibility="invisible" android:contentDescription="@string/accessibility_menu" systemui:glowBackground="@drawable/ic_sysbar_highlight" />
        </LinearLayout>
        <LinearLayout android:layout_height="match_parent" android:layout_width="match_parent" android:orientation="horizontal" android:id="@+id/lights_out" android:visibility="gone" >
            <ImageView android:layout_width="80dp" android:layout_height="match_parent" android:layout_marginStart="40dp" android:src="@drawable/ic_sysbar_lights_out_dot_small" android:scaleType="center" android:layout_weight="0" />
            <View android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:visibility="invisible" />
            <ImageView android:layout_width="80dp" android:layout_height="match_parent" android:src="@drawable/ic_sysbar_lights_out_dot_large" android:scaleType="center" android:layout_weight="0" />
            <View android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:visibility="invisible" />
            <ImageView android:layout_width="80dp" android:layout_marginEnd="40dp" android:layout_height="match_parent" android:src="@drawable/ic_sysbar_lights_out_dot_small" android:scaleType="center" android:layout_weight="0" />
        </LinearLayout>
        <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent">
            <com.android.systemui.statusbar.policy.KeyButtonView android:layout_width="80dp" android:id="@+id/search_light" android:layout_height="match_parent" android:layout_gravity="center" android:src="@drawable/search_light" android:scaleType="center" android:visibility="gone" android:contentDescription="@string/accessibility_search_light" />
            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/camera_button" android:layout_height="match_parent" android:layout_width="80dp" android:layout_gravity="center_vertical|right" android:src="@drawable/ic_sysbar_camera" android:scaleType="center" android:visibility="gone" android:contentDescription="@string/accessibility_camera_button" />
        </FrameLayout>
        <com.android.systemui.statusbar.policy.DeadZone android:id="@+id/deadzone" android:layout_height="match_parent" android:layout_width="match_parent" systemui:minSize="@dimen/navigation_bar_deadzone_size" systemui:maxSize="@dimen/navigation_bar_deadzone_size_max" systemui:holdTime="@integer/navigation_bar_deadzone_hold" systemui:decayTime="@integer/navigation_bar_deadzone_decay" systemui:orientation="horizontal" android:layout_gravity="top" />
    </FrameLayout>
    <FrameLayout android:id="@+id/rot90" android:layout_height="match_parent" android:layout_width="match_parent" android:visibility="gone" android:paddingTop="0dp" >
        <LinearLayout android:layout_height="match_parent" android:layout_width="match_parent" android:orientation="vertical" android:clipChildren="false" android:clipToPadding="false" android:id="@+id/nav_buttons" android:animateLayoutChanges="true" >
            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu" android:layout_height="40dp" android:layout_width="match_parent" android:src="@drawable/ic_sysbar_menu_land" systemui:keyCode="82" android:layout_weight="0" android:visibility="invisible" android:contentDescription="@string/accessibility_menu" systemui:glowBackground="@drawable/ic_sysbar_highlight_land" />
            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/recent_apps" android:layout_height="80dp" android:layout_width="match_parent" android:src="@drawable/ic_sysbar_recent_land" android:layout_weight="0" android:contentDescription="@string/accessibility_recent" systemui:glowBackground="@drawable/ic_sysbar_highlight_land" />
            <View android:layout_height="match_parent" android:layout_width="match_parent" android:layout_weight="1" android:visibility="invisible" />
            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home" android:layout_height="80dp" android:layout_width="match_parent" android:src="@drawable/ic_sysbar_home_land" systemui:keyCode="3" systemui:keyRepeat="false" android:layout_weight="0" android:contentDescription="@string/accessibility_home" systemui:glowBackground="@drawable/ic_sysbar_highlight_land" />
            <View android:layout_height="match_parent" android:layout_width="match_parent" android:layout_weight="1" android:visibility="invisible" />
            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back" android:layout_height="80dp" android:layout_width="match_parent" android:src="@drawable/ic_sysbar_back_land" android:scaleType="center" systemui:keyCode="4" android:layout_weight="0" android:contentDescription="@string/accessibility_back" systemui:glowBackground="@drawable/ic_sysbar_highlight_land" />
            <View android:layout_height="40dp" android:layout_width="match_parent" android:layout_weight="0" android:visibility="invisible" />
        </LinearLayout>
        <LinearLayout android:layout_height="match_parent" android:layout_width="match_parent" android:orientation="vertical" android:id="@+id/lights_out" android:visibility="gone" >
            <ImageView android:layout_height="80dp" android:layout_marginTop="40dp" android:layout_width="match_parent" android:src="@drawable/ic_sysbar_lights_out_dot_small" android:scaleType="center" android:layout_weight="0" />
            <View android:layout_height="match_parent" android:layout_width="match_parent" android:layout_weight="1" android:visibility="invisible" />
            <ImageView android:layout_height="80dp" android:layout_width="match_parent" android:src="@drawable/ic_sysbar_lights_out_dot_large" android:scaleType="center" android:layout_weight="0" />
            <View android:layout_height="match_parent" android:layout_width="match_parent" android:layout_weight="1" android:visibility="invisible" />
            <ImageView android:layout_height="80dp" android:layout_marginBottom="40dp" android:layout_width="match_parent" android:src="@drawable/ic_sysbar_lights_out_dot_small" android:scaleType="center" android:layout_weight="0" />
        </LinearLayout>
        <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/search_light" android:layout_height="80dp" android:layout_width="match_parent" android:layout_gravity="center_vertical" android:src="@drawable/search_light_land" android:scaleType="center" android:visibility="gone" android:contentDescription="@string/accessibility_search_light" />
        <com.android.systemui.statusbar.policy.DeadZone android:id="@+id/deadzone" android:layout_height="match_parent" android:layout_width="match_parent" systemui:minSize="@dimen/navigation_bar_deadzone_size" systemui:maxSize="@dimen/navigation_bar_deadzone_size_max" systemui:holdTime="@integer/navigation_bar_deadzone_hold" systemui:decayTime="@integer/navigation_bar_deadzone_decay" systemui:orientation="vertical" android:layout_gravity="top" />
    </FrameLayout>
    <View android:id="@+id/rot270" android:layout_height="match_parent" android:layout_width="match_parent" android:visibility="gone" />
</com.android.systemui.statusbar.phone.NavigationBarView>
This is relatively dense code and it can be hard to work out just what it's doing but it does all make sense. For now though, all we need is just one line. Let's say we want to put a HOME softkey in our statusbar. In that case, we just want a line with 'home' in it.

And here it is:

Code:
<com.android.systemui.statusbar.policy.KeyButtonView
    android:id="@+id/home"
    android:layout_width="@dimen/navigation_key_width"
    android:layout_height="match_parent"
    android:src="@drawable/ic_sysbar_home"
    systemui:keyCode="3"
    systemui:keyRepeat="false"
    android:layout_weight="0"
    systemui:glowBackground="@drawable/ic_sysbar_highlight"
    android:contentDescription="@string/accessibility_home" 
/>
We're going to put that into our status bar, so let's have a look at our status_bar.xml:

Code:
<com.android.systemui.statusbar.phone.PhoneStatusBarView android:id="@+id/status_bar" android:background="@drawable/system_bar_background" android:orientation="vertical" android:focusable="true" android:descendantFocusability="afterDescendants" android:fitsSystemWindows="true"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui">
    <ImageView android:id="@+id/notification_lights_out" android:layout_width="@dimen/status_bar_icon_size" android:layout_height="match_parent" android:paddingStart="6dip" android:paddingBottom="2dip" android:src="@drawable/ic_sysbar_lights_out_dot_small" android:scaleType="center" android:visibility="gone" />
    <LinearLayout android:id="@+id/status_bar_contents" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingStart="6dip" android:paddingEnd="6dip" android:orientation="horizontal" >
        <LinearLayout android:id="@+id/notification_icon_area" android:layout_width="0dip" android:layout_height="match_parent" android:layout_weight="1" android:orientation="horizontal" >
            <com.android.systemui.statusbar.StatusBarIconView android:id="@+id/moreIcon" android:layout_width="@dimen/status_bar_icon_size" android:layout_height="match_parent" android:src="@drawable/stat_notify_more" android:visibility="gone" />
            <com.android.systemui.statusbar.phone.IconMerger android:id="@+id/notificationIcons" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignParentStart="true" android:gravity="center_vertical" android:orientation="horizontal"/>  
        </LinearLayout>
        <LinearLayout android:id="@+id/system_icon_area" android:layout_width="wrap_content" android:layout_height="match_parent" android:orientation="horizontal">
            <LinearLayout android:id="@+id/statusIcons" android:layout_width="wrap_content" android:layout_height="match_parent" android:gravity="center_vertical" android:orientation="horizontal"/>    
            <LinearLayout android:id="@+id/signal_battery_cluster" android:layout_width="wrap_content" android:layout_height="match_parent" android:paddingStart="2dp" android:orientation="horizontal" android:gravity="center" >
                <include layout="@layout/signal_cluster_view" android:id="@+id/signal_cluster" android:layout_width="wrap_content" android:layout_height="wrap_content" />
                <com.android.systemui.BatteryMeterView android:id="@+id/battery" android:layout_height="16dp" android:layout_width="10.5dp" android:layout_marginBottom="0.33dp" android:layout_marginStart="4dip" />
            </LinearLayout>
            <com.android.systemui.statusbar.policy.Clock android:id="@+id/clock" android:textAppearance="@style/TextAppearance.StatusBar.Clock" android:layout_width="wrap_content" android:layout_height="match_parent" android:singleLine="true" android:paddingStart="6dip" android:gravity="center_vertical|start" />
        </LinearLayout>
    </LinearLayout>
    <LinearLayout android:id="@+id/ticker" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingStart="6dip" android:animationCache="false" android:orientation="horizontal" >
        <ImageSwitcher android:id="@+id/tickerIcon" android:layout_width="@dimen/status_bar_icon_size" android:layout_height="@dimen/status_bar_icon_size" android:layout_marginEnd="4dip" >
            <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:layout_width="0dip" android:layout_weight="1" android:layout_height="wrap_content" android:paddingTop="2dip" android:paddingEnd="10dip">
            <TextView android:textAppearance="@style/TextAppearance.StatusBar.PhoneTicker" android:layout_width="match_parent" android:layout_height="wrap_content" android:singleLine="true" />
            <TextView android:textAppearance="@style/TextAppearance.StatusBar.PhoneTicker" android:layout_width="match_parent" android:layout_height="wrap_content" android:singleLine="true" />
        </com.android.systemui.statusbar.phone.TickerView>
    </LinearLayout>
</com.android.systemui.statusbar.phone.PhoneStatusBarView>
Being right-handed, I might as well put my HOME softkey to the right of the clock. That way, it's as close to the right side of the status bar as possible. All I need to do is just copy and paste..

Code:
<com.android.systemui.statusbar.phone.PhoneStatusBarView android:id="@+id/status_bar" android:background="@drawable/system_bar_background" android:orientation="vertical" android:focusable="true" android:descendantFocusability="afterDescendants" android:fitsSystemWindows="true"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui">
    <ImageView android:id="@+id/notification_lights_out" android:layout_width="@dimen/status_bar_icon_size" android:layout_height="match_parent" android:paddingStart="6dip" android:paddingBottom="2dip" android:src="@drawable/ic_sysbar_lights_out_dot_small" android:scaleType="center" android:visibility="gone" />
    <LinearLayout android:id="@+id/status_bar_contents" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingStart="6dip" android:paddingEnd="6dip" android:orientation="horizontal" >
        <LinearLayout android:id="@+id/notification_icon_area" android:layout_width="0dip" android:layout_height="match_parent" android:layout_weight="1" android:orientation="horizontal" >
            <com.android.systemui.statusbar.StatusBarIconView android:id="@+id/moreIcon" android:layout_width="@dimen/status_bar_icon_size" android:layout_height="match_parent" android:src="@drawable/stat_notify_more" android:visibility="gone" />
            <com.android.systemui.statusbar.phone.IconMerger android:id="@+id/notificationIcons" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignParentStart="true" android:gravity="center_vertical" android:orientation="horizontal"/>  
        </LinearLayout>
        <LinearLayout android:id="@+id/system_icon_area" android:layout_width="wrap_content" android:layout_height="match_parent" android:orientation="horizontal">
            <LinearLayout android:id="@+id/statusIcons" android:layout_width="wrap_content" android:layout_height="match_parent" android:gravity="center_vertical" android:orientation="horizontal"/>    
            <LinearLayout android:id="@+id/signal_battery_cluster" android:layout_width="wrap_content" android:layout_height="match_parent" android:paddingStart="2dp" android:orientation="horizontal" android:gravity="center" >
                <include layout="@layout/signal_cluster_view" android:id="@+id/signal_cluster" android:layout_width="wrap_content" android:layout_height="wrap_content" />
                <com.android.systemui.BatteryMeterView android:id="@+id/battery" android:layout_height="16dp" android:layout_width="10.5dp" android:layout_marginBottom="0.33dp" android:layout_marginStart="4dip" />
            </LinearLayout>
            <com.android.systemui.statusbar.policy.Clock android:id="@+id/clock" android:textAppearance="@style/TextAppearance.StatusBar.Clock" android:layout_width="wrap_content" android:layout_height="match_parent" android:singleLine="true" android:paddingStart="6dip" android:gravity="center_vertical|start" />
            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home" android:layout_width="@dimen/navigation_key_width" android:layout_height="match_parent" android:src="@drawable/ic_sysbar_home" systemui:keyCode="3" systemui:keyRepeat="false" android:layout_weight="0" systemui:glowBackground="@drawable/ic_sysbar_highlight" android:contentDescription="@string/accessibility_home" />
        </LinearLayout>
    </LinearLayout>
    <LinearLayout android:id="@+id/ticker" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingStart="6dip" android:animationCache="false" android:orientation="horizontal" >
        <ImageSwitcher android:id="@+id/tickerIcon" android:layout_width="@dimen/status_bar_icon_size" android:layout_height="@dimen/status_bar_icon_size" android:layout_marginEnd="4dip" >
            <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:layout_width="0dip" android:layout_weight="1" android:layout_height="wrap_content" android:paddingTop="2dip" android:paddingEnd="10dip">
            <TextView android:textAppearance="@style/TextAppearance.StatusBar.PhoneTicker" android:layout_width="match_parent" android:layout_height="wrap_content" android:singleLine="true" />
            <TextView android:textAppearance="@style/TextAppearance.StatusBar.PhoneTicker" android:layout_width="match_parent" android:layout_height="wrap_content" android:singleLine="true" />
        </com.android.systemui.statusbar.phone.TickerView>
    </LinearLayout>
</com.android.systemui.statusbar.phone.PhoneStatusBarView>
And, once I've saved, recompiled and flashed back to the phone, here's the result:


*** But That's Not Invisible, Ticklefish!! ***


You're right, it's not. Not only is the softkey taking up space on my status bar because it's visible, but it also looks a little squashed.

We can change the icon to make it look a bit better...but we're better off doing something a little cleverer..

For this, we're going to use a RelativeLayout to put the clock and the softkey on top of each other. And we need to make a few changes to the attributes of those lines:

Code:
<RelativeLayout android:layout_width="wrap_content" android:layout_height="fill_parent">
   <com.android.systemui.statusbar.policy.Clock android:layout_alignParentRight="true" android:id="@+id/clock" android:textAppearance="@style/TextAppearance.StatusBar.Clock" android:layout_width="wrap_content" android:layout_height="match_parent" android:singleLine="true" android:paddingStart="6dip" android:gravity="center_vertical|start" />
   <com.android.systemui.statusbar.policy.KeyButtonView android:layout_alignParentRight="true" android:id="@+id/home" android:layout_width="20.0dip" android:layout_height="match_parent" systemui:keyCode="3" systemui:keyRepeat="false" android:layout_weight="0" systemui:glowBackground="@drawable/ic_sysbar_highlight" android:contentDescription="@string/accessibility_home" />
</RelativeLayout>
Here's the code in full:

Code:
<com.android.systemui.statusbar.phone.PhoneStatusBarView android:id="@+id/status_bar" android:background="@drawable/system_bar_background" android:orientation="vertical" android:focusable="true" android:descendantFocusability="afterDescendants" android:fitsSystemWindows="true"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui">
    <ImageView android:id="@+id/notification_lights_out" android:layout_width="@dimen/status_bar_icon_size" android:layout_height="match_parent" android:paddingStart="6dip" android:paddingBottom="2dip" android:src="@drawable/ic_sysbar_lights_out_dot_small" android:scaleType="center" android:visibility="gone" />
    <LinearLayout android:id="@+id/status_bar_contents" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingStart="6dip" android:paddingEnd="6dip" android:orientation="horizontal" >
        <LinearLayout android:id="@+id/notification_icon_area" android:layout_width="0dip" android:layout_height="match_parent" android:layout_weight="1" android:orientation="horizontal" >
            <com.android.systemui.statusbar.StatusBarIconView android:id="@+id/moreIcon" android:layout_width="@dimen/status_bar_icon_size" android:layout_height="match_parent" android:src="@drawable/stat_notify_more" android:visibility="gone" />
            <com.android.systemui.statusbar.phone.IconMerger android:id="@+id/notificationIcons" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignParentStart="true" android:gravity="center_vertical" android:orientation="horizontal"/>  
        </LinearLayout>
        <LinearLayout android:id="@+id/system_icon_area" android:layout_width="wrap_content" android:layout_height="match_parent" android:orientation="horizontal">
            <LinearLayout android:id="@+id/statusIcons" android:layout_width="wrap_content" android:layout_height="match_parent" android:gravity="center_vertical" android:orientation="horizontal"/>    
            <LinearLayout android:id="@+id/signal_battery_cluster" android:layout_width="wrap_content" android:layout_height="match_parent" android:paddingStart="2dp" android:orientation="horizontal" android:gravity="center" >
                <include layout="@layout/signal_cluster_view" android:id="@+id/signal_cluster" android:layout_width="wrap_content" android:layout_height="wrap_content" />
                <com.android.systemui.BatteryMeterView android:id="@+id/battery" android:layout_height="16dp" android:layout_width="10.5dp" android:layout_marginBottom="0.33dp" android:layout_marginStart="4dip" />
            </LinearLayout>
            <RelativeLayout android:layout_width="wrap_content" android:layout_width="fill_parent">
                <com.android.systemui.statusbar.policy.Clock android:layout_alignParentRight="true" android:id="@+id/clock" android:textAppearance="@style/TextAppearance.StatusBar.Clock" android:layout_width="wrap_content" android:layout_height="match_parent" android:singleLine="true" android:paddingStart="6dip" android:gravity="center_vertical|start" />
                <com.android.systemui.statusbar.policy.KeyButtonView android:layout_alignParentRight="true" android:id="@+id/home" android:layout_width="20.0dip" android:layout_height="match_parent" systemui:keyCode="3" systemui:keyRepeat="false" android:layout_weight="0" systemui:glowBackground="@drawable/ic_sysbar_highlight" android:contentDescription="@string/accessibility_home" />
            </RelativeLayout>
        </LinearLayout>
    </LinearLayout>
    <LinearLayout android:id="@+id/ticker" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingStart="6dip" android:animationCache="false" android:orientation="horizontal" >
        <ImageSwitcher android:id="@+id/tickerIcon" android:layout_width="@dimen/status_bar_icon_size" android:layout_height="@dimen/status_bar_icon_size" android:layout_marginEnd="4dip" >
            <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:layout_width="0dip" android:layout_weight="1" android:layout_height="wrap_content" android:paddingTop="2dip" android:paddingEnd="10dip">
            <TextView android:textAppearance="@style/TextAppearance.StatusBar.PhoneTicker" android:layout_width="match_parent" android:layout_height="wrap_content" android:singleLine="true" />
            <TextView android:textAppearance="@style/TextAppearance.StatusBar.PhoneTicker" android:layout_width="match_parent" android:layout_height="wrap_content" android:singleLine="true" />
        </com.android.systemui.statusbar.phone.TickerView>
    </LinearLayout>
</com.android.systemui.statusbar.phone.PhoneStatusBarView>
I've removed the reference to the image file in the softkey line and changed the width to 20 density-independent pixels. That width may need changing, depending on your personal preference. Too big and there'll be a big gap between the clock and the battery icon. Too small and the softkey will be very hard to tap. Experiment to find the value that works for you.

By using the RelativeLayout and the 'android:layout_alignParentRight' attribute, I've ensured that the clock and the softkey occupy the same part of the status bar. Because the softkey now has no image file, it's basically invisible.

Just tap on the clock to go back to the home screen!


(You could use a FrameLayout instead of a RelativeLayout, which would be simpler. But it's worth getting used to how RelativeLayouts work, they can be very useful!)

Of course, you don't have to put the HOME softkey in your status bar. It could be the MENU softkey, the RECENT APPS softkey, even a POWER or SEARCH softkey if you know how.

Or you can have more than one in there. Or they can be visible.

It's your device, you can do what you want.

Just make sure to make a backup before you start modding though!
The Following 23 Users Say Thank You to Ticklefish For This Useful Post: [ View ] Gift Ticklefish Ad-Free
5th November 2014, 04:04 PM |#6  
*** 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:

Code:
<?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:

Code:
<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 @serajr, 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:

Code:
<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"
/>
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:

Code:
<com.android.systemui.statusbar.policy.Clock
    android:id="@id/clock"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center"
    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:

Code:
<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>
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:

Code:
<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 android:background="@drawable/status_bar_background" 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..
The Following 17 Users Say Thank You to Ticklefish For This Useful Post: [ View ] Gift Ticklefish Ad-Free
5th November 2014, 04:05 PM |#7  
*** How To Center The Clock In The Status Bar...Part 2 ***


So how do we fix this issue of the overlapping notifications with the Simple Method?

With the Best Method, of course!

*** The Best Method ***


This is a bit more involved but is the very best way to center the clock.

Or anything else.

In fact, it's a brilliant way to arrange your status bar so you can move anything anywhere.

The Best Method splits the @id/icons Layout into three unique areas, making it very easy to decide what you want where.

What we do is we use this basic arrangement:

Code:
<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:id="@+id/Status_Bar_Left_Side" android:orientation="horizontal" android:layout_width="0.0dip" android:layout_height="fill_parent" android:layout_weight="1.0">

   <!-- HERE ARE ALL THE CODES FOR THE ITEMS ON THE LEFT SIDE OF THE STATUSBAR -->

    </LinearLayout>

   <!-- HERE ARE ALL THE CODES FOR THE ITEMS IN THE CENTER OF THE STATUSBAR -->

    <RelativeLayout android:id="@+id/Status_Bar_Right_Side" android:layout_width="0.0dip" android:layout_height="fill_parent" android:layout_weight="1.0">
        <LinearLayout android:id="@+id/Inside_Status_Bar_Right_Side" android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_alignParentRight="true">

   <!-- HERE ARE ALL THE CODES FOR THE ITEMS ON THE RIGHT SIDE OF THE STATUSBAR -->

        </LinearLayout>
    </RelativeLayout>
</LinearLayout>
Make sense? No? Well, don't worry. There is a logic behind all this. Even if it's not obvious.

This Method basically divides the status bar into just two individual areas. Because those areas have the same 'weight' as each other, they take up exactly the same amount of space as each other. Meaning that whatever goes between those two areas, as long as it doesn't have a weight of 1 or more, will be essentially pushed into the exact center of the status bar.

So, what we do next is apply this Method to our code from above to create:

Code:
<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:id="@+id/Status_Bar_Left_Side" android:orientation="horizontal" android:layout_width="0.0dip" android:layout_height="fill_parent" android:layout_weight="1.0">
        <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>
   <com.android.systemui.statusbar.policy.Clock android:id="@id/clock" android:layout_width="wrap_content" android:layout_height="fill_parent" android:gravity="center" android:textAppearance="@style/TextAppearance.StatusBar.Clock" android:singleLine="true"/>
    <RelativeLayout android:id="@+id/Status_Bar_Right_Side" android:layout_width="0.0dip" android:layout_height="fill_parent" android:layout_weight="1.0">
        <LinearLayout android:id="@+id/Inside_Status_Bar_Right_Side" android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_alignParentRight="true">
            <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>
    </RelativeLayout>
</LinearLayout>
The original code is in red. The only real challenge with this Method is knowing what lines to put in the @id/Status_Bar_Left_Side Layout and which lines to put in the @id/Status_Bar_Right_Side Layout. But take your time, look at the attributes (especially the @id attributes) and it should all become clear.


See? Doesn't that just look beautiful?

And so easy to do as well!

*** The Best Method...On KitKat And Lollipop ***


When I came up with the Best Method, Google were only just getting ready to give the world Jelly Bean.

It's two years later and the XML has changed a bit. This is what the stock KitKat status_bar.xml looks like:

Code:
<com.android.systemui.statusbar.phone.PhoneStatusBarView android:id="@+id/status_bar" android:background="@drawable/system_bar_background" android:orientation="vertical" android:focusable="true" android:descendantFocusability="afterDescendants" android:fitsSystemWindows="true"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui">
    <ImageView android:id="@+id/notification_lights_out" android:layout_width="@dimen/status_bar_icon_size" android:layout_height="match_parent" android:paddingStart="6dip" android:paddingBottom="2dip" android:src="@drawable/ic_sysbar_lights_out_dot_small" android:scaleType="center" android:visibility="gone" />
    <LinearLayout android:id="@+id/status_bar_contents" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingStart="6dip" android:paddingEnd="6dip" android:orientation="horizontal" >
        <LinearLayout android:id="@+id/notification_icon_area" android:layout_width="0dip" android:layout_height="match_parent" android:layout_weight="1" android:orientation="horizontal" >
            <com.android.systemui.statusbar.StatusBarIconView android:id="@+id/moreIcon" android:layout_width="@dimen/status_bar_icon_size" android:layout_height="match_parent" android:src="@drawable/stat_notify_more" android:visibility="gone" />
            <com.android.systemui.statusbar.phone.IconMerger android:id="@+id/notificationIcons" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignParentStart="true" android:gravity="center_vertical" android:orientation="horizontal"/>  
        </LinearLayout>
        <LinearLayout android:id="@+id/system_icon_area" android:layout_width="wrap_content" android:layout_height="match_parent" android:orientation="horizontal">
            <LinearLayout android:id="@+id/statusIcons" android:layout_width="wrap_content" android:layout_height="match_parent" android:gravity="center_vertical" android:orientation="horizontal"/>    
            <LinearLayout android:id="@+id/signal_battery_cluster" android:layout_width="wrap_content" android:layout_height="match_parent" android:paddingStart="2dp" android:orientation="horizontal" android:gravity="center" >
                <include layout="@layout/signal_cluster_view" android:id="@+id/signal_cluster" android:layout_width="wrap_content" android:layout_height="wrap_content" />
                <com.android.systemui.BatteryMeterView android:id="@+id/battery" android:layout_height="16dp" android:layout_width="10.5dp" android:layout_marginBottom="0.33dp" android:layout_marginStart="4dip" />
            </LinearLayout>
            <com.android.systemui.statusbar.policy.Clock android:id="@+id/clock" android:textAppearance="@style/TextAppearance.StatusBar.Clock" android:layout_width="wrap_content" android:layout_height="match_parent" android:singleLine="true" android:paddingStart="6dip" android:gravity="center_vertical|start" />
        </LinearLayout>
    </LinearLayout>
    <LinearLayout android:id="@+id/ticker" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingStart="6dip" android:animationCache="false" android:orientation="horizontal" >
        <ImageSwitcher android:id="@+id/tickerIcon" android:layout_width="@dimen/status_bar_icon_size" android:layout_height="@dimen/status_bar_icon_size" android:layout_marginEnd="4dip" >
            <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:layout_width="0dip" android:layout_weight="1" android:layout_height="wrap_content" android:paddingTop="2dip" android:paddingEnd="10dip">
            <TextView android:textAppearance="@style/TextAppearance.StatusBar.PhoneTicker" android:layout_width="match_parent" android:layout_height="wrap_content" android:singleLine="true" />
            <TextView android:textAppearance="@style/TextAppearance.StatusBar.PhoneTicker" android:layout_width="match_parent" android:layout_height="wrap_content" android:singleLine="true" />
        </com.android.systemui.statusbar.phone.TickerView>
    </LinearLayout>
</com.android.systemui.statusbar.phone.PhoneStatusBarView>
It looks similar to the code at the top of this post but there are significant differences. The @id/icons Layout has been replaced with a @id/status_bar_contents Layout which looks a lot more complex.

But it isn't, really. We can still use the Best Method on it. And it's actually quite easy to do.

The Best Method splits the status bar into two individual areas. The @id/status_bar_contents Layout splits the status bar into two individual areas.

Half the work is done for us.

We just need to make four very simple changes..

Code:
<com.android.systemui.statusbar.phone.PhoneStatusBarView android:id="@+id/status_bar" android:background="@drawable/system_bar_background" android:orientation="vertical" android:focusable="true" android:descendantFocusability="afterDescendants" android:fitsSystemWindows="true"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui">
    <ImageView android:id="@+id/notification_lights_out" android:layout_width="@dimen/status_bar_icon_size" android:layout_height="match_parent" android:paddingStart="6dip" android:paddingBottom="2dip" android:src="@drawable/ic_sysbar_lights_out_dot_small" android:scaleType="center" android:visibility="gone" />
    <LinearLayout android:id="@+id/status_bar_contents" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingStart="6dip" android:paddingEnd="6dip" android:orientation="horizontal" >
        <LinearLayout android:id="@+id/notification_icon_area" android:layout_width="0dip" android:layout_height="match_parent" android:layout_weight="1" android:orientation="horizontal" >
            <com.android.systemui.statusbar.StatusBarIconView android:id="@+id/moreIcon" android:layout_width="@dimen/status_bar_icon_size" android:layout_height="match_parent" android:src="@drawable/stat_notify_more" android:visibility="gone" />
            <com.android.systemui.statusbar.phone.IconMerger android:id="@+id/notificationIcons" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignParentStart="true" android:gravity="center_vertical" android:orientation="horizontal"/>  
        </LinearLayout>
        <com.android.systemui.statusbar.policy.Clock android:id="@+id/clock" android:textAppearance="@style/TextAppearance.StatusBar.Clock" android:layout_width="wrap_content" android:layout_height="match_parent" android:singleLine="true" android:gravity="center_vertical|start" />
        <LinearLayout android:id="@+id/system_icon_area" android:layout_width="0dip" android:layout_weight="1" android:layout_height="match_parent" android:orientation="horizontal">
            <View android:visibility="invisible" android:layout_width="0.0dip" android:layout_height="fill_parent" android:layout_weight="1.0" />
            <LinearLayout android:id="@+id/statusIcons" android:layout_width="wrap_content" android:layout_height="match_parent" android:gravity="center_vertical" android:orientation="horizontal"/>    
            <LinearLayout android:id="@+id/signal_battery_cluster" android:layout_width="wrap_content" android:layout_height="match_parent" android:paddingStart="2dp" android:orientation="horizontal" android:gravity="center" >
                <include layout="@layout/signal_cluster_view" android:id="@+id/signal_cluster" android:layout_width="wrap_content" android:layout_height="wrap_content" />
                <com.android.systemui.BatteryMeterView android:id="@+id/battery" android:layout_height="16dp" android:layout_width="10.5dp" android:layout_marginBottom="0.33dp" android:layout_marginStart="4dip" />
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>
    <LinearLayout android:id="@+id/ticker" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingStart="6dip" android:animationCache="false" android:orientation="horizontal" >
        <ImageSwitcher android:id="@+id/tickerIcon" android:layout_width="@dimen/status_bar_icon_size" android:layout_height="@dimen/status_bar_icon_size" android:layout_marginEnd="4dip" >
            <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:layout_width="0dip" android:layout_weight="1" android:layout_height="wrap_content" android:paddingTop="2dip" android:paddingEnd="10dip">
            <TextView android:textAppearance="@style/TextAppearance.StatusBar.PhoneTicker" android:layout_width="match_parent" android:layout_height="wrap_content" android:singleLine="true" />
            <TextView android:textAppearance="@style/TextAppearance.StatusBar.PhoneTicker" android:layout_width="match_parent" android:layout_height="wrap_content" android:singleLine="true" />
        </com.android.systemui.statusbar.phone.TickerView>
    </LinearLayout>
</com.android.systemui.statusbar.phone.PhoneStatusBarView>
I've highlighted three of those four changes in red. The fourth you can't see as I just deleted the androidaddingStart="6dip" attribute from the clock line, to keep the clock centered.

The View line pushes the contents of the @id/system_icon_area Layout to the far right of the screen. The contents of the other Layout are already on the far left of the screen. So what's between should be in the center..


(thanks to @bobfrantic for the picture)



So that's KitKat, but what about Android 5.0? What about Lollipop?

Well, this is the stock Lollipop status_bar.xml:

Code:
<?xml version="1.0" encoding="utf-8"?>
<com.android.systemui.statusbar.phone.PhoneStatusBarView android:orientation="vertical" android:id="@id/status_bar" android:background="@drawable/system_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">
    <ImageView android:id="@id/notification_lights_out" android:paddingBottom="2.0dip" android:visibility="gone" android:layout_width="@dimen/status_bar_icon_size" android:layout_height="fill_parent" android:src="@drawable/ic_sysbar_lights_out_dot_small" android:scaleType="center" android:paddingStart="6.0dip" />
    <LinearLayout android:orientation="horizontal" android:id="@id/status_bar_contents" android:layout_width="fill_parent" android:layout_height="fill_parent" android:paddingStart="6.0dip" android:paddingEnd="8.0dip">
        <com.android.systemui.statusbar.AlphaOptimizedFrameLayout android:orientation="horizontal" android:id="@id/notification_icon_area" android:layout_width="0.0dip" android:layout_height="fill_parent" android:layout_weight="1.0">
            <com.android.keyguard.AlphaOptimizedLinearLayout android:id="@id/notification_icon_area_inner" android:layout_width="fill_parent" android:layout_height="fill_parent">
                <com.android.systemui.statusbar.StatusBarIconView android:id="@id/moreIcon" android:visibility="gone" android:layout_width="@dimen/status_bar_icon_size" android:layout_height="fill_parent" android:src="@drawable/stat_notify_more" />
                <com.android.systemui.statusbar.phone.IconMerger android:gravity="center_vertical" android:orientation="horizontal" android:id="@id/notificationIcons" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_alignParentStart="true" />
            </com.android.keyguard.AlphaOptimizedLinearLayout>
        </com.android.systemui.statusbar.AlphaOptimizedFrameLayout>
        <com.android.keyguard.AlphaOptimizedLinearLayout android:orientation="horizontal" android:id="@id/system_icon_area" android:layout_width="wrap_content" android:layout_height="fill_parent">
            <include layout="@layout/system_icons" />
            <com.android.systemui.statusbar.policy.Clock android:textAppearance="@style/TextAppearance.StatusBar.Clock" android:gravity="start|center" android:id="@id/clock" android:layout_width="wrap_content" android:layout_height="fill_parent" android:singleLine="true" android:paddingStart="7.0dip" />
        </com.android.keyguard.AlphaOptimizedLinearLayout>
    </LinearLayout>
    <ViewStub android:id="@id/ticker_stub" android:layout="@layout/status_bar_ticker" android:inflatedId="@id/ticker" android:layout_width="fill_parent" android:layout_height="fill_parent" />
</com.android.systemui.statusbar.phone.PhoneStatusBarView>
Look closely and you'll notice that the @id/status_bar_contents Layout is still just divided into two areas: @id/notification_icon_area and @id/system_icon_area.

Adding the Best Method to that shouldn't be a problem at all...
Code:
<?xml version="1.0" encoding="utf-8"?>
<com.android.systemui.statusbar.phone.PhoneStatusBarView android:orientation="vertical" android:id="@id/status_bar" android:background="@drawable/system_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">
    <ImageView android:id="@id/notification_lights_out" android:paddingBottom="2.0dip" android:visibility="gone" android:layout_width="@dimen/status_bar_icon_size" android:layout_height="fill_parent" android:src="@drawable/ic_sysbar_lights_out_dot_small" android:scaleType="center" android:paddingStart="6.0dip" />
    <LinearLayout android:orientation="horizontal" android:id="@id/status_bar_contents" android:layout_width="fill_parent" android:layout_height="fill_parent" android:paddingStart="6.0dip" android:paddingEnd="8.0dip">
        <com.android.systemui.statusbar.AlphaOptimizedFrameLayout android:orientation="horizontal" android:id="@id/notification_icon_area" android:layout_width="0.0dip" android:layout_height="fill_parent" android:layout_weight="1.0">
            <com.android.keyguard.AlphaOptimizedLinearLayout android:id="@id/notification_icon_area_inner" android:layout_width="fill_parent" android:layout_height="fill_parent">
                <com.android.systemui.statusbar.StatusBarIconView android:id="@id/moreIcon" android:visibility="gone" android:layout_width="@dimen/status_bar_icon_size" android:layout_height="fill_parent" android:src="@drawable/stat_notify_more" />
                <com.android.systemui.statusbar.phone.IconMerger android:gravity="center_vertical" android:orientation="horizontal" android:id="@id/notificationIcons" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_alignParentStart="true" />
            </com.android.keyguard.AlphaOptimizedLinearLayout>
        </com.android.systemui.statusbar.AlphaOptimizedFrameLayout>
        <com.android.systemui.statusbar.policy.Clock android:textAppearance="@style/TextAppearance.StatusBar.Clock" android:gravity="start|center" android:id="@id/clock" android:layout_width="wrap_content" android:layout_height="fill_parent" android:singleLine="true" />
        <com.android.keyguard.AlphaOptimizedLinearLayout android:orientation="horizontal" android:id="@id/system_icon_area" android:layout_width="0.0dip" android:layout_height="fill_parent" android:layout_weight="1.0" >
            <View android:visibility="invisible" android:layout_width="0.0dip" android:layout_height="fill_parent" android:layout_weight="1.0" />
            <include layout="@layout/system_icons" />
        </com.android.keyguard.AlphaOptimizedLinearLayout>
    </LinearLayout>
    <ViewStub android:id="@id/ticker_stub" android:layout="@layout/status_bar_ticker" android:inflatedId="@id/ticker" android:layout_width="fill_parent" android:layout_height="fill_parent" />
</com.android.systemui.statusbar.phone.PhoneStatusBarView>
Now, we're nearly there but there's still work to be done.

In Lollipop, the clock on the status bar isn't shown when the device is locked. There's not much need for it when you have a bigger clock on the lockscreen anyway. But, when we move the clock to get it centered, the clock doesn't disappear. It's always visible.

To make the clock vanish when the device is locked, you'll need to do a smali mod. Have a look at this post by @S0bes to see what to do: http://forum.xda-developers.com/show...&postcount=172

*** Using The Best Method On Xperia KitKat ***


For their KitKat ROM's, Sony have done something a bit different with their XML. There's not enough space here for me to say what to do about it, so have a look at my post here instead: http://forum.xda-developers.com/show...&postcount=297


*** Anything Else, Ticklefish? ***


Nope, that's it. This is the longest post in this thread so far. And probably the hardest to follow.

So I'll let you take a break now so you can try some XML modding for yourself.

I'll be updating this thread in time with other fun mods to try. But, for now, have some fun and see what you can come up with.

If you have any questions, or need any help, feel free to ask. I'm always happy to help and I'm hoping that some of the people I've helped over the years will be prepared to help out as well.

One final thing...ALWAYS MAKE A BACKUP!!!

The Following 29 Users Say Thank You to Ticklefish For This Useful Post: [ View ] Gift Ticklefish Ad-Free
5th November 2014, 04:05 PM |#8  
*** android:layout_gravity, android:gravity AND android:layout_weight ***


Centering the clock in the previous two posts wouldn't have been possible without using two particular attributes: 'android:gravity' and 'android:layout_weight'.

In physics, weight is the result of gravity acting on mass. But this isn't physics, it's Android, so what do these attributes actually mean?

*** GRAVITY ***


In Android, the gravity of an object changes how it's laid out in the space it occupies.

Let's have a few practical examples to better explain..

Here's a blank status bar.


Let's add a simple clock to it.

Code:
<com.android.systemui.statusbar.policy.Clock
    android:id="@id/clock"
    android:background="#ff33b5e5"
    android:textColor="#ffffffff"
    android:layout_width="wrap_content"
    android:layout_height="fill_parent"
/>
I've missed a few attributes that you'd normally find in a real XML file, just to keep it simple. But I have added an attribute that sets the background colour to Holo Blue Light. You'll see how useful that is as I continue..

Here's my status bar now.


(DISCLAIMER: This isn't a real status bar. It's just something I put together in a picture-editing program on my PC. Doing these images with a real status bar would take forever...)

Let's add a gravity attribute to get this clock centered..

Code:
<com.android.systemui.statusbar.policy.Clock
    android:id="@id/clock"
    android:gravity="center"
    android:background="#ff33b5e5"
    android:textColor="#ffffffff"
    android:layout_width="wrap_content"
    android:layout_height="fill_parent"
/>
This gives us this..


That didn't work. The android:gravity attribute changes how an object is laid out, but only in its own space. The clock is now centered in that space, but not the statusbar.

So let's expand that space.

Code:
<com.android.systemui.statusbar.policy.Clock
    android:id="@id/clock"
    android:background="#ff33b5e5"
    android:textColor="#ffffffff"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
/>
Which looks like:


Oops, forgot that gravity attribute!

Code:
<com.android.systemui.statusbar.policy.Clock
    android:id="@id/clock"
    android:gravity="center"
    android:background="#ff33b5e5"
    android:textColor="#ffffffff"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
/>
Here's the result.


Better, no?

So what's the difference between android:gravity and android:layout_gravity?

Well, android:layout_gravity affects how an object is laid out, not in its own space, but in its parent Layout.

Let's try using that to center the clock:

Code:
<com.android.systemui.statusbar.policy.Clock
    android:id="@id/clock"
    android:layout_gravity="center"
    android:background="#ff33b5e5"
    android:textColor="#ffffffff"
    android:layout_width="wrap_content"
    android:layout_height="fill_parent"
/>
Here's the result:


So why didn't that work? Well, it really depends on that parent Layout.

In a LinearLayout, some of the layout_gravity attributes are ignored. This would have worked in a RelativeLayout but, as we saw in the Simple Method two posts ago, other objects can overlap the clock.

Generally when you're modding, you normally only worry about layout_gravity when using a RelativeLayout or FrameLayout.

For your reference, here's are the values you can set your gravity to. This is taken direct from Google themselves.

Quote:
Originally Posted by Google

top - Push object to the top of its container, not changing its size.
bottom - Push object to the bottom of its container, not changing its size.
left - Push object to the left of its container, not changing its size.
right - Push object to the right of its container, not changing its size.
center_vertical - Place object in the vertical center of its container, not changing its size.
fill_vertical - Grow the vertical size of the object if needed so it completely fills its container.
center_horizontal - Place object in the horizontal center of its container, not changing its size.
fill_horizontal - Grow the horizontal size of the object if needed so it completely fills its container.
center - Place the object in the center of its container in both the vertical and horizontal axis, not changing its size.
fill - Grow the horizontal and vertical size of the object if needed so it completely fills its container.
clip_vertical - Additional option that can be set to have the top and/or bottom edges of the child clipped to its container's bounds. The clip will be based on the vertical gravity: a top gravity will clip the bottom edge, a bottom gravity will clip the top edge, and neither will clip both edges.
clip_horizontal - Additional option that can be set to have the left and/or right edges of the child clipped to its container's bounds. The clip will be based on the horizontal gravity: a left gravity will clip the right edge, a right gravity will clip the left edge, and neither will clip both edges.
start - Push object to the beginning of its container, not changing its size.
end - Push object to the end of its container, not changing its size.

Most of those you'll rarely, if ever, use while modding. But it's handy to know about them!

*** WEIGHT ***


Weight is a trickier concept to understand.

Google, on their developer website, have this to say about the layout_weight attribute:

Quote:
Originally Posted by Google

The weight value is a number that specifies the amount of remaining space each view should consume, relative to the amount consumed by sibling views. This works kind of like the amount of ingredients in a drink recipe: "2 parts vodka, 1 part coffee liqueur" means two-thirds of the drink is vodka. For example, if you give one view a weight of 2 and another one a weight of 1, the sum is 3, so the first view fills 2/3 of the remaining space and the second view fills the rest. If you add a third view and give it a weight of 1, then the first view (with weight of 2) now gets 1/2 the remaining space, while the remaining two each get 1/4.

In my opinion, this isn't the best explanation ever. It makes things too confusing. (Although it does say a lot about work practices inside Google HQ...clearly I have the wrong job!)

Let me see if I can't explain it a little bit better..

Here's our blank status bar again.


Let's say we want a notification icon and a signal icon here.

Code:
<LinearLayout
    android:orientation="horizontal"
    android:id="status_bar_contents"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
>
    <com.android.systemui.statusbar.phone.IconMerger 
        android:id="@id/notificationIcons"
        android:background="#ff0099cc"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
    />
    <ImageView
        android:id="@id/mobile_signal"
        android:background="#ff33b5e5"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
    />
</LinearLayout>
As before, I've missed out a few attributes that you'd have in the real code, just to make things a bit simpler to read.
And, as before, I've added a background to the signal icon. This time I'm using Holo Blue Dark (I like Holo Blue...).

This makes our status bar look like this:


I'm sure you've noticed on your status bar that the notification icons are on the left and the signal icon on the right. That's easy enough to do with a RelativeLayout or a FrameLayout but, if we have too many notifications, we would be overlapping the signal icon.

So, to do this in a LinearLayout, we use layout_weight.

This attribute essentially sets the priority for the object it's attached to.
By default, an object has a layout_weight of 0 (even if there's no layout_weight attribute in the code). So, if we give an object a layout_weight of 1, Android will allocate it more space.

Let's see it in action by changing the layout_weight of our notification icons to 1:

Code:
<LinearLayout
    android:orientation="horizontal"
    android:id="status_bar_contents"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
>
    <com.android.systemui.statusbar.phone.IconMerger 
        android:id="@id/notificationIcons"
        android:layout_weight="1"
        android:background="#ff0099cc"
        android:layout_width="0.0dip"
        android:layout_height="fill_parent"
    />
    <ImageView
        android:id="@id/mobile_signal"
        android:background="#ff33b5e5"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
    />
</LinearLayout>
Android now gives that object as much space in the Layout as it can, effectively pushing the signal icon to the far right.


Because the width of the notification icon object is being changed by the layout_weight, the layout_width attribute is superseded. So you should always set it to "0.0dip", this stops Android from having to waste processing power that's not needed.
Since this is only the status bar, we're not talking about a lot of power and it's doubtful you'd notice any difference in performance. But it's always good practice.

This is essentially how the standard Android status bar is set up.
Yes, there are more icons and more Layout but, at its heart, there is still a notification area with a weight of 1 pushing a status icon area with a weight of 0 to the right of the screen.
Have a look at your status_bar.xml and you'll see what I mean!

For fun, let's see what happens if we change the weight of the signal icon as well...

Code:
<LinearLayout
    android:orientation="horizontal"
    android:id="status_bar_contents"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
>
    <com.android.systemui.statusbar.phone.IconMerger 
        android:id="@id/notificationIcons"
        android:layout_weight="1"
        android:background="#ff0099cc"
        android:layout_width="0.0dip"
        android:layout_height="fill_parent"
    />
    <ImageView
        android:id="@id/mobile_signal"
        android:layout_weight="1"
        android:background="#ff33b5e5"
        android:layout_width="0.0dip"
        android:layout_height="wrap_content"
    />
</LinearLayout>
This results in:


That looks a bit stupid. But not to worry, we can use a spacer to push that signal icon back to the right of the screen again.

Code:
<LinearLayout
    android:orientation="horizontal"
    android:id="status_bar_contents"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
>
    <com.android.systemui.statusbar.phone.IconMerger 
        android:id="@id/notificationIcons"
        android:layout_weight="1"
        android:background="#ff0099cc"
        android:layout_width="0.0dip"
        android:layout_height="fill_parent"
    />
    <LinearLayout
        android:orientation="horizontal"
        android:layout_weight="1"
        android:layout_width="0.0dip"
        android:background="#ff33b5e5"
        android:layout_height="fill_parent"
    >
        <View
            android:visibility="invisible"
            android:layout_width="0.0dip"
            android:layout_height="fill_parent"
            android:layout_weight="1"
        />
        <ImageView
            android:id="@id/mobile_signal"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
        />
    </LinearLayout>
</LinearLayout>
Here we go..


I've changed the signal icon's weight back to 0 and put it inside a LinearLayout with a View object that has a weight of 1.

The View line pushes the signal icon to the far right but has this attribute: "android:visibility="invisible"". Remember this attribute from a few posts ago? If this is set to !invisible, Android doesn't show it but still pays attention to how much space it uses. Making it the perfect spacer!

Why am I doing this? Well, look what happens if we add a clock to all this code (using a background of Holo Blue Bright this time)...

Code:
<LinearLayout
    android:orientation="horizontal"
    android:id="status_bar_contents"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
>
    <com.android.systemui.statusbar.phone.IconMerger 
        android:id="@id/notificationIcons"
        android:layout_weight="1"
        android:background="#ff0099cc"
        android:layout_width="0.0dip"
        android:layout_height="fill_parent"
    />
    <com.android.systemui.statusbar.policy.Clock
        android:id="@id/clock"
        android:layout_gravity="center"
        android:background="#00ddff"
        android:textColor="#ffffffff"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
    />
    <LinearLayout
        android:orientation="horizontal"
        android:layout_weight="1"
        android:layout_width="0.0dip"
        android:background="#ff33b5e5"
        android:layout_height="fill_parent"
    >
        <View
            android:visibility="invisible"
            android:layout_width="0.0dip"
            android:layout_height="fill_parent"
            android:layout_weight="1"
        />
        <ImageView
            android:id="@id/mobile_signal"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
        />
    </LinearLayout>
</LinearLayout>
Here it is:


Well, would you look at that? We've just centered the clock! Neat!

Let's remove those background attributes..

Code:
<LinearLayout
    android:orientation="horizontal"
    android:id="status_bar_contents"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
>
    <com.android.systemui.statusbar.phone.IconMerger 
        android:id="@id/notificationIcons"
        android:layout_weight="1"
        android:layout_width="0.0dip"
        android:layout_height="fill_parent"
    />
    <com.android.systemui.statusbar.policy.Clock
        android:id="@id/clock"
        android:layout_gravity="center"
        android:textColor="#ffffffff"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
    />
    <LinearLayout
        android:orientation="horizontal"
        android:layout_weight="1"
        android:layout_width="0.0dip"
        android:layout_height="fill_parent"
    >
        <View
            android:visibility="invisible"
            android:layout_width="0.0dip"
            android:layout_height="fill_parent"
            android:layout_weight="1"
        />
        <ImageView
            android:id="@id/mobile_signal"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
        />
    </LinearLayout>
</LinearLayout>
Et voilĂ ...


Have another look at the previous two posts. Hopefully they should make a bit more sense now...
The Following 24 Users Say Thank You to Ticklefish For This Useful Post: [ View ] Gift Ticklefish Ad-Free
5th November 2014, 04:06 PM |#9  
*** Do NOT Edit "public.xml"!! ***


I've seen a lot of tutorials on xda and other forums which say, at some point, something like this:

Quote:

...add these lines to public.xml..

I never do this, I always leave public.xml alone, and it's probably time I explained why.

First, let's take a look at what public.xml actually is and what it does.

You'll find this file in the "res\values\" folder of your decompiled apk and it looks something like this:

Code:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <public type="attr" name="type" id="0x7f010012" />
    .....
    <public type="drawable" name="somc_sys_wifi_signal_null" id="0x7f0201b4" />
    .....
    <public type="mipmap" name="ic_launcher_dreams" id="0x7f030001" />
    .....
    <public type="layout" name="navigation_bar_sw600dp" id="0x7f040009" />
    .....
    <public type="anim" name="wallpaper_recents_launch_from_launcher_exit" id="0x7f05001a" />
    .....
    <public type="xml" name="somc_skin_permissions" id="0x7f060000" />
    .....
    <public type="array" name="config_fullBatteryVibrationPattern" id="0x7f07000f" />
    .....
    <public type="id" name="traffic" id="0x7f0800ac" />
    .....
    <public type="color" name="somc_quick_settings_tabwidget_text_colors" id="0x7f090016" />
    .....
    <public type="bool" name="config_miniTablet" id="0x7f0a0013" />
    .....
    <public type="string" name="done_button" id="0x7f0b00fe" />
    .....
    <public type="integer" name="status_bar_config_maxNotificationIcons" id="0x7f0c0013" />
    .....
    <public type="dimen" name="status_bar_recents_thumbnail_top_margin" id="0x7f0d004f" />
    .....
    <public type="style" name="TextAppearance.StatusBar.PhoneTicker" id="0x7f0e001d" />
    .....
    <public type="plurals" name="status_bar_accessibility_recent_apps" id="0x7f0f0000" />
    .....
    <public type="menu" name="tools_popup_menu" id="0x7f100002" />
    .....
</resources>
This is the public.xml from my phone's SystemUI.apk. I've had to take some of the lines out, the whole file is over 1,300 lines long!

In fact, public.xml is probably the longest XML file you'll have in your APK files. This is because it lists all the individual parts of the APK. All the images, id's, strings, colours, styles, etc.
Each of those parts is allocated an unique hexadecimal reference. These references are known as "Resource ID's". There's a very handy post on stackoverflow that details just how Resource ID's are allocated:

Quote:
Originally Posted by hackbod @ stackoverflow

At build time, the aapt tool collects all of the resources you have defined (though separate files or explicit definitions in files) and assigns resource IDs to them.

A resource ID is a 32 bit number of the form: PPTTNNNN. PP is the package the resource is for; TT is the type of the resource; NNNN is the name of the resource in that type. For applications resources, PP is always 0x7f.

The TT and NNNN values are assigned by aapt arbitrarily -- basically for each new type the next available number is assigned and used (starting with 1); likewise for each new name in a type, the next available number is assigned and used (starting with 1).

So if we have these resource files handled by aapt in this order:

layout/main.xml
drawable/icon.xml
layout/listitem.xml
The first type we see is "layout" so that is given TT == 1. The first name under that type is "main" so that is given NNNN == 1. The final resource ID is 0x7f010001.

Next we see "drawable" so that is given TT == 2. The first name for that type is "icon" so that gets NNNN == 1. The final resource ID is 0x7f020001.

Last we see another "layout" which has TT == 1 as before. This has a new name "listitem" so that gets the next value NNNN == 2. The final resource ID is 0x7f010002.

Note that aapt by default makes no attempt to keep these identifiers the same between builds. Each time the resources change, they can all get new identifiers.

(You can find the original post here: http://stackoverflow.com/questions/6...646113#6646113)

Resource ID's are used in the Java side of the app. Although every part of an APK gets a resource ID allocated to it, not every resource ID is used in the Java.

Here's the line of XML that displays my status bar clock:

Code:
<com.android.systemui.statusbar.policy.Clock
    android:textAppearance= @style/TextAppearance.StatusBar.Clock"
    android:gravity="start|center"
    android:id="@id/clock"
    android:layout_width="wrap_content"
    android:layout_height="fill_parent"
    android:singleLine="true"
    android:paddingStart="6.0dip" />
This is the line in my public.xml that assigns a resource ID to "@id/clock":

Code:
<public type="id" name="clock" id="0x7f08002d" />
And this is a little snippet of smali code that uses that resource ID:

Code:
iget-object v1, p0, Lcom/android/systemui/statusbar/phone/PhoneStatusBar;->mStatusBarView:Lcom/android/systemui/statusbar/phone/PhoneStatusBarView;

const v2, 0x7f08002d

invoke-virtual {v1, v2}, Landroid/view/View;->findViewById(I)Landroid/view/View;

move-result-object v1

invoke-virtual {v1}, Landroid/view/View;->getWidth()I

move-result v1

add-int/2addr v0, v1
So what's the problem with adding lines to public.xml? Well, there's actually three problems..
  1. It's very time-consuming. For everything that you're adding to public.xml, you have to work out what the next available hexadecimal reference is. The resource ID's aren't always in numerical order so you might have to search for the number you want to use to make sure it's not already taken.
    And, if you've got more than one or two lines to add, it's a lot of typing.
  2. It's easy to get wrong. Even if you're adding resource ID's that aren't already taken, you still might get a compiling error saying that the number's too high, or something similar. Which means you have to go back into public.xml, work out another hexadecimal number and try that one. Which takes even more time.
  3. And the main problem....apktool will automatically do it for you anyway! Apktool uses a piece of software called "aapt".
    Sound familiar? It should. Remember that quote from earlier?
    Quote:
    Originally Posted by hackbod @ stackoverflow...again

    At build time, the aapt tool collects all of the resources you have defined (though separate files or explicit definitions in files) and assigns resource IDs to them.


That's right. If you add lines to public.xml, all you're doing is something that would happen when you recompile anyway.

Of course, if you want to waste time and effort doing something completely unnecessary, that's your decision...

*** Don't DELETE "public.xml" Either!! ***


I've seen more than a few posts suggest deleting public.xml, normally if people are having difficulty getting the new resource ID's right.

Hopefully by now, you can see why this isn't necessary but it can also cause your app to crash!

The trouble is that you can't guarantee that the new resource ID's will be the same as the old ones..

Quote:
Originally Posted by hackbod @ stackoverflow...yet again

Note that aapt by default makes no attempt to keep these identifiers the same between builds. Each time the resources change, they can all get new identifiers.

Admittedly, this quote is talking about compiling brand new APK files but the point remains. Remember this line of code from earlier?

Code:
<public type="id" name="clock" id="0x7f08002d" />
If I delete public.xml and recompile my APK, the file will be remade but it's possible that this line will change..

Code:
<public type="id" name="clock" id="0x7f08002e" />
..but the line in the smali won't.

Code:
const v2, 0x7f08002d
So the new app will run, try to display the clock, can't find it and Android will force the app to close.

Whoops.

So, to summarise, if you spot a tutorial or a mod that tells you to edit public.xml.....don't. You never need to.
The Following 11 Users Say Thank You to Ticklefish For This Useful Post: [ View ] Gift Ticklefish Ad-Free
5th November 2014, 04:06 PM |#10  
*** How To Add Seconds To The Clock ***
*** And Display The Date In Any Format You Want ***


(If you're reading this, ignore this post. I'm busy writing it right now..)
The Following 8 Users Say Thank You to Ticklefish For This Useful Post: [ View ] Gift Ticklefish Ad-Free
Post Reply Subscribe to Thread

Tags
center, clock, statusbar, tutorial, xml

Guest Quick Reply (no urls or BBcode)
Message:
Previous Thread Next Thread
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes