Set Drag Margin for Android Navigation Drawer

Set drag margin for Android Navigation Drawer

Here I've found a solution via reflections

DrawerLayout mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
Field mDragger = mDrawerLayout.getClass().getDeclaredField(
"mLeftDragger");//mRightDragger for right obviously
mDragger.setAccessible(true);
ViewDragHelper draggerObj = (ViewDragHelper) mDragger
.get(mDrawerLayout);

Field mEdgeSize = draggerObj.getClass().getDeclaredField(
"mEdgeSize");
mEdgeSize.setAccessible(true);
int edge = mEdgeSize.getInt(draggerObj);

mEdgeSize.setInt(draggerObj, edge * 5); //optimal value as for me, you may set any constant in dp

How to increase the width of pulling the Navigation Drawer from the side

There is a solution. You can Set drag margin for your Navigation Drawer

Check this link
Set drag margin for Android Navigation Drawer

Android navigation drawer trigger area is too small

You can do something like this:

private void setLeftMargin() {
java.lang.reflect.Field mDragger = null;
try {
mDragger = mDrawerLayout.getClass()
.getDeclaredField("mLeftDragger");
} catch (NoSuchFieldException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
mDragger.setAccessible(true);
ViewDragHelper draggerObj = null;
try {
draggerObj = (ViewDragHelper) mDragger.get(mDrawerLayout);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

java.lang.reflect.Field mEdgeSize = null;
try {
mEdgeSize = draggerObj.getClass().getDeclaredField("mEdgeSize");
} catch (NoSuchFieldException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
mEdgeSize.setAccessible(true);
int edge = 0;
try {
edge = mEdgeSize.getInt(draggerObj);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

try {
mEdgeSize.setInt(draggerObj, edge * 1);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

It will set left side area as per your requirement.You can set int edge = valueYouNeed;Hope it will help you.

Touch anywhere to slide open menu for navigation drawer

I have found a solution. You can configure margin of touch and make it as wide as your view is. Here is the link

Set drag margin for Android Navigation Drawer

Android Navigation Drawer Doesn't Pass onTouchEvent to Activity

Apparently the answer is somewhat easy, although it does make you extend the DrawerLayout and do some thinking, and maybe will result in some strange results (using the LAST
example, I haven't seen any, yet).

Anyway, related questions which looking backwards can help understanding the issue (will explain about the first one later on):

1. DrawerLayout prevents call of MainActivity.onTouchEvent()

2. How can I requestDisallowTouchEvents on Android DrawerLayout

3. Set drag margin for Android Navigation Drawer

Answer
First, please note that I put lots of examples here. If you just want the best one (for me), jump to the last one.

Secondly, if someone has enough reputation, please comment on the first link's question and put a link to this answer (it can help that guy).

Example 1
Well, basically, just extend Android's DrawerLayout and replace onTouchEvent() to this:

@Override
public boolean onTouchEvent(MotionEvent arg0) {
super.onTouchEvent(arg0);
return false;
}

This solution will do anything except that it won't open the Drawer on slides, only menu clicks and the like. Besides, it forwards clicks so when the Drawer is open
for instance, touching outside of it will NOT close it, but click on whatever is behind (e.g. a ListView). Le'ts try harder...

Example 2
Now, let's catch the open OR visible cases, to return true (and consume the action at the Drawer).

@Override
public boolean onTouchEvent(MotionEvent arg0) {
super.onTouchEvent(arg0);

if(isDrawerOpen(findViewById(R.id.list_slidermenu)) ||
isDrawerVisible(findViewById(R.id.list_slidermenu))){
return true;
}

return false;
}

This solution is better, as it prevents clicks on behind the Drawer when the drawer is open or even visible (slide starts...). But touch-sliding it still doesn't work.

Example 3
Ok, so let's just split cases. Touches (MotionEvent.ACTION_DOWN) inside the Drawer's margin (area that Google desided to slide Drawer when touched at)
will result in returning True to consume the action, and others will forward the event (return False).

@Override
public boolean onTouchEvent(MotionEvent arg0) {
super.onTouchEvent(arg0);
float edge = 30;//that's for a left drawer obviously. Use <parentWidth - 30> for the right one.
View mDrawerListView = findViewById(R.id.drawer_listview);

if(isDrawerOpen(mDrawerListView) ||
isDrawerVisible(mDrawerListView)){
return true;
} else if(arg0.getAction() == MotionEvent.ACTION_DOWN && arg0.getX() > edge){
return false;
}

return true;
}

Note that I used 30dp. That's what I found to be the margin (although in one of the links it is said to be 20....).

Well, the next example would of course be deciding what is, exactly, that edge (see in code above) value is, according to Android. We don't want to
use a number that could change or whatever.

New Question
So now that first link should come handy. It "hacks" the Drawer code to get that Drawer edge/megin number. BUT, it didn't work for me, as those exact Field names could not be found.

I run mDrawerLayout.getClass().getField() which returns all the fields, but without any luck finding what we want. Anyone?

Last Example - Full Code
Ok, looking on example number 3, after understanding what exactly I did, we can make it faster by extending the onFinishInflate() method and save it as a global variable
for this CustomDrawerLayout for later use. We can also put that first 'if' inside the second one to save some more work. OK here goes:

View mDrawerListView;
...

@Override
protected void onFinishInflate() {
super.onFinishInflate();
mDrawerListView = findViewById(R.id.drawer_listview);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);

if(event.getX() > 30 && event.getAction() == MotionEvent.ACTION_DOWN){
if(isDrawerOpen(mDrawerListView) || isDrawerVisible(mDrawerListView)){
return true;
} else{
return false;
}
}

return true;
}

That's it for now! Hope it'll helps someone in the future beside myself, hehe....



Related Topics



Leave a reply



Submit