I'm working on application that has a tab structure, and use sliding movements to move through the tabs.
But now, I want to apply Drawer Layout. The problem is that the Drawer has slide to open events. How I can delete this event? My idea was that the Drawer only could open and close with a button. Is this possible?
Thanks!
Just write
drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
to prevent menu from listening to gesture
and use openDrawer and closeDrawer to change menu visibility
By default the DrawerLayout is initially hidden from the view unless you put a code to open the Drawer, by the time there is a sliding event triggered.
From the Navigation Drawer example, the contain content_frame is used to dynamically display views inside the Drawer using fragments.
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</FrameLayout>
From the Fragment's onCreateView() you can include a button somewhere that has OnClickListener where in you put this code,
//For me a better way in avoiding a `null pointer` in getting the DrawerLayout
final DrawerLayout drawer = (DrawerLayout) getActivity().findViewById(R.id.drawer_layout);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
//Opens the Drawer
drawer.openDrawer(Your View, Usually a ListView);
}
return false;
});
You Can also use* to close the drawer.
drawer.closeDrawer(Your View, Usually a ListView);
you can write this way
mButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
drawer.openDrawer(navigationView);
}
});
If you want to navigate between drawer item on click of button inside your fragments,
you can use this
((YourMainActivity)getActivity()).selectItem(position);
Related
I'm working with Navigation Drawer and I want to click the button on activity and Navigation Drawer should show, but I don't know how to do it. Normally, when we swipe from left edge to the right the navigation will be shown. as such, I want to be able to open the navigation drawer with the click of a button.
Use the following methods to open and close your navigation drawer:
DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
//To Open:
drawerLayout.openDrawer(Gravity.START);
//To Close:
drawerLayout.closeDrawer(Gravity.END);
Source1 for more information:
Source2
Button hamMenu = findViewById(R.id.ham_menu);
hamMenu.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
DrawerLayout navDrawer = findViewById(R.id.drawer_layout);
// If the navigation drawer is not open then open it, if its already open then close it.
if(!navDrawer.isDrawerOpen(GravityCompat.START)) navDrawer.openDrawer(Gravity.START);
else navDrawer.closeDrawer(Gravity.END);
}
});
You can also use a method and Use the exact same steps given by #Zeeshan.
public void hamMenu(View view){
DrawerLayout drawer = findViewById(R.id.drawer_layout);
if (!drawer.isDrawerOpen(GravityCompat.START)) {
drawer.openDrawer(GravityCompat.START);
} else {
drawer.closeDrawer(GravityCompat.END);
}
}
Use this method in the button which you need android:Onclick="hamMenu" in .xml.
Can we open multiple DrawerLayout in one activity.
i mean when open on one DrawerLayout and onclick on item open another drawerlayout.
(Nested Drawer layout).
Yes you can using Fragments.
From the Fragment's onCreateView() you can include a button somewhere that has OnClickListenerwhere in you put this code .
open a new Drawer :
//For me a better way in avoiding a `null pointer` in getting the DrawerLayout
final DrawerLayout drawer = (DrawerLayout) getActivity().findViewById(R.id.drawer_layout);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
//Opens the Drawer
drawer.openDrawer(Your View, Usually a ListView);
}
return false;
});
And close Drawer :
drawer.closeDrawer(Your View, Usually a ListView);
Hope it helps .
I've put a webview on the Navigation Drawer; the webview shows formatted text about the current UI so that the users can familiarize themselves with features.
Unfortunately, after scrolling up or down on the webview (horizontal scrolling of the webview is disabled), the navigation drawer closes itself after I lift my finger off the webview !
How can I prevent the Navigation Drawer from closing itself when the user lets go ?
EDIT:
additional findings ... I've attached an OnTouchListener() to the drawer's layout that does nothing except return true. This prevents the auto-closing from happening when touching an empty space on the Navigation Drawer. To see how this is done, check out http://android-er.blogspot.com/2014/01/android-drawerlayout-and-drawerlistener.html and look at the "experimental" comment.
Unfortunately it doesn't stop the Navigation Drawer from closing when the user doesn't scroll up/down perfectly on the webview.
For example, scrolling up and down on the webview will close the drawer if there is a very small horizontal component to the drag.
So the (hassle-free) solution to prevent the over-zealous closing of the drawer: once the drawer is open, lock it open and have a button trigger the closeDrawer(). The code below shows how to manage the lock/unlock status. It doesn't include the button to call closeDrawer() because that's quite basic.
in XML, the id of the DrawerLayout is :
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
in your Activity, the java code is :
import android.support.v4.widget.DrawerLayout;
public class MyActivity extends Activity implements DrawerLayout.DrawerListener
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.layoutwithdrawer);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerLayout.setDrawerListener(this);
}
#Override
public void onDrawerClosed(View arg0) {
// allow swiping to open the drawer
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
}
#Override
public void onDrawerOpened(View arg0) {
// disable swiping so that the drawer can't be closed by accident when scrolling through webview
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN);
}
#Override
public void onDrawerSlide(View arg0, float arg1) {}
#Override
public void onDrawerStateChanged(int arg0) {}
}
The setup
I have an activity whose contentView is an instance of a DrawerLayout, which has a navigation drawer with a drawer indicator displayed in the action bar. The activity contains a Fragment, let's call it ListFragment, which contains a list of options. When an option is clicked, I replace the ListFragment with a DetailFragment.
At this point, I would like to display an "up" navigation option instead of the navigation drawer indicator. I'm able to display the "up" icon if I disable the drawer indicator by calling mDrawerToggle.setDrawerIndicatorEnabled(false), but this only removes the drawer icon--it does not remove the functionality--that is, when I click the caret, the navigation drawer is still opened.
Additionally, in these subviews, I would like to disable the opening of the drawer by dragging from the edge of the screen. I have tried doing this by calling setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED) but it doesn't seem to have disabled this functionality.
I have tried extending the ActionBarDrawerToggle class to prevent opening the drawer when the indicator is clicked--however, all that happens is that the overriding action (the "up" navigation) is performed, but the drawer still opens.
I have also implemented the steps in Switching between Android Navigation Drawer image and Up caret when using fragments . It works insofar as displaying the caret goes, but despite overriding the up button functionality, the menu still opens (the app does navigate back--it just also opens the drawer).
Question
So, long story short: is there any (preferably clean and elegant, but at this point I'll go with hacky) way to achieve these things when my layout root is a DrawerLayout:
Replace the drawer indicator with an "up" caret (tentatively doable via mDrawerToggle.setDrawerIndicatorEnabled(false))
Prevent the drawer from opening when the caret is clicked, and instead override with my own "up" functionality
Prevent the drawer from opening when I drag from the edge of the screen.
Edit
All right, it looks like if I both override ActionBarDrawerToggle AND onOptionsItemSelected, the menu does not open when I click the caret. But it still opens if I drag from the edge. Help!
Short Code
public void setDrawerState(boolean isEnabled) {
if ( isEnabled ) {
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
drawerToggle.onDrawerStateChanged(DrawerLayout.LOCK_MODE_UNLOCKED);
drawerToggle.setDrawerIndicatorEnabled(true);
drawerToggle.syncState();
}
else {
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
drawerToggle.onDrawerStateChanged(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
drawerToggle.setDrawerIndicatorEnabled(false);
drawerToggle.syncState();
}
}
This is only part of the solution that I arrived at, but it was quite hard to figure out this bug, so I'm leaving this here for posterity's sake.
This how I was defining the ListView for my navigation drawer:
<ListView
android:id="#+id/listview_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start|bottom"
android:background="#111"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp" />
Even after calling setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED) I was still able to slide the drawer open.
However, after changing the layout_gravity to "start" this problem seems to be resolved.
I was able to reproduce this issue in a sample, navigation-drawer-only app, so it does appear to be a reproducible issue not unique to my situation.
Building on sonida's answer. After calling setDrawerIndicatorEnabled(false), onNavigateUp wasn't being called still. So, I just created a new onClickListener that called it:
public void setDrawerState(boolean isEnabled) {
if ( isEnabled ) {
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
drawerToggle.setDrawerIndicatorEnabled(true);
drawerToggle.syncState();
}
else {
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
drawerToggle.setDrawerIndicatorEnabled(false);
drawerToggle.setToolbarNavigationClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onSupportNavigateUp();
}
});
drawerToggle.syncState();
}
}
also I think
drawerToggle.onDrawerStateChanged(DrawerLayout.LOCK_MODE_UNLOCKED);
has been depreciated, but it works fine without it.
You need to disable swipe and disable the actionbar home button:
Use the below code that builds on the code already given to disable swipe
public void setDrawerState(boolean isEnabled) {
if ( isEnabled ) {
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
mDrawerToggle.onDrawerStateChanged(DrawerLayout.LOCK_MODE_UNLOCKED);
mDrawerToggle.setDrawerIndicatorEnabled(true);
mDrawerToggle.syncState();
getActivity().getActionBar().setHomeButtonEnabled(true);
}
else {
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
mDrawerToggle.onDrawerStateChanged(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
mDrawerToggle.setDrawerIndicatorEnabled(false);
mDrawerToggle.syncState();
getActivity().getActionBar().setHomeButtonEnabled(false);
}
}
Building on answer by #sonida And after using the tweaks given by #luca992 and #jai.
I tried above suggested codes But the "up" or "Back" arrow in left side of action bar was just not showing up in my app. But luckily I was able to fix that.
I had to add this extra line of code in setNavigationDrawerState() [Ref: android.support.v7.app.ActionBarDrawerToggle.setHomeAsUpIndicator ]
toggle.setHomeAsUpIndicator(R.drawable.ic_keyboard_backspace_white_24dp);
I downloaded the drawable: ic_keyboard_backspace_white_24dp from Material.io
Here is the complete code:
MainActivity.java -> onCreate()
DrawerLayout drawer;
ActionBarDrawerToggle toggle;
#Override
protected void onCreate(Bundle savedInstanceState) {
// Start: Code automatically generated by Android Studio
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
// End: Code automatically generated by Android Studio
// I had to add this listener as the "back" arrow was totally unresponsive
// Thanks to #luca992
toggle.setToolbarNavigationClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
// Start: Code automatically generated by Android Studio
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
// End: Code automatically generated by Android Studio
// More custom code for other stuff
// ...
}
MainActivity.java -> setNavigationDrawerState()
public void setNavigationDrawerState(boolean isEnabled) {
if ( isEnabled ) {
drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
toggle.setDrawerIndicatorEnabled(true);
toggle.syncState();
}
else {
drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
toggle.setDrawerIndicatorEnabled(false);
// the extra line of code goes here
toggle.setHomeAsUpIndicator(R.drawable.ic_keyboard_backspace_white_24dp);
toggle.syncState();
}
MainActivity.java -> onBackPressed()
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else if(getSupportFragmentManager().getBackStackEntryCount() > 0){
getSupportFragmentManager().popBackStack();
}else {
super.onBackPressed();
}
}
MainActivity.java -> startFragment() [dummy function for example]
public void startFragment(){
MyFrag myFrag = new MyFrag();
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.frag_container ,myFrag)
.addToBackStack(null)
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
.commit();
}
MyFrag.java --> onViewCreated()
#Override
public void onViewCreated (View view, Bundle savedInstanceState){
super.onViewCreated(view, savedInstanceState);
// Say, using an implemented interface Make call to MainActivitiy's setNavigationDrawerState() passing false
// setNavigationDrawerState(false)
// ...
}
MyFrag.java --> onDestroyView()
#Override
public void onDestroyView(){
// Say, using an implemented interface Make call to MainActivitiy's setNavigationDrawerState() passing true
// setNavigationDrawerState(true)
super.onDestroyView();
}
I am using navigation drawer. I have hidden the action bar using aandroid:theme="#android:style/Theme.Light.NoTitleBar". So i am able to slide the drawer using swipe only. I want to create a button. On button click i want to show the drawer. I have googled but couldn't find much. Thanks in advance.
Call openDrawer on your onClick:
public void openDrawer (View drawerView)
Open the specified drawer view by animating it into view.
Parameters drawerView Drawer view to open
http://developer.android.com/reference/android/support/v4/widget/DrawerLayout.html#openDrawer(android.view.View)
drawer.openDrawer(Gravity.LEFT);
and to close :
drawer.closeDrawer(Gravity.LEFT);
Try this:
final ImageView toolbar1 = (ImageView) findViewById(R.id.Toolbar1);
final DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
toolbar1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
drawer.openDrawer(GravityCompat.START);
}
});