I use a navigation drawer, which I want to disable for inner Fragments.
I used following code to setup the drawer:
private void initSideMenu() {
actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawerLayout, R.string.Open, R.string.Close);
drawerLayout.addDrawerListener(actionBarDrawerToggle);
actionBarDrawerToggle.syncState();
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
binding.nv.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.menuData:
selectPersonalDataFragment();
break;
case R.id.menuBlogPosts:
closeDrawerAndNavigateTo(new BlogPostFragment(), true);
break;
case R.id.menuSettings:
closeDrawerAndNavigateTo(new BackgroundImageFragment(), true);
break;
}
return true;
}
});
}
To disable the navigation drawer I use following code:
#Override
public void setDrawerEnabled(boolean enabled) {
Log.d(TAG, "setDrawerEnabled: " + enabled);
if(enabled) {
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
actionBarDrawerToggle.setDrawerIndicatorEnabled(true);
} else {
actionBarDrawerToggle.setDrawerIndicatorEnabled(false);
actionBarDrawerToggle.setToolbarNavigationClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
}
}
The burger icon changes to a back arrow, but this arrow does not have any functionality. So why is my listener not listening?
After a lot of trying I found out, that I did not have to set a toolbar navigation click Listener, but had to override onSupportNavigateUp():
Changed setDrawerEnabled():
#Override
public void setDrawerEnabled(boolean enabled) {
Log.d(TAG, "setDrawerEnabled: " + enabled);
if(enabled) {
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
actionBarDrawerToggle.setDrawerIndicatorEnabled(true);
} else {
actionBarDrawerToggle.setDrawerIndicatorEnabled(false);
}
}
New overriden onSupportNavigateUp():
#Override
public boolean onSupportNavigateUp() {
onBackPressed();
return true;
}
Related
I am trying to add click functionality on the Actionbar back button. I have tried the below things till now, but unable to get the desired result.
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Observed that the onClick method is not being called when i click on the back button in the action bar
toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close) {
};
drawer.setDrawerListener(toggle);
drawer.post(new Runnable() {
#Override
public void run() {
toggle.syncState();
}
});
toggle.setDrawerIndicatorEnabled(true);
toggle.setToolbarNavigationClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onKeyDown(4, null);
}
});
Use the updated code
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
switch (item.getItemId()) {
case android.R.id.home:
showToast("Test");
return true;
}
you can try like this
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowTitleEnabled(false);
getSupportActionBar().setDisplayShowHomeEnabled(true);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
use following code inside your Activity :
//for going back or finish current activity.
#Override
public boolean onSupportNavigateUp() {
finish();
startActivity(new Intent(ResultActivity.this, MainActivity.class));
return true;
}
Below code are for actionBar menu.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.logout) {
// toast Here
return true;
}
if (id == R.id.home) {
// toast Here
return true;
}
return super.onOptionsItemSelected(item);
}
onCreateOptionsMenu() is used for creating your menu & setting your menu.xml
onOptionsItemSelected() is used for selection of menu items & actions.
I use MaterialDrawer and code MainActivity is:
public class MainActivity extends AppCompatActivity implements KitchenFragment.CallbackOne {
public static final String TAG = "myLogTag";
private Toolbar mToolbar;
private Drawer drawer;
private FragmentManager fm;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mToolbar = (Toolbar) findViewById(R.id.toolbar);
mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG, "CLICK NOCL");
}
});
setSupportActionBar(mToolbar);
// getSupportActionBar().setDisplayHomeAsUpEnabled(false);
fm = getFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.content_frame);
if (fragment == null) {
fragment = MenuFragment.newInstance();
fm.beginTransaction()
.add(R.id.content_frame, fragment)
.commit();
}
drawer = new DrawerBuilder()
.withActivity(this)
.withToolbar(mToolbar)
.withActionBarDrawerToggle(true)
.withHeader(R.layout.drawer_header)
.addDrawerItems(
new PrimaryDrawerItem().withName(R.string.menu).withIdentifier(1),
new PrimaryDrawerItem().withName(R.string.kitchen_title).withIdentifier(2),
new PrimaryDrawerItem().withName(R.string.information_title).withEnabled(false)
).withOnDrawerItemClickListener(new Drawer.OnDrawerItemClickListener() {
#Override
public boolean onItemClick(View view, int position, IDrawerItem drawerItem) {
Log.d(TAG, "position clicked: " + position);
Fragment fragment = MenuFragment.newInstance();
switch (position) {
case 1:
fragment = MenuFragment.newInstance();
break;
case 2:
fragment = KitchenFragment.newInstance();
break;
default:
fragment = new Fragment();
}
fm.beginTransaction().replace(R.id.content_frame, fragment).commit();
return false;
}
})
.withFireOnInitialOnClick(true)
.withSavedInstance(savedInstanceState)
.withOnDrawerNavigationListener(new Drawer.OnDrawerNavigationListener() {
#Override
public boolean onNavigationClickListener(View view) {
Log.d(TAG, "CLICK in DNL");
if (!drawer.getActionBarDrawerToggle().isDrawerIndicatorEnabled()) {
onBackPressed();
return true;
} else
return false;
}
})
.build();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
Log.d(TAG, "CLICK OIS");
switch (item.getItemId()) {
case R.id.action_settings:
return true;
case android.R.id.home:
getFragmentManager().popBackStackImmediate();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
outState = drawer.saveInstanceState(outState);
super.onSaveInstanceState(outState);
}
#Override
public void onBackPressed() {
if (drawer.isDrawerOpen())
drawer.closeDrawer();
else if (getFragmentManager().getBackStackEntryCount() == 1) {
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
drawer.getActionBarDrawerToggle().syncState();
getFragmentManager().popBackStack();
} else if (getFragmentManager().getBackStackEntryCount() > 0)
getFragmentManager().popBackStack();
else
super.onBackPressed();
}
#Override
public void setFirstSelected() {
drawer.setSelection(1);
}
}
I'm trying to trace a Click in mToolbar.setNavigationOnClickListener
and withOnDrawerNavigationListener and onOptionsItemSelected.
None of the listeners not reacted for clicking.
How you see i use Activity that launches Fragment (1), which in turn lets Fragment (2 and 3). In 2 and 3 Fragment in OnCreate i use ((AppCompatActivity)getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(true); , and I need to by pressing the back button (in toolbar), returning the previous fragment, and not open Drawer
The MaterialDrawer already handles all the listeners for you. If you need to do an action after the drawer opens or closes you can provide the listener via the DrawerBuilder
For the icon you have this listener:
OnDrawerNavigationListener
https://github.com/mikepenz/MaterialDrawer/blob/develop/library/src/main/java/com/mikepenz/materialdrawer/DrawerBuilder.java#L1158
For drawer close / open this listener:
OnDrawerListener
https://github.com/mikepenz/MaterialDrawer/blob/develop/library/src/main/java/com/mikepenz/materialdrawer/DrawerBuilder.java#L1116
I suggest you to create new Activity using android studio wizard. File->New->Activity->Navigation Drawer Activity.
In that case ActionBarDrawerToaggle is used
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
This toggle contains click listener which handle open/close drawer functionality for you.
Also you can that item clicks implemented through OnNavigationItemSelectedListener.onNavigationItemSelected(MenuItem item)
I'm completely new at Android. I was quite surprised that Android Studio does not have a template for navigation between fragments. I have spent several days now, but still cannot make my code work properly.
I have single activity and two fragments - MainFragment and AboutFragment. About is accessible via drawer menu item. I want to return to MainFragment by pressing back action bar button. The problem is button is not working. Can anyone help me?
Complete minimal Android Studio project:
test.zip
Here is my activity class:
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener,
MainFragment.OnFragmentInteractionListener, AboutFragment.OnFragmentInteractionListener {
private DrawerLayout drawer;
private boolean zOrderSet = false;
private ActionBarDrawerToggle toggleListener;
private FragmentManager.OnBackStackChangedListener mOnBackStackChangedListener =
new FragmentManager.OnBackStackChangedListener() {
#Override
public void onBackStackChanged() {
syncActionBarArrowState();
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
toggleListener = new ActionBarDrawerToggle(this, drawer, toolbar,
R.string.navigation_drawer_open, R.string.navigation_drawer_close) {
#Override
public void onDrawerSlide(View drawerView, float slideOffset) {
super.onDrawerSlide(drawerView, slideOffset);
if (!zOrderSet) {
drawer.bringChildToFront(drawerView);
drawer.requestLayout();
drawer.invalidate();
zOrderSet = true;
}
}
public void onDrawerClosed(View view) {
syncActionBarArrowState();
}
public void onDrawerOpened(View drawerView) {
toggleListener.setDrawerIndicatorEnabled(true);
}
};
drawer.setDrawerListener(toggleListener);
toggleListener.syncState();
getSupportFragmentManager().addOnBackStackChangedListener(mOnBackStackChangedListener);
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
getSupportFragmentManager().beginTransaction().replace(R.id.flContent, MainFragment.newInstance("", "")).commit();
}
#Override
protected void onDestroy() {
getSupportFragmentManager().removeOnBackStackChangedListener(mOnBackStackChangedListener);
super.onDestroy();
}
private void syncActionBarArrowState() {
boolean empty = getSupportFragmentManager().getBackStackEntryCount() == 0;
toggleListener.setDrawerIndicatorEnabled(empty);
getSupportActionBar().setDisplayHomeAsUpEnabled(!empty);
}
#Override
public void onBackPressed() {
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (toggleListener.isDrawerIndicatorEnabled() && toggleListener.onOptionsItemSelected(item)) {
return true;
}
int id = item.getItemId();
if (id == android.R.id.home && getSupportFragmentManager().popBackStackImmediate()) {
return true;
}
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public boolean onNavigationItemSelected(MenuItem item) {
FragmentTransaction ta = getSupportFragmentManager().beginTransaction();
try {
switch (item.getItemId()) {
case R.id.nav_restart:
ta.replace(R.id.flContent, MainFragment.class.newInstance());
break;
case R.id.nav_about:
ta.replace(R.id.flContent, AboutFragment.class.newInstance()).addToBackStack(null);
break;
default:
return false;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
ta.commit();
}
drawer.closeDrawer(GravityCompat.START);
return true;
}
#Override
public void onFragmentInteraction(Uri uri) {
}
}
#Override
public void onBackPressed(){
getActivity().getFragmentManager().beginTransaction().remove(this).commit();
}
I am using DrawerArrowDrawable to animate the hamburger icon during the opening and closing of Navigation drawer. Following is the code snippet I used for that:
DrawerArrowDrawable drawerArrow = new DrawerArrowDrawable(this);
toolbar.setNavigationIcon(drawerArrow)
mDrawerToggle.syncState();
Now when I open a fragment I use actionBar.setHomeAsUpIndicator(R.drawable.back_icon); & actionBar.setDisplayHomeAsUpEnabled(true); in that very fragment, to change the navigation icon as a back icon. The icon changes but the functionality of that button stays same i.e., it opens the navigation drawer, but I want to go back to the previous fragment (by using popBackStack).
I tried to override onOptionsItemSelected :
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
FragmentManager fm = getSupportFragmentManager();
if (fm.getBackStackEntryCount() > 0) {
fm.popBackStack();
}
break;
}
}
But the control never reaches in the above block when I press the navigation icon.
If I get to know that How to intercept the click event of DrawerArrowDrawable? I would be able to run popBackStack and do what I want to do.
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
FragmentManager fm = getSupportFragmentManager();
if (fm.getBackStackEntryCount() > 0) {
fm.popBackStack();
}
}
});
Add this listener inside the Navigation Drawer Activity:
private FragmentManager.OnBackStackChangedListener mOnBackStackChangedListener = new FragmentManager.OnBackStackChangedListener() {
#Override
public void onBackStackChanged() {
setActionBarArrowDependingOnFragmentsBackStack();
}
};
Then create this method:
public void setActionBarArrowDependingOnFragmentsBackStack() {
int backStackEntryCount = getFragmentManager().getBackStackEntryCount();
mDrawerToggle.setDrawerIndicatorEnabled(backStackEntryCount == 0);
}
Now override these methods:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (mDrawerToggle.isDrawerIndicatorEnabled() && mDrawerToggle.onOptionsItemSelected(item)) {
return true;
} else if (item.getItemId() == android.R.id.home && getFragmentManager().popBackStackImmediate()) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
return super.onCreateOptionsMenu(menu);
}
#Override
public void onDestroy() {
super.onDestroy();
getFragmentManager().removeOnBackStackChangedListener(mOnBackStackChangedListener);
}
Finally add this line inside your onCreate() method:
getFragmentManager().addOnBackStackChangedListener(mOnBackStackChangedListener);
i want the right drawer to be opened on menu click
i have used the following code but its not working for some reason
mDrawerToggle = new ActionBarDrawerToggle(getActivity(),mDrawerLayout,toolbar, R.string.drawer_open,
R.string.drawer_close) {
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item != null && item.getItemId() == R.id.more) {
if (mDrawerLayout.isDrawerOpen(Gravity.END)) {
saveToPreferences(getActivity(),KEY_USER_LEARNED_DRAWER,mUserLearnedDrawer+"");
mDrawerLayout.closeDrawer(Gravity.END);
} else {
mDrawerLayout.openDrawer(Gravity.END);
}
}
return false;
}
};
please help me out
SOLVED IT BY MODIFYING THE MAINACTIVITY
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_settings:
return true;
case R.id.more:
if (notificationDrawerFragment.mDrawerLayout.isDrawerOpen(Gravity.END)){
notificationDrawerFragment.mDrawerLayout.closeDrawer(Gravity.END);
}
else
{ notificationDrawerFragment.mDrawerLayout.openDrawer(Gravity.END);
}
default:
return super.onOptionsItemSelected(item);
}
}
Solved the following by modifying the menu option within the main activity
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_settings:
return true;
case R.id.more:
notificationDrawerFragment.mDrawerLayout.openDrawer(Gravity.END);
default:
return super.onOptionsItemSelected(item);
}
}
Do you have this override:
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
mDrawerToggle.syncState();
}
also you should have overrides under ActionBarDrawerToggle:
public void onDrawerOpened(View drawerView) and
public void onDrawerClosed(View drawerView)
Try this, I had learnt this from SO:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item != null && item.getItemId() == android.R.id.more) {
if (mDrawerLayout.isDrawerOpen(Gravity.RIGHT)) {
saveToPreferences(getActivity(),KEY_USER_LEARNED_DRAWER,mUserLearnedDrawer+" ");
mDrawerLayout.closeDrawer(Gravity.RIGHT);
} else {
mDrawerLayout.openDrawer(Gravity.RIGHT);
}
}
return false;
}
};
Hope this helps.