Using ActionBarSherlock; experiencing View.getLocationOnScreen() inconsistency between 2.2 and ICS/JB - android

I have a RelativeLayout whose size takes up all screen area that is available to the containing Activity. That is, it fills all screen area except for the notification bar.
I am using ActionBarSherlock. The ActionBar is set to overlay mode using getWindow().requestFeature(Window.FEATURE_ACTION_BAR_OVERLAY). Therefore, the height of my RelativeLayout spans from immediately below the notification bar right down to the bottom of the screen, and any child Views it holds could potentially be placed behind the ActionBar. The ActionBar is therefore definitely operating in overlay mode. I confirm this is the case on devices running 2.2, 4.0.x(ICS) and 4.1(JB).
Because my application implements a drag-and-drop mechanism within this RelativeLayout, I need to know the layout's position on the screen so that I can correct the absolute screen Y touch values returned by getRawY(). To achieve this, after the layout phase has been done, I have been calling mRelativeLayout.getLocationOnScreen() inside of onWindowFocusChanged().
On my 4.0 and 4.1 devices, the call to getLocationOnScreen() produced a Y value that matched the height, in pixels, of the very top notification bar. In order to determine the height of the notification bar and ActionBar combined, I would add the Y value returned by getLocationOnScreen() to the result of ActionBarSherlock's getHeight() method.
The problem is that when testing on a 2.2 device, getLocationOnScreen() is returning a Y value that is already the notification bar height plus the ABS height. This is the case even though the ABS is set to overlay mode.
There are a few questions on SO regarding implausable results from getLocationOnScreen(); the one here has an answer which gives me the idea to just abandon getLocationOnScreen() and instead calculate the RelativeLayout's top Y offset by subtracting the layout's height from the total screen height:
DisplayMetrics dm = new DisplayMetrics();
this.getWindowManager().getDefaultDisplay().getMetrics(dm);
int mRelativeLayoutYOffs = dm.heightPixels - mRelativeLayout.getMeasuredHeight();
What I find bizarre about the result of this though is that it seems to give me the same inconsistency as I get from getLocationOnScreen(). What happens on 2.2 is that the call to .getMeasuredHeight() on the RelativeLayout actually seems to be giving a height value that has the ActionBar height subtracted from the actual height of the RelativeLayout, even though the ABS is set to overlay and that I have visually confirmed it is definitely in overlay mode.
The best strategy I can think of doing at the moment is to just treat the result of getLocationOnScreen() differently depending on the operating system version. If it's 2.2, then I know it includes the ABS height. If 4.0 onwards, it doesn't. Anything between 2.2 and 4.0, I'm not yet sure. Perhaps people can help fill those details in. Perhaps the difference is introduced in OS versions that support the ActionBar natively? If it is predictable and well defined what the behaviour is, then hopefully this would be a safe strategy.
Failing that, are there any suggestions for other means of determining the RelativeLayout's top and left screen positions in order to correct the absolute screen touch values?

The problem was because I should not have been using getWindow().requestFeature(Window.FEATURE_ACTION_BAR_OVERLAY). Intead, my custom style (which inherits from a parent ActionBarSherlock theme) needed to contain:
<item name="android:windowActionBarOverlay">true</item>
<item name="windowActionBarOverlay">true</item>
Furthermore, I was wrong in saying that on 2.2 the ABS was working in overlay mode - in fact, it wasn't. Now that I'm using the above style items, it is now working in overlay mode in 2.2.
.getLocationOnScreen() is now correctly returning a Y value that only represents the notification bar height on my 2.2, 4.0 and 4.1 devices.

Related

How to Create Custom Notification with Standard Height in Android 7?

I created a custom notification with standard height (not the expanded version described with bigContentView) which works fine with Android 4 up to 6.
In Android 7 the design of the notifications was changed, the third line which used to be at the bottom is now at the top, and the notifications are higher than before. But for unknown reason my custom notification is not enlarged accordingly and now looks like a foreign object between the other notifications.
I am using android:layout_height="match_parent" and also experimented with fixed height, but without success.
Is there a way in Android 7 to let my notifications look great again, or is there a bug in that OS version?
The picture the link points to shows three notifications. The first and last ones are 99 pixels high, while my custom notification is 85 pixels high.
Custom Notification
I was having a problem with my notification layout on Android 7. Setting the parent with fixed height such as 64dp and having its childen's height set to match parent was resulting in a weird UI with empty spaces on the top and bottom. I resolved it by setting the children's height to 64dp instead of match_parent. Hope this helps.

