how to avoid window view to come over Keyboard? - android

I have window view in bottom and when i click on any edittext, keyboard opens but below windows view (Windowview comes over keyboard).
Tried using adjustPan, adjustResize.
Tried using show hide the view as per keyboard visibility but it give Security Exception.
mTabParams = new WindowManager.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_SYSTEM_ALERT |
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSPARENT);
mTabParams.format = PixelFormat.TRANSLUCENT;
mTabParams.height = TAB_BAR_HEIGHT;
mTabParams.gravity = Gravity.BOTTOM;
mWindowmanager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
mWindowmanager.addView(mTabbarLayout, mTabParams);

This worked for me :
params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PRIORITY_PHONE,
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN |
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
WindowManager.LayoutParams.FLAG_SPLIT_TOUCH |
WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
PixelFormat.TRANSLUCENT);
This put the added view behind the keyboard.

Related

Android: Request focus on view (WebView) added via WindowManager

I am showing a webView as an alertDialog from a service when my app is not running on foreground, therefore, My webView is attached to the screen via WindowManager.addView() method.
The webView has an input field which I want to be accessible by the user. Unfortunately, when the user clicks on the input field, it is not showing the keyboard for users to allow input.
My webView is inside a cardView who's params are as follows:
public WindowManager.LayoutParams getParamsForOpenWebView() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
| WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.START | Gravity.TOP;
params.x = left;
params.y = top;
return params;
} else {
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
| WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.START | Gravity.TOP;
params.x = left;
params.y = 200;
return params;
}
}
If I connect the phone to my laptop and use the laptop keyboard to add inputs to the input field, it works fine but it's just that the keyboard on the phone does not pop-up.
Also, the input is inside the webView therefore I cannot use View.requestFocus() to get focus unlike in case of an EditText.
I would really appreciate any help regarding how to request focus to the webView to allow inputs.
Found an answer to the question myself after a while.
I tried a lot of combinations of different flags but none worked, unless I tried
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
| WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
These flags gave the results I wanted and hope it helps someone who goes through the same.

How to change Screen overlay after system ui mode changed(Fullscreen, hide navigation)?

I create overlay:
mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
/*The parent view (actually the root view) the will be added in front of all the windows on the screen*/
mOverlayView = (RelativeLayout) inflater.inflate(R.layout.overlay_control, null);
mWindowManager.getDefaultDisplay().getSize(size);
mWindowSize = new Size(size.x, size.y);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH |
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS |
WindowManager.LayoutParams.FLAG_FULLSCREEN,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.TOP | Gravity.LEFT;
mWindowManager.addView(mOverlayView, params);
I need to move overlay if system UI Visibility changed. There is possibility to detect it(documentation) for view but it not works for overlay. So I only need callback to detect if mode of device changed.
I found the way to do it:
In Android there is OnSystemUiVisibilityChangeListener but it not works if there is not view which will has match_parent value of width or hight.
So I created such overlay and made it 1 px height and match_parent width and add OnSystemUiVisibilityChangeListener to it.

Status bar and overlay

I'm showing a custom overlay with this parameter inflating the view from a service:
params = new WindowManager.LayoutParams(WindowManager
.LayoutParams
.MATCH_PARENT,
statusBarHeight, WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, WindowManager
.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams
.FLAG_NOT_FOCUSABLE, 0);
params.gravity = Gravity.CENTER | Gravity.TOP;
The problem is that if the status bar is expanded, the overlay is over the quick settings menu. How can I avoid that? I'm using android 6.
Instead of TYPE_SYSTEM_OVERLAY use TYPE_SYSTEM_ERROR.
params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
100,
// Allows the view to be on top of the StatusBar
WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
// Keeps the button presses from going to the background window
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
// Enables the notification to recieve touch events
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
// Draws over status bar
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.TOP|Gravity.CENTER;
mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
mWindowManager.addView(mView, mLP);
This should solve your issue.

Showing a view in WindowManager that can come from "out of screen"

I'm having the following issue - I'm having a view that I'm putting inside the WindowManager
and I would like it to come in translate animation from out of the screen and toward the middle of the screen.
Unfortunately, no matter what I do the view sticks to the axis.
This is the code:
view = (FrameLayout) LayoutInflater.from(this).inflate(
R.layout.poke, null);
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
300, 400, WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);
params.verticalMargin = -10f;
params.gravity = Gravity.TOP;
windowManager.addView(view, params);
As you can see I tried playing with the margin (put there minus to make it go up).
By the way - I know that it's ugly to put numbers and not dp in dimen.xml. Its just a test code..
I just faced the same issue and the actual flag is:
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
So your code should look like:
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
300, 400, WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
PixelFormat.TRANSLUCENT);
In the flags that you are specifying, add another flag FLAG_LAYOUT_NO_LIMITS.
That should allow you to place your views even outside the screen.
Your code should look like this:
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
300, 400, WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
PixelFormat.TRANSLUCENT);

Screenorientation in addview()

I add view by addView() and I want to block screen orientation on that view to portrait.
I tried:
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.FILL_PARENT,
WindowManager.LayoutParams.FILL_PARENT,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
| WindowManager.LayoutParams.FLAG_FULLSCREEN,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.CENTER | Gravity.TOP;
params.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
LinearLayout glass = new LinearLayout(this);
glass.setBackgroundResource(R.drawable.glass6);
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
wm.addView(glass, params);
It doesn't work.
How can I do it?
Also how can I do that my new view do not dissapear after app close?
Try this
glass.setOrintation(Configuration.ORIENTATION_LANDSCAPE)
Use android:screenOrientation="landscape" or android:screenOrientation="portrait" in your manifest file.To restrict your activity to be viewed in portrait or landscape mode.

Categories

Resources