#android #layout #uinavigationbar
#Android #макет #uinavigationbar
Вопрос:
У меня есть этот слайдер, который представляет собой вид наложения. Он появляется над панелью навигации, когда она находится под экраном.
При открытии браузера Chrome панель навигации становится черной, а остальное работает нормально.
Я хочу добиться этого эффекта постоянно для панели навигации во время работы слайдера
Здесь находится ползунок наложения кода
import android.content.Context;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import com.sleepycoat.tapxicon.utils.ScreenUtils;
import java.security.InvalidAlgorithmParameterException;
import static android.view.MotionEvent.ACTION_OUTSIDE;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
import static android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN;
import static android.view.WindowManager.LayoutParams.TYPE_PHONE;
/**
* Created by egslava on 24/08/16.
* Unfortunately, Android system is not supported (or I could find how) managing keyboard in windows
* (not activities) that are always on top. So we need to manage keyboard manually.
*/
public class TopScreenDrawerLogic {
private static final String TAG = "TopScreenDrawerLogic";
final Keyboarder keyboarder;
// private final View fakeFocus;
View visibleView;
DrawerView drawer;
ScrollerLogic scroller;
private final ScreenUtils utils;
private final WindowManager wm;
public static final int COMMON_WINDOW_FLAGS =
FLAG_LAYOUT_NO_LIMITS | // for fast "resizing". Window can be moved out of screen
FLAG_NOT_TOUCH_MODAL | // other windows (on the background, that our window is not overlapped) can intercept touch events
FLAG_LAYOUT_IN_SCREEN; // need for right positioning (getting into account status bar)
// when FLAG_LAYOUT_IN_SCREEN is set getHeight() will return value - navigation bar height
public static final int BACKGROUND_WINDOW_FLAGS = COMMON_WINDOW_FLAGS |
FLAG_NOT_FOCUSABLE | FLAG_ALT_FOCUSABLE_IM; // "back" and other hardware buttons will go throw window
public static final int FOREGROUND_WINDOW_FLAGS = COMMON_WINDOW_FLAGS |
// FLAG_LOCAL_FOCUS_MODE |
// FLAG_NOT_TOUCHABLE | // if we want go clicks throw the window
FLAG_WATCH_OUTSIDE_TOUCH; // need to know when user touched outside of window to "unfocus"
private final InputMethodManager imm;
public static WindowManager.LayoutParams createLayout() {
return new WindowManager.LayoutParams(
MATCH_PARENT, MATCH_PARENT, TYPE_PHONE, FOREGROUND_WINDOW_FLAGS, PixelFormat.TRANSLUCENT);
}
//////////////////////////////////////////////////////
// mrtndat add 9/9
//////////////////////////////////////////////////////
public static WindowManager.LayoutParams createLayout(Context context) {
// int w
Point navBarSize = ScreenUtils.getNavigationBarSize(context);
Point screenSize = ScreenUtils.getRealScreenSize(context);
int maxHeight = navBarSize != null ? (screenSize.y - navBarSize.y) :
screenSize.y;
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
PixelFormat.TRANSLUCENT);
// params.gravity = Gravity.TOP;
// params.x = 0;
// int diff = 0;
// if (navBarSize != null) {
// diff = maxHeight - navBarSize.y;
// }
// if (navBarSize != null) {
// params.y = -navBarSize.y 144;
// }
return params;
}
//////////////////////////////////////////////////////
// mrtndat end 9/9
//////////////////////////////////////////////////////
public TopScreenDrawerLogic(DrawerView drawer, View visibleView) {
this.visibleView = visibleView;
this.drawer = drawer;
scroller = new ScrollerLogic(drawer);
keyboarder = new Keyboarder(drawer);
utils = new ScreenUtils(drawer.getContext());
wm = drawer.windowManager;
imm = (InputMethodManager) drawer.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
// this.fakeFocus = fakeFocus;
}
public int minY() {
return 0;
}
public int maxY() {
int[] location = new int[2];
visibleView.getLocationInWindow(location);
int visibleViewTop = location[1];
ViewGroup.MarginLayoutParams margins = (ViewGroup.MarginLayoutParams) visibleView.getLayoutParams();
int visibleViewBottom = visibleViewTop visibleView.getHeight() margins.bottomMargin; //just a bit margin;
return utils.getDisplayHeight() - visibleViewBottom;// - navBarHeight;
}
private int minY(int value) {
return Math.max(value, minY());
}
private int maxY(int value) {
return Math.min(maxY(), value);
}
;
public int boundY(int y) {
return maxY(minY(y));
}
// difference between nearest correct Y value and given
public int yCorrection(int y) {
return y - boundY(y);
}
public int shiftDrawer(int dy) {
return shiftDrawer(dy, false);
}
/**
* shifts drawer and returns new y coordinate
*/
public int shiftDrawer(int dy, boolean animated) {
WindowManager.LayoutParams params = drawer.getLayoutParams();
WindowManager wm = drawer.windowManager;
// params.y = params.y dy;
if (dy > 1500) {
new Throwable().printStackTrace();
}
final int newY = drawer.logic.boundY(params.y dy);
if (animated) {
new TranslateDrawerAnim(drawer, boundY(drawer.getLayoutParams().y (int) dy)/* target layout height */, 250).execute();
} else {
params.y = newY;
wm.updateViewLayout(drawer, params);
}
return params.y;
}
public int shiftDrawerByScreenPercent(float dy, boolean animated) {
return shiftDrawer((int) (utils.getDisplayHeight() / 100.0f * dy), animated);
}
public static final int STATE_UNDEFINED = 0;
public static final int STATE_FOREGROUND = 1;
public static final int STATE_BACKGROUND = 2;
public static final int INITIAL_STATE = STATE_FOREGROUND;
public int state = INITIAL_STATE;
public void resetState(View focusedView) {
if (INITIAL_STATE == STATE_BACKGROUND) {
makeBackground();
} else if (INITIAL_STATE == STATE_FOREGROUND) {
makeForeground();
} else throw new RuntimeException(new InvalidAlgorithmParameterException("Strange state"));
}
public void makeBackground() {
new Throwable().printStackTrace();
Log.d(TAG, "makeBackground()" ", previous state = " stateToString(state));
if (state == STATE_BACKGROUND) return;
state = STATE_BACKGROUND;
imm.hideSoftInputFromWindow(drawer.getWindowToken(), 0);
WindowManager.LayoutParams params = drawer.getLayoutParams();
WindowManager wm = drawer.windowManager;
params.softInputMode = SOFT_INPUT_STATE_ALWAYS_HIDDEN;
params.flags = BACKGROUND_WINDOW_FLAGS;
wm.updateViewLayout(drawer, params);
// final View focus = drawer.findFocus();
// if (focus != null) focus.postDelayed(new Runnable() {
// @Override
// public void run() {
// imm.hideSoftInputFromWindow(drawer.getWindowToken(), 0, new ResultReceiver(new Handler(new Handler.Callback() {
// @Override
// public boolean handleMessage(Message message) {
// fakeFocus.requestFocus();
// keyboarder.applyPos();
// return true;
// }
// })));
// }
// }, 250);
}
public String stateToString(int state) {
switch (state) {
case STATE_BACKGROUND:
return "background";
case STATE_FOREGROUND:
return "foreground";
default:
throw new RuntimeException("Invalid state");
}
}
public void makeForeground() {
new Throwable().printStackTrace();
Log.d(TAG, "makeForeground()" ", previous state = " stateToString(state));
if (state == STATE_FOREGROUND) return;
state = STATE_FOREGROUND;
WindowManager.LayoutParams params = drawer.getLayoutParams();
WindowManager wm = drawer.windowManager;
params.flags = FOREGROUND_WINDOW_FLAGS;
// params.softInputMode = SOFT_INPUT_STATE_UNCHANGED;
params.softInputMode = SOFT_INPUT_STATE_HIDDEN;
// params.softInputMode = SOFT_INPUT_STATE_VISIBLE;
wm.updateViewLayout(drawer, params);
// request focus on focused element. Why? The reason:
// 1. when window is in background state it can't be focused.
// 2. when window is in foreground state some time it focuses last focused element
// 3. when this happens Android shows keyboard but DOESN'T call onFocusChanged
// 4. #Keyboarder class can't process this case correctly and move drawer on keyboard level
// final View focus = drawer.findFocus();
// if (focus != null)focus.postDelayed(new Runnable() {
// @Override
// public void run() {
// focus.requestFocus();
// }
// }, 250);
}
public void dispatchTouchEvent(MotionEvent e) {
Log.d(TAG, "dispatchTouchEvent() called with: " "e = [" e "]");
switch (e.getAction()) {
case ACTION_OUTSIDE:
makeBackground();
break;
default:
makeForeground();
break;
}
}
public boolean delegateOnTouch(MotionEvent e) {
Log.d(TAG, "delegateOnTouch() called with: " "e = [" e "]");
keyboarder.delegateOnTouch(e);
return scroller.delegateOnTouch(e);
}
// need to process keyboard by ourselves
public void delegateOnInputClick(final View v) {
keyboarder.delegateOnInputClick(v);
}
public void delegateOnInputFocus(final View v, final boolean b) {
keyboarder.delegateOnInputFocus(v, b);
}
public boolean delegateOnInterceptTouch(MotionEvent e) {
return scroller.delegateOnInterceptTouch(e);
}
public void callWhenEnterIsPressed() {
}
public void callWhenKeypressed() { // for backpressing
}
public void callWhenKeyboardIsShown() {
}
public void delegateOnKeyPreIme(int keyCode, KeyEvent event) {
keyboarder.delegateOnKeyPreIme(keyCode, event);
}
}
Я хочу добиться такого эффекта браузера Chrome, используя прозрачную активность с наложенным макетом, но снова ползунок появляется над прозрачной активностью.