I have SingleFramgnetActivity whose purpose is only to hold and replace fragments inside it.
layout looks like this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:gravity="center_horizontal"
android:orientation="vertical"
tools:context=".SingleFragmentActivity"
>
<include layout="#layout/toolbar"/>
<FrameLayout
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
I'm replacing the Fragments inside the FrameLayout. When I set the fitsSystemWindows to true on the Fragment layout, it is not responding. Actually it is working only when Activity is created, but once I replace the Fragment inside the FrameLayout, the fitsSystemWindows parameter is ignored and the layout is below the status bar and navigation bar.
I found some solution with custom FrameLayout which is using deprecated methods, but for some reason it is not working for me (same result as with normal FrameLayout) and I also do not like the idea to use deprecated methods.
Your FrameLayout is not aware of window inset sizes, because it's parent - LinearLayout hasn't dispatched it any. As a workaround, you can subclass LinearLayout and pass insets to children on your own:
#TargetApi(Build.VERSION_CODES.KITKAT_WATCH)
#Override
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
int childCount = getChildCount();
for (int index = 0; index < childCount; index++)
getChildAt(index).dispatchApplyWindowInsets(insets); // let children know about WindowInsets
return insets;
}
You can have a look to my this answer, which will explain detailed how this works, and also how to use ViewCompat.setOnApplyWindowInsetsListener API.
You could also build a custom WindowInsetsFrameLayout and use a OnHierarchyChangedListener to request applying the insets again:
public WindowInsetsFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
// Look for replaced fragments and apply the insets again.
setOnHierarchyChangeListener(new OnHierarchyChangeListener() {
#Override
public void onChildViewAdded(View parent, View child) {
requestApplyInsets();
}
#Override
public void onChildViewRemoved(View parent, View child) {
}
});
}
Check out this detailed answer: https://stackoverflow.com/a/47349880/3979479
I think the problem revolves around onApplyWindowInsets getting called before the fragment view hierarchy gets attached. An effective solution is to get the following override on a view somewhere in the view hierarchy of the fragment.
#Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
// force window insets to get re-applied if we're being attached by a fragment.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
requestApplyInsets();
} else {
//noinspection deprecation
requestFitSystemWindows();
}
}
A complete solution (if you don't have to use CoordinatorLayout) follows. Make sure fitSystemWindows=true does not appear ANYWHERE in views higher in the heirarchy. Maybe not anywhere else. I suspect (but am not sure) that consumeSystemWindowInsets eats the insets for views that are further on in the layout order of the view tree.
package com.twoplay.xcontrols;
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Rect;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;
import android.view.WindowInsets;
import android.widget.FrameLayout;
public class FitSystemWindowsLayout extends FrameLayout {
private boolean mFit = true;
public FitSystemWindowsLayout(final Context context) {
super(context);
init();
}
public FitSystemWindowsLayout(final Context context, final AttributeSet attrs) {
super(context, attrs);
init();
}
public FitSystemWindowsLayout(final Context context, final AttributeSet attrs, final int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
setFitsSystemWindows(true);
}
public boolean isFit() {
return mFit;
}
#Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
requestApplyInsets();
} else {
//noinspection deprecation
requestFitSystemWindows();
}
}
public void setFit(final boolean fit) {
if (mFit == fit) {
return;
}
mFit = fit;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
requestApplyInsets();
} else {
//noinspection deprecation
requestFitSystemWindows();
}
}
#SuppressWarnings("deprecation")
#Override
protected boolean fitSystemWindows(final Rect insets) {
if (mFit) {
setPadding(
insets.left,
insets.top,
insets.right,
insets.bottom
);
return true;
} else {
setPadding(0, 0, 0, 0);
return false;
}
}
#TargetApi(Build.VERSION_CODES.KITKAT_WATCH)
#Override
public WindowInsets onApplyWindowInsets(final WindowInsets insets) {
if (mFit) {
setPadding(
insets.getSystemWindowInsetLeft(),
insets.getSystemWindowInsetTop(),
insets.getSystemWindowInsetRight(),
insets.getSystemWindowInsetBottom()
);
return insets.consumeSystemWindowInsets();
} else {
setPadding(0, 0, 0, 0);
return insets;
}
}
}
Suspicion, not fact: that only one view in the entire hierarchy gets a chance to eat the window insets, UNLESS you have CoordinatorLayout in the hierarchy, which allows more than one direct child to have FitSystemWindow=true. If you do have a CoordinatorLayout, your mileage may vary.
This entire feature in Android seems to be an unholy mess.
a) you can use CoordinatorLayout as your root view inside fragment
or
b) you can create custom linear layout what will call requestApplyInsets and use it as your root view inside fragment
class WindowInsetsLinearLayout : LinearLayout {
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
override fun onAttachedToWindow() {
super.onAttachedToWindow()
ViewCompat.requestApplyInsets(this)
}
}
and then inside fragment you can catch applying insets
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
ViewCompat.setOnApplyWindowInsetsListener(root_layout) { _, insets ->
//appbar.setPadding(insets.systemWindowInsetLeft, insets.systemWindowInsetTop, 0, 0)
insets.consumeSystemWindowInsets()
}
}
Related
I would like to disable sound effects when browsing over RecycleView items and also clicking sounds in an Android TV app. But, I do not want to disable all other sounds (e.g., There is Exoplayer in the app that its output sounds should not be muted).
I noticed there are some other questions similar to this on Stackoverflow and the suggested solutions are:
Disable Sound effect in the Layout Files by setting android:soundEffectsEnabled="false" (I put this in every Layout). However, this does not have any effect and there is still clicking and item browsing sound effects.
Disable sound effects using AudioManager. I tried the following:
audioManager.adjustStreamVolume(AudioManager.STREAM_NOTIFICATION, AudioManager.ADJUST_MUTE, 0); and audioManager.adjustStreamVolume(AudioManager.STREAM_SYSTEM, AudioManager.ADJUST_MUTE, 0); These mute all app sounds including Media sounds.
I would be grateful if someone can help with this issue. Thanks
Finally I found a solution for this problem.
Issue 1: Disabling sound effect on pressing DPAD_CENTER key. I could resolve this issue by programmatically disabling sound effect in CardPresenter (for Leanback ListRowPresenter) and CardAdapter (for RecyclerView).
Issue 2: Disabling sound effect on pressing DPAD navigation keys (DPAD_RIGHT, DPAD_LEFT, ...). Digging into the ViewRootImpl.java class, it turns out that navigation sound is always played without checking the soundEffect flag. Here is parts of the code in ViewRootImpl.java
if (v.requestFocus(direction, mTempRect)) {
boolean isFastScrolling = event.getRepeatCount() > 0;
playSoundEffect(
SoundEffectConstants.getConstantForFocusDirection(direction,
isFastScrolling));
return true;
So a workaround that I came up with is to override the requestFocus method in my views and always return false to prevent playing sound effect.
Code for Leanback ListRowPresenter:
CardPresenter.java
public class CardPresenter extends Presenter {
....
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent) {
....
Context mContext = parent.getContext();
CustomImageCardView mCardView = new CustomImageCardView(mContext);
mCardView.setSoundEffectsEnabled(false);
return new ViewHolder(mCardView);
}
CustomImageCardView.java
public class CustomImageCardView extends ImageCardView {
public CustomImageCardView(Context context, int themeResId) {
super(context, themeResId);
}
public CustomImageCardView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public CustomImageCardView(Context context) {
super(context);
}
public CustomImageCardView(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
public boolean requestFocus(int direction, Rect previouslyFocusedRect) {
super.requestFocus(direction, previouslyFocusedRect);
return false;
}
}
Code for RecyclerView:
CardAdapter.java
public class CardAdapter extends RecyclerView.Adapter<CardAdapter.ViewHolder> {
...
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = mLayoutInflater.inflate(R.layout.recycler_view, viewGroup, false);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
view.setFocusable(true);
view.setSoundEffectsEnabled(false);
}
mViewHolder = new ViewHolder(view);
return mViewHolder;
}
CustomLinearLayout.java (Root View for Recycler View)
public class CustomLinearLayout extends LinearLayout {
public CustomLinearLayout(Context context) {
super(context);
}
public CustomLinearLayout(Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
}
public CustomLinearLayout(Context context, #Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public CustomLinearLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
#Override
public void playSoundEffect(int soundConstant) {
super.playSoundEffect(soundConstant);
}
#Override
public boolean requestFocus(int direction, Rect previouslyFocusedRect) {
super.requestFocus(direction, previouslyFocusedRect);
return false;
}
}
If you just want to mute android tv navigation system sound effect and there is no custom navigation behavior, I found a way by overriding onKeyDown.
First, I added a GlobalFocusChangeListener at Activity and Dialog to listen and keep the reference of focused view.
window.decorView.viewTreeObserver.addOnGlobalFocusChangeListener { oldFocus, newFocus ->
focusView = newFocus
}
Second, I overrided onKeyDown method at Activity and Dialog and implement like this.
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
focusView?.let {
when (keyCode) {
KeyEvent.KEYCODE_DPAD_UP -> View.FOCUS_UP
KeyEvent.KEYCODE_DPAD_DOWN -> View.FOCUS_DOWN
KeyEvent.KEYCODE_DPAD_LEFT -> View.FOCUS_LEFT
KeyEvent.KEYCODE_DPAD_RIGHT -> View.FOCUS_RIGHT
else -> null
}?.let { direction ->
val nextFocusView = it.focusSearch(direction)
if (nextFocusView != null) {
nextFocusView.requestFocus()
return true
}
}
}
return super.onKeyDown(keyCode, event)
}
This is work on android tv emulator and my Xiaomi TV. I think this change will not effect any touch behavior on phone or tablet.
Step 1. Create a new app with Navigation Drawer template.
Step 2. Add a customized button and override the onMeasure method.
#CoordinatorLayout.DefaultBehavior(MyButton.Behavior.class)
public class MyButton extends android.support.v7.widget.AppCompatButton {
private ViewTreeObserver.OnPreDrawListener mPreDrawListener;
public MyButton(Context context) {
super(context);
}
public MyButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (mPreDrawListener == null) {
mPreDrawListener = new ViewTreeObserver.OnPreDrawListener() {
#Override
public boolean onPreDraw() {
offsetTopAndBottom(50);
return true;
}
};
ViewParent p = getParent();
if (p instanceof View) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
((View)p).getViewTreeObserver().addOnPreDrawListener(mPreDrawListener);
}
}
}
}
public static class Behavior extends CoordinatorLayout.Behavior<MyButton> {
#Override
public boolean onLayoutChild(CoordinatorLayout parent, MyButton child, int layoutDirection) {
final List<View> dependencies = parent.getDependencies(child);
return super.onLayoutChild(parent, child, layoutDirection);
}
#Override
public void onAttachedToLayoutParams(#NonNull CoordinatorLayout.LayoutParams lp) {
if (lp.dodgeInsetEdges == Gravity.NO_GRAVITY) {
// If the developer hasn't set dodgeInsetEdges, lets set it to BOTTOM so that
// we dodge any Snackbars
lp.dodgeInsetEdges = Gravity.BOTTOM;
}
}
}
}
Step 3. Use MyButton in app_bar_main layout.
Step 4. Set a breakpoint in onPreDraw and then I could see it will be executed infinitely. If I comment the offsetTopAndBottom(50), everything goes fine.
I also trace the source code and find app receive vsync signal again and again which cause the onVsync function in Choreographer.java run infinitely. Why this happens?
Update
If I set a breakpoint as below and comment onPreDraw, this breakpoint finally will not be reached, otherwise, it can be reached always.
The callback onPreDraw() is called before each frame is drawn. Since you normally keep on drawing frames (~60fps), it is normal that it is called "infinitely".
To avoid this behavior, the usual pattern is to remove the listener as first statement in onPreDraw():
view.getViewTreeObserver().removeOnPreDrawListener(this);
where view is the downcasted parent in your case.
You can see example code in this video. The engineers are part of the Android Framework team.
I was recently working with ImageButtons and I came across this new type of ImageButton 'VisibilityAwareImageButton'. It would be really helpful if someone could tell me the usage of this ImageButton and how is it different from the regular ImageButton? Thanks in advance :)
Here's the full source for VisibilityAwareImageButton.
class VisibilityAwareImageButton extends ImageButton {
private int mUserSetVisibility;
public VisibilityAwareImageButton(Context context) {
this(context, null);
}
public VisibilityAwareImageButton(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public VisibilityAwareImageButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mUserSetVisibility = getVisibility();
}
#Override
public void setVisibility(int visibility) {
internalSetVisibility(visibility, true);
}
final void internalSetVisibility(int visibility, boolean fromUser) {
super.setVisibility(visibility);
if (fromUser) {
mUserSetVisibility = visibility;
}
}
final int getUserSetVisibility() {
return mUserSetVisibility;
}
}
It appears to be almost exactly the same as a regular ImageButton, only it keeps track of the last visibility actually set by the user. The only usage I can find is in the FloatingActionButton source. It is used to keep track of what the user wants the visibility of the view to be while it does it's own internal changes and animations. i.e.
if (child.getUserSetVisibility() != VISIBLE) {
// The view isn't set to be visible so skip changing it's visibility
return false;
}
It's in the design support library and has package visibility, so it seems like Google intends on using it internally (and seemingly only for the FAB implementation at this time).
I have this custom view that is being added to the WindowManager as a System Alert which should function as a fullscreen overlay to block certain parts of the phone when the app is running.
This works great when the overlay is shown it blocks the phone window fullscreen. Now I want to support rotation changes.
This part also works fine, I have 3 layout files in layout layout-land and layout-h600dp-land and when I rotate the phone it changes to the correct layout. The problem I have with this is after onConfigurationChanged(Configuration newConfig) is called and I inflate the layout again all the click listeners are gone so none of the buttons in the views react to clicks. The button's pressed state does change when I tap on them but none of the onClickListeners are being triggered. Before the orientation change all the buttons do work. I have been using Butterknife to reduce the boilerplate code for onClicklisteners and findViewById's but I already changed that to findViewById and adding a clicklistener on the view manually which doesn't make a difference.
And now for some code. The service adds the view to the windowmanager
public class OverlayService extends Service {
public void showOverlay() {
startForeground();
mUiHandler.post(new Runnable() {
#Override
public void run() {
if (!DrivingOverlay.isShowing()) {
if (mOverlay == null) {
mOverlay = new Overlay(OverlayService.this);
mOverlay.setTag(OVERLAY_TAG);
mOverlay.setId(R.id.overlay);
}
addView(mOverlay);
}
});
}
private void addView(#NonNull final View view) {
try {
final WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
windowManager.addView(view, Overlay.LAYOUT_PARAMS);
} catch (IllegalStateException error) {
Log.e(TAG, Log.getStackTraceString(error));
}
}
}
The Custom View which is the overlay.
public class Overlay extends FrameLayout {
private static boolean sIsOverlayShowing;
public static final WindowManager.LayoutParams LAYOUT_PARAMS = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_FULLSCREEN
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
PixelFormat.TRANSLUCENT);
public Overlay(Context context) {
super(context);
init(context);
}
public Overlay(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public Overlay(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public Overlay(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(context);
}
protected void init(Context context) {
inflate(context, R.layout.driving_overlay, this);
if (!isInEditMode()) {
ButterKnife.bind(this);
}
}
#Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Log.d(TAG, "onConfigurationChanged");
init(getContext());
}
#Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
setIsOverlayShowing(true);
}
#Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
setIsOverlayShowing(false);
}
#Override
public void onViewAttachedToWindow(View v) {
setIsOverlayShowing(true);
}
#Override
public void onViewDetachedFromWindow(View v) {
setIsOverlayShowing(false);
}
public static boolean isShowing() {
return sIsOverlayShowing;
}
public static void setIsOverlayShowing(boolean isOverlayShowing) {
sIsOverlayShowing = isOverlayShowing;
}
}
Finally figured it out.
Calling inflate(context, R.layout.driving_overlay, this) in the init adds the view that is being inflated to the root view in this case to Overlay which is a FrameLayout so each rotation was inflating a new layout and adding it to the root view so after the a rotation the Overlay class had more than 1 child view. The OnClickListeners would bind the child views button's at position 0 to the OnClickListeners in the class and it would show the child view that was newly inflated at position 1 or higher. So after adding this a check and removing obsolete views the OnClickListeners are working again.
protected void init(Context context) {
if (getChildCount() >= 1) {
removeViewAt(0);
}
final View view = inflate(context, R.layout.driving_overlay, this);
if (!isInEditMode()) {
ButterKnife.bind(this, view);
}
}
Assuming you have not restricted the Restarting of activity due to change in
the orientation. When a device s configuration gets changed in your case
Orientation, its user interface has to be updated according to the new
configuration.
Being the primary component for interaction, it can be updated with some
attributes to handle changes. Default behavior of Activity when device gets
rotated is it gets destroyed and restarted again. This may be your issue.
To handle the rotation of activity use android:configChanges = "orientation"
attribute in manifest for your activity.
My problem is as follows: I lock the navigation drawer menu setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN) in the landscape mode of the tablet, but I need the fragment from the right to be active, so I can click it with navigation always opened. But I dont know how to do it. Please help.
There are a few things you need to do:
Disable the layout fading by setting a transparent color:
drawer.setScrimColor(Color.TRANSPARENT);
Lock the drawer
drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN);
Create a custom drawer class which allows clicking through when in locked mode:
public class CustomDrawer extends DrawerLayout {
public CustomDrawer(Context context) {
super(context);
}
public CustomDrawer(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomDrawer(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
View drawer = getChildAt(1);
if (getDrawerLockMode(drawer) == LOCK_MODE_LOCKED_OPEN && ev.getRawX() > drawer.getWidth()) {
return false;
} else {
return super.onInterceptTouchEvent(ev);
}
}
}
Use this class in xml:
<com.example.myapplication.CustomDrawer
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- The main content view -->
</FrameLayout>
<ListView android:layout_width="100dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#111"/>
</com.example.myapplication.CustomDrawer>
This is a tricky one. When the drawer is open, it intercepts your touch events which trigger the close of the drawer. In order to prevent that, you need to subclass your DrawerLayout and override the onInterceptTouchEvent method:
public class CustomDrawerLayout extends DrawerLayout
{
private View rightView;
private int mTouchSlop;
public CustomDrawerLayout (Context context)
{
this(context, null);
}
public CustomDrawerLayout (Context context, AttributeSet attrs)
{
this(context, attrs, 0);
}
public CustomDrawerLayout (Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
mTouchSlop = ViewConfigurationCompat.getScaledPagingTouchSlop(ViewConfiguration.get(context));
}
public void setRightView (View v)
{
this.rightView = v;
}
#Override
public boolean onInterceptTouchEvent (MotionEvent ev)
{
boolean result = super.onInterceptTouchEvent(ev);
if (rightView != null && isDrawerOpen(rightView))
{
DrawerLayout.LayoutParams layoutParams = (DrawerLayout.LayoutParams) rightView.getLayoutParams();
if (layoutParams.gravity == Gravity.END)
{
// This is true when the position.x of the event is happening on the left of the drawer (with gravity END)
if (ev.getX() < rightView.getX() && ev.getX() > mTouchSlop)
{
result = false;
}
}
}
return result;
}
}
This is my code working with a right drawer. I'm sure you can adapt this for your left drawer. You might also want to disable the shadow:
mDrawerLayout.setScrimColor(Color.TRANSPARENT);
Thanks for #Simas's solution!
I found if an item which user click is quite near drawerView, use ev.rawX is not appropriate. Furthermore, I add other gravity check to determinate interception.
class ContentTouchableDrawer #JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null
) : DrawerLayout(context, attrs) {
override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
val drawer: View = getChildAt(1)
logt("drawer : $drawer")
logt("drawer : width = ${drawer.width}")
logt("drawer : x = ${drawer.x}")
logt("drawer : eventRawX = ${ev.rawX}")
logt("drawer : eventX = ${ev.x}")
val drawerGravity = (drawer.layoutParams as LayoutParams).gravity
val result = when(drawerGravity){
Gravity.RIGHT, GravityCompat.END -> ev.x < drawer.x
Gravity.LEFT, GravityCompat.START -> ev.x > drawer.width
//Gravity.NO_GRAVITY
else -> false
}
return if (getDrawerLockMode(drawer) == LOCK_MODE_LOCKED_OPEN && result) {
false
} else {
super.onInterceptTouchEvent(ev)
}
}
}