How to design a page that supports Android N(Nougat) API 24(Multi Window design)?

I have some doubts regarding creating perfect design that supports Multi Window feature(from API 24). Please find below for some of my doubts.
Width and Height of a page till Marshmallow(API 23) is fixed size,
from Nougat(API 24) width and height of application will change
based on full screen mode, split-screen mode and free-form mode. How to handle these
kind of width and height related issues?
If in normal mode for example 4 big images are filling my complete
width of the device, if we change it to multi window mode then width
gets reduced means then those 4 images will not fit in the UI. How
to handle these kind of situations?
Do we need to take care of text sizes and other attributes for both
normal and multi window mode? If yes how to do that?
Any other thing we need to keep in mind when designing a layout that
support API 24?
Now your screens should be adapted for different screen sizes. You can process this by obtaining screen width and height in runtime and fit your design dynamically. It is a long way but if you want a perfect-fit design, I think it's the most appropriate approach.
If you don't need such a flexible screen, you can set android:minimalHeight and/or android:minimalWidth and be sure that all major UI elements are always visible.
If you don't want to be so strict you can use ScrollView not to depend on height of the screen and android:layout_width="match_parent" to be independent of screen width. Actually, in this case, you should test your app on various devices to make sure that all app sections are displayed correctly.
Several other things which you need to care about you can find in article http://blog.azoft.com/android-7-0-nougat-features-for-business-apps/.

what is the screen area returned by getWindowManager().getDefaultDisplay()?

I am trying to get the available screen area of my app programmatically.
To do so I am using getWindowManager().getDefaultDisplay().getSize() . However I am not quite sure of what is exactly the screen area corresponding to this 'Default Display Window'.
It seems to incorporate the whole screen (including the notification bar) except the navigation bar. Is this correct ? Are there exceptions ?
From the documentation:
Gets the size of the display, in pixels.
Note that this value should not be used for computing layouts, since a
device will typically have screen decoration (such as a status bar)
along the edges of the display that reduce the amount of application
space available from the size returned here. Layouts should instead
use the window size.
The size is adjusted based on the current rotation of the display.
The size returned by this method does not necessarily represent the
actual raw size (native resolution) of the display. The returned size
may be adjusted to exclude certain system decoration elements that are
always visible. It may also be scaled to provide compatibility with
older applications that were originally designed for smaller displays.
Emphasis mine. So yes, it's possible they might exclude the navigation bar from it, but not necessarily.
Yes, it includes all space usable by your application (i.e., not counting OS level components like the status and notification bar).
However, the size does change based on whether use you methods such as setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION); which hides the notification and status bar and gives your application temporarily more room.

How do I get the size of the navigation bar on a Kindle tablet?

I'm working with the Kindle Fire HD 8.9", and unlike other Android tablets, its navigation bar (Back, Home, etc.) resides on the right edge of the device rather than the bottom edge. This is causing layout issues for myself since I need to calculate sizes as a percentage of the available screen width.
I've tried Display#getPoint(Point), as the Javadoc wording makes it sound like it will exclude system decor, but it does not for this device. I'm also aware of setting a OnLayoutChangeListener on my root view, but I need to know the available size prior to when this listener is triggered.
So is there a way to get the size of the navigation bar programmatically? I've calculated the size to be 90px, but I want to avoid hardcoding as it's risk-prone.

AbsoluteLayout - do I have an alternative?

In an app I'm developing, I need to layout 2 to 5 buttons as if on the edge of a circle. The app starts with 5 buttons, but buttons gradually disappear (based on user input) until there are 2 of them.
I thought I would use an AbsoluteLayout control, and set the position of each button in code (taking into account the screen size). However, it says more or less everywhere that AbsoluteLayout should not be used. Since I'm targeting this app to Android 2.2 and up, I can't use the fancier layouts introduced with ICS.
I know I can use a RelativeLayout and play with the margins, but this seems less intuitive, and just as error prone, as using AbsoluteLayout.
Do I have any reasonable alternative?
I think, you dont have many alternatives. Except relative layout you mentioned, you could of course use FrameLayout and set left and bottom margin to position your buttons correctly.

Categories

Resources