Guide - MOD - Controlling the Status Bar Views positions without duplicating views
1.- What is this mod for?
Have a look to the video
The goal of this mod is:
- To be able to move to left, center or right any of the exisiting main views in status bar, both in home and keyguard.
- No views duplications, we are using only 1 instance of every view
- An easy way to add more custom views.
- To be able to sort the views on every container out.
2.- Resources needed to understand this mod
- Status bar view mod bitbucket repo
Go to the repo and have a look or clone it or whatever. This is the app i have made to develop this mod. You can change whatever you need to meet your needs.
3.- Environment
I have made this mod for Stock Nougat (7.0) Samsung Galaxy S7E. In the repo, download the rar inside the smali_apk_guide folder. You will find a quick smali and grxsettings guide to setup the mod in stock nougat s7e firmware.
I am not going to explain 1 by 1 every detail. What i am going to do in this post is to explain the idea, the logic and what i had to change and why. The details can be seen in the source code and the rar file in the repo.
4.-
Working on the Layouts
This is the most laborious part of the mod. In nougat status bar in keyguard is in keyguard_status_bar.xml while in the rest of screens it is in status_bar.xml
If you have a look to the modded xmls provided in the rar file in the bucket repo you will see:
- i have added a left and center container in status_bar.xml. As right side container i am using system_icons.xml
- In the keyguard_status_bar, i am using the keyguard_notification_icon_area_inner linear layout as left container, i have embeded a modded system_icons linearlayout as right container and i have added a linearlayout (center_container) as center container
- i have moved inside system_icons a textview related to knox. Since i do not actually know what is this for, i have kept it, because i saw some code in smalies
- I have moved the clock inside the system_icons xml, keeping its position
- I have embedded battery metter view in a linear layout (batterycontainer) since we need to do this if you want to have margins.
- In keyguard layout, i have removed the include system icons and i have added the linear layout with the used views. I moved to this layout the battery level textview
To make the mod in a scaleable way i am using tags in the views. You will see in those xml that i have added a tag to every involved view in the mod. The code of the mod will use these tags and the preferences in GrxSettings as well.
- To make the views to appear nice when the user moves them from one place to another, i have added a paddingstart and paddingend of 3 dip to every involved textview and a margingstart and marginged of 3 dips to every linear. The result seems nice on s7e. May be you need to change these dimensions.
I recommend to start with status_bar and system_icons, when you get them ok, then copy the needed views to keyguard_status xml
1 more important thing about layouts
There are 2 things done by code in the mod related to layouts:
- in status_bar, (layouts controlled by StatusBarIconController class) the code expects the view to be on its original place. What i have done is to move the view to the right container by code.
- There are both in keyguard and home layouts a TwoPhones TextView involved, i have never seen it, but i guess it is related to dual sim phones. This view is added by code. I have modded the methods adding this view in order to add the tag we need for the mod.
Finally to tell something related to visibility.
When we are/leave the keyguard, the original icon and notification areas of the status_bar.xml are hidden. This is done in PhoneStatusBar. From there 4 methods existing in StatusBariconcontroller are called to show/hide notification area or to show/hide icon area.
I have modded those methods to hide - show the new containers. You can see in the java source code (or in the provided smali) how i did it . It is easy.
5.- The logic
Once we know the layouts are ready the logic of this mod is quite simple. We know that there are 3 containers in both status bars. So we init the references to our containers. For keyguard we do this in the onfinishinflate method. For the normal status bar we do it at the end of the Statusbariconcontroller constructor.
To change the position of the views what the mod does is:
- if the mod detects that the views positions have to change, a LinkedHashMap is created. This map is String, View . The string will contain the tag added to the view.
- Go through the left container and add the elements to the map, the same with the center and right container.
- Then we parse the user selection, which has the format tag;position|tag;position|... where | is the separator used in this case.
So, for every tag-view pair what we do is to get from the map the tagged view and to add it to the destination container.
6.- The preferences
GrxPerItemSingleSelection preference allowing to sort out the items.
7.- On Fly
Of course you can use GrxSettings to restart systemui. i have designed the mod to work also in that mode. I have not tested this, but it should. GrxSettings allows to restart any app after a preference change, but i never do mods not on - fly. If you want to use this feature, look into the provided code and do not add the changes related to the observer and phonestatusbar
GrxSettings allows the mods to be updated in different ways. In this case i have added a small observer. I have added the same group key to both preferences. I store the preferences values in a public static class (GrxSettings.smali) in public static fields. For only 2 keys you do not need to use group keys, but if you use same key for many preferences ....
Well, once the observed group key changes, the observer calls to a method in phonestatusbar wich calls to the statusbariconcontroller and keyguardstatusbarview methods to update the positions. Both methods check if their involved preference key´s value changed or not. If it did, then the views are updated.
I have also added a publica class with shared methods used in the mod. You can change these to your own, since i provide the jave source code to make it easier
8.- Adding a view
Well, it should be as easy as:
- Add the view to the initial container you wish it to be
- Add a tag to the view
- Add the entry to the GrxSettings.apk preferences arrays (the tag)
- Change in GrxSettings.smali the default value
- Change in the preferences xml the default value
May be you need to change the two preferences keys if you provide the mod not in a clean install..