How to get statusbar height in Android XML layout? - android

I have two same screens, with a logo at the center of the screen.
However, one screen has statusbar height considered while the other one doesn't, so the position of the logo does not match between the two.
This is the code on xml.
screen 1
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/blue" />
<item
android:height="200dp"
android:width="200dp"
android:gravity="center"
android:drawable="#mipmap/ic_launcher_foreground">
</item>
</layer-list>
screen 2
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/blue"
android:gravity="center">
<ImageView
android:layout_height="200dp"
android:layout_width="200dp"
android:layout_marginBottom = "39dp"
android:scaleType="centerCrop"
android:src="#mipmap/ic_launcher_foreground"/>
</LinearLayout>
I use galaxy s10, which has height of statusbar of 39dp.
Now I can manually set margin of 39 to match the position of the logo(like the code above), but that is only for one specific device(which is s10). I need to set the margin dynamically for different mobile devices.
How do I do this? and why does one screen integrates the status bar height while the other doesn't?
P.s. This is a react-native project.

Related

How can I limit the gradient in Android Studio?

I'm developing my first app in Android studio and I have some styles applied to it, and one of them is a gradient background but I want to limit it.
This is my actual view:
The graident goes from top to bottom perfectly, but I want the gradient to occupy 1/4 of the screen, how can I do it? I've been looking on the internet but I didn't find a solution. Up to the red line for example:
How can I do it?
This is my actual drawable:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<gradient
android:angle="-90"
android:startColor="#3cba92"
android:endColor="#e6e9f0"
/>
</shape>
</item>
</selector>
Rather than modifying your drawable, why don't create an empty layout which has height as 1/4th of the screen and background as your drawable.
The rest of your code will remain as it is and should have no background.
For example, this can be done easily using a constraint layout as follows.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:weightSum="1"
>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="250dp"
android:background="#drawable/background_gradient"
app:layout_constraintTop_toTopOf="parent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
Note : You can set the height programatically by measuring the screen size and dividing it by 4.

Android bottomRightRadius + elevation results in gray bar

I'm running into some really strange behaviour when running this (test) layout on my OnePlus6T but it works fine when i run it in the emulator.
There is a gray bar appearing below the FrameLayout which increases/decreases in size depending on the elevation (smaller elevation means wider but less tall bar).
It only occurs when using a combination of an elevation and corner specific radius (using plain android:radius instead of bottomRightRadius makes it appear normal). Also, when I change the outlineProvider from background to something else, it works as well.
Can anyone confirm this behaviour on other phones and/or is it a known bug? I tried it on a friends Moto X4 and it works fine there.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#DCDCDC"
tools:context=".MainActivity">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="40dp"
android:layout_marginTop="40dp"
android:layout_marginEnd="40dp"
android:layout_marginBottom="40dp"
android:background="#drawable/background_rounded"
android:outlineProvider="background"
android:elevation="100dp">
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
#drawable/background_rounded.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#android:color/white" />
<corners android:bottomRightRadius="64dp" />
</shape>
Screenshot from my 6T
Screenshot from API28 Emulator

How to convert layout to drawable for use in splash screen

Background information
When a user enters my Android application. They are first taken to LoginActivity. LoginActivity takes some time to load as it is also responsible for performing background sqlite migrations as well as other housekeeping tasks (this takes 500-1000ms).
Unfortunately, the user sees a blank screen during this entire time. As setContentView has not executed yet.
I am trying to remediate this problem by following the guides
https://android.jlelse.eu/launch-screen-in-android-the-right-way-aca7e8c31f52
https://www.bignerdranch.com/blog/splash-screens-the-right-way/
They tell me I need to create a background_splash.xml in drawables and point to it using a custom style with <item name="android:windowBackground">#drawable/background_splash</item>
Unfortunately I noticed that I am not able to control padding margin width height, gravity of my logo in drawables.
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="#color/gray"/>
<!-- cant control android:margin=... (my min API is 21) -->
<!-- cant control android:width=... (my min API is 21) -->
<!-- cant control android:height=... (my min API is 21) -->
<item>
<bitmap
android:gravity="center"
android:src="#mipmap/ic_launcher"/>
</item>
</layer-list>
My problem
How to properly achieve same behavior (or at least similar) as my current activity_login.xml file and convert that into a drawable?
My code
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.LinearLayoutCompat
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/material_red_500">
<!--***********************************************************
* Layout section: The login logo
************************************************************-->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<android.support.v7.widget.AppCompatImageView
android:layout_centerInParent="true"
android:src="#drawable/image_symbol_lock"
android:scaleType="fitCenter"
android:layout_width="150dp"
android:layout_height="150dp"/>
</RelativeLayout>
<!--***********************************************************
* Layout section: The login button (facebook)
************************************************************-->
<android.support.v7.widget.AppCompatTextView
android:id="#+id/button_facebook"
android:paddingTop="28dp"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:paddingBottom="28dp"
android:background="#color/material_blue_500"
android:text="LOG IN"
android:textSize="32sp"
android:textColor="#color/white"
android:gravity="center_horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</android.support.v7.widget.LinearLayoutCompat>
You can create a layout_splash with your own design and in the Splash style only set a background color. So first you will see the background color and not the blank and next see the layout. You could do this with the login activity.

