Draw Overlay underneath Navigation Bar - android

How can an overlay (of type TYPE_APPLICATION_OVERLAY) be drawn underneath the Navigation bar in Android?
I'm trying to cover the entire screen with a translucent view that allows users to interact with the UI underneath the overlay, but the Navigation bar retains its color.
The status bar was not an issue since I used the following flag - WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS
I'm trying to achieve the above using the following code -
overlay.setBackgroundResource(R.color.colorOverlayGray)
overlay.fitsSystemWindows = false
val layoutFlag = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
} else {
WindowManager.LayoutParams.TYPE_PHONE
}
val params = WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
layoutFlag,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS or
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN or
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE or
WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS,
PixelFormat.TRANSLUCENT
)
params.gravity = Gravity.START or Gravity.TOP
windowManager.addView(overlay, params)

Figured it out. The issue was that I was using MATCH_PARENT as the height, but the height needs to be greater than that.
So now I'm calculating the height of the screen as such -
val displayMetrics = DisplayMetrics()
windowManager.defaultDisplay.getMetrics(displayMetrics)
val height = displayMetrics.heightPixels
And adding the height of the system navigation bar to that.
(Please note that the following code will work in an activity)
var navBarHeight = 0
window.decorView.setOnApplyWindowInsetsListener { view, insets ->
navBarHeight = insets.systemWindowInsetBottom
view.onApplyWindowInsets(insets)
}
And now setting the LayoutParams as such -
val params = WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
height + navBarHeight,
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS or
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE or
WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS,
PixelFormat.TRANSLUCENT
)

You can get the height of the display, including navbar, with getRealMetrics():
val displayMetrics = DisplayMetrics()
windowManager.defaultDisplay.getRealMetrics(displayMetrics)
val overlayHeight = displayMetrics.heightPixels
val overlayWidth = displayMetrics.widthPixels
then create window params:
params = WindowManager.LayoutParams(
overlayWidth,
overlayHeight,
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
OVERLAY_FLAGS,
PixelFormat.TRANSLUCENT
)

Related

Android - Overlay view is drawn at status bar in only tablet or foldable model

I made overlay view and I set this layout params like that.
DisplayMetrics matrix = new DisplayMetrics();
mManager.getDefaultDisplay().getMetrics(matrix);
mParams = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
PixelFormat.TRANSLUCENT
);
mParams.alpha = 0.8f;
mParams.gravity = Gravity.TOP | Gravity.LEFT;
mParams.x = 0;
mParams.y = 0;
But in this case, in tablet or fold model, overlay view is drawn from status bar.
Any other phone are not.. It didn't approach status bar..
how do i solve it??
I want to make overlay view is not drawn at status bar. Only under the status bar.
I put params.y to specific value but all tablet and foldable model have not same status bar.
So It is not what i want.

System Overlay not covering Status bar & Navigation bar Android

I am using Window Service to draw Overlay over screen. But my Overlay not covering the whole screen, It leaves out Status bar and Navigation Bar.
I have tried different approaches to solve it, but didn't find any solution. But the solution is available, as some Apps (Edge Lighting) on Play Store drawing border over full screen(Even on Android O).
My code snippet to achieve the task.
Window Manager
int Layout_Flag;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Layout_Flag = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
}else {
Layout_Flag = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
}
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
Layout_Flag,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.CENTER;
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
windowManager.addView(customView, params);
Drawing Edge
`override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
// draw a shape
val width = measuredWidth
val height = measuredHeight
val strokeWidthCalculation = paint.strokeWidth / 2
path?.moveTo(strokeWidthCalculation, strokeWidthCalculation)
path?.lineTo(width - strokeWidthCalculation, strokeWidthCalculation)
path?.lineTo(width - strokeWidthCalculation, height - strokeWidthCalculation)
path?.lineTo(strokeWidthCalculation, height - strokeWidthCalculation)
path?.close()
paint.pathEffect = cornerPathEffect
canvas.drawPath(path!!, paint)
}`
Result
sample image, not covering status and navigation bar
In order to achieve it, the fourth parameter of WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS.
That's it.
The whole complete code:
val LAYOUT_FLAG: Int
LAYOUT_FLAG = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
} else {
WindowManager.LayoutParams.TYPE_TOAST
}
params = WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
LAYOUT_FLAG, // NOTE
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
or WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
PixelFormat.TRANSLUCENT
)

How to create in Android a head bubble like in Viber (or something like facebook meesenger has)?

I already created head bubble which works perfectly on older API's until 28.
On latest API 29 I can't open on tap app from background.
Here is head bubble screenshot
Screenshot of head bubble when an app is in background
Here is my current code...
override fun onCreate() {
super.onCreate()
mCallHeadView =
LayoutInflater.from(this).inflate(R.layout.call_head, null);
var params: WindowManager.LayoutParams = WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
LayoutParams.TYPE_APPLICATION_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT
)
//val params = LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT, LayoutParams.TYPE_PHONE,
LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT)
params.gravity = Gravity.TOP or Gravity.END
params.x = 0
params.y = 270
mWindowManager = getSystemService(WINDOW_SERVICE) as? WindowManager;
if( mWindowManager != null){
mWindowManager!!.addView(mCallHeadView, params);
}
var closeButton = mCallHeadView!!.findViewById<ConstraintLayout> .
(R.id.callHead)
closeButton.setOnClickListener {
val i = Intent()
i.setClass(this,MainActivity::class.java)
i.flags = Intent.FLAG_ACTIVITY_NEW_TASK
startActivity(i)
stopSelf()
}
Because implementing Bubbles is different in the new versions of Android (28 or higher)
So try to follow Android Documentation or any new tutorial like this

Fullscreen view with gravity.BOTTOM is unwantingly clipped when an overscan value is set

My Android (8.0+) app is implementing a narrow overlay along the bottom of the screen, but when a user sets an overscan value, it disappears. How can I make my view respect what is actually visible so Gravity.BOTTOM will not be clipped? I have tried countless combinations of flags, but nothing seems to ackknowledge the overscan value.
Point screen_size = new Point();
WindowManager.LayoutParams mParams;
WindowManager mWindowManager = getSystemService(WINDOW_SERVICE);
mWindowManager.getDefaultDisplay().getRealSize(screen_size);
layout = new LinearLayout(getApplicationContext());
layout.setOnTouchListener(this);
// color for debug.
layout.setBackgroundColor(0x55ff0000);
mParams = new WindowManager.LayoutParams(
screen_size.x,
40,
0,
0,
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
mParams.gravity = Gravity.BOTTOM;
mWindowManager.addView(layout, mParams);

Move popup window out of screen

Hello i have this code to show popup window...
final WindowManager.LayoutParams parameters = new WindowManager.LayoutParams(
(width/100)*50, height, WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
parameters.gravity = Gravity.CENTER | Gravity.CENTER;
parameters.x = (width/100)*50;
parameters.y = 0;
But i need to show it out of screen...
When i set x position to more then windows size it's stuck at corner and not go over screen...
Thanks.
Edit: Because some people don't know what i mean.. i mean half outside screen not full..
You need to add one more flag which is flag_layout_no_limits
final WindowManager.LayoutParams parameters = new WindowManager.LayoutParams(
(width/100)*50, height,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
parameters.gravity = Gravity.CENTER | Gravity.CENTER;
parameters.x = (width/2);
parameters.y = 0;

Categories

Resources