Android : Rounded-edges view grow within another rounded-edges view

I am trying to make two rounded edges views, A and B, in Android. Both views have the same corner radius but B is within A or B should look like within A.
B's width is dynamic according to the percentage below. When the percentage is more than 5%, this works perfectly fine. However, as the percentage is less than 5%, it will turn out like the failure-figure below. They look like completely independence views, though they actually are. I need the green part grows within the gray area only. How can this be accomplished?
Ideally, it should look like
But I failed to make it. :/ The figure I got
Here is what I did, define a drawable as given below
<RelativeLayout
android:id="#+id/percentageBarViewGroup"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<View
android:id="#+id/a_Bar"
android:layout_width="match_parent"
android:layout_height="20dp"
android:background="#drawable/progress_bar_empty_background"/>
<View
android:id="#+id/b_Bar"
android:layout_width="0dp"
android:layout_height="20dp"
android:background="#drawable/progress_bar_progressing_background"/>
</RelativeLayout>
You should use nested views and padding .
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<FrameLayout
android:id="#+id/a_Bar"
android:layout_width="match_parent"
android:layout_height="20dp"
android:background="#drawable/progress_bar_empty_background">
<View
android:id="#+id/b_Bar"
android:layout_width="0dp"
android:layout_height="match_parent"
android:background="#drawable/progress_bar_progressing_background"/>
</FrameLayout>
</RelativeLayout>
At the end add stroke to your progress_bar_progressing_backgroundwith the same color as progress_bar_empty_background.
something like this :
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="3dp"/>
<stroke android:width="2dp" android:color="#222"/>
<solid android:color="#fff"/>
</shape>

How to make an identic layout after splash screen

My splash screen is a layer-list drawable as background in app theme. Here is it:
background_splash.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="#color/dark_blue"/>
<item android:top="100dp">
<bitmap
android:gravity="top"
android:src="#mipmap/img_logo"/>
</item>
</layer-list>
As you see, I place the logo with margin 100dp from the top. Then I try to do the same in my fragment layout:
fragment_start.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#mipmap/bg_create_account">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#mipmap/img_logo"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="100dp" />
</RelativeLayout>
But the logo in the layout appears lower than logo on the splash screen. I thought, the problem is in the default margin of Activity. But if I set:
<dimen name="activity_horizontal_margin">0dp</dimen>
<dimen name="activity_vertical_margin">0dp</dimen>
Nothing still happens. I always see the "jump" of logo from top to down about 10-20 dp. How can I avoid it?
EDIT: My activity xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"/>
</LinearLayout>
EDIT 2: I tried to pick up the distance manually and if I set <item android:top="125dp"> (or 126dp) and leave android:layout_marginTop="100dp" I see no "jump". It means the difference is 25 or 26 dp, but where are they?
EDIT 3: according to answer from Bryan the issue exists only in Android 4.4(API 19) and above. To avoid it I overrode styles.xml in folder values-19 with:
<item name="android:windowTranslucentStatus">true</item>
It seems drawable that you use for the splash screen does not take into account the size of the status bar, but the Activity does. This is the ~25dp difference you are observing, though this height of ~25dp is not guaranteed to be the same on all devices.
Maybe the problem is in the ActionBarSize, try add this to the SplashScreen :
Without AppCompat
android:paddingTop="?android:attr/actionBarSize"
With AppCompat
android:paddingTop="?attr/actionBarSize"
Or if you want, (although may be considered a bad practice), you can set a negative padding in the Activity Layout using data binding :
android:paddingTop="#{-1 * ?android:actionBarSize}"

Categories

Resources