Skip to content

Commit f128b59

Browse files
committed
Add option to handle some menu items yourself.
1 parent 6387913 commit f128b59

14 files changed

Lines changed: 269 additions & 91 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Changelog
2+
3+
## Version 0.2.0
4+
5+
* Added `shouldHandleMenuItem()`, which can be overridden to handle some menu items yourself in the listener set via `setNavigationItemSelectedListener()`.

README.md

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ Now you have your navigation drawer up and running, including state saving of th
4949

5050
# Advanced Usage
5151

52+
## OnNavigationItemSelectedListener
53+
54+
An additional `OnNavigationItemSelectedListener` can be provided via `setNavigationItemSelectedListener()`. This can be used to add behavior after the fragment transaction was commited. If you just want to close the drawer, the lib includes a `CloseDrawerNavigationItemSelectedListener`.
55+
5256
## Back Stack
5357

5458
There are cases when some menu items (e.g. settings) should not simply replace the current fragment, but also be added to the back stack. To do this, override `shouldAddToBackStack()` in your adapter:
@@ -58,28 +62,42 @@ There are cases when some menu items (e.g. settings) should not simply replace t
5862
return menuItemId == R.id.navitem_settings;
5963
}
6064

61-
## Animations
65+
## Custom Actions
6266

63-
You can provide custom animations for your fragment transactions via `setCustomAnimations()`. Separate animations can be set for when you add the transaction to the back stack via `setBackStackCustomAnimations()`.
67+
If you don't want to handle fragments when a menu item is selected (e.g. to start an Activity), you can override `shouldHandleMenuItem()` in your adapter:
6468

65-
## OnNavigationItemSelectedListener
69+
@Override
70+
public boolean shouldHandleMenuItem(@IdRes int menuItemId) {
71+
return menuItemId != R.id.navitem_sample_activity;
72+
}
6673

67-
An additional `OnNavigationItemSelectedListener` can be provided via `setNavigationItemSelectedListener()`. This can be used to add behavior after the fragment transaction was commited. If you just want to close the drawer, the lib includes a `CloseDrawerNavigationItemSelectedListener`.
74+
Don't forget to set an additional `OnNavigationItemSelectedListener` via `setNavigationItemSelectedListener()`, where you have to handle these menu items:
75+
76+
adapter.setNavigationItemSelectedListener(new CloseDrawerNavigationItemSelectedListener(drawerLayout) {
77+
@Override
78+
public boolean onNavigationItemSelected(MenuItem item) {
79+
if(item.getItemId() == R.id.navitem_sample_activity) {
80+
startActivity(new Intent(MainActivity.this, SampleActivity.class));
81+
}
82+
83+
return super.onNavigationItemSelected(item);
84+
}
85+
});
86+
87+
## Animations
88+
89+
You can provide custom animations for your fragment transactions via `setCustomAnimations()`. Separate animations can be set for when you add the transaction to the back stack via `setBackStackCustomAnimations()`.
6890

6991
# Sample
7092

7193
A basic sample app with example Activities for both adapters is available in the `sample` project.
7294

7395
# Setup
7496

75-
Add the following to your `build.gradle`:
76-
77-
repositories {
78-
maven { url 'https://dl.bintray.com/patloew/maven' }
79-
}
97+
The library is available on jCenter. Add the following to your `build.gradle`:
8098

8199
dependencies {
82-
compile 'com.patloew.navigationviewfragmentadapters:adapters:0.1.1'
100+
compile 'com.patloew.navigationviewfragmentadapters:adapters:0.2.0'
83101
}
84102

85103
# License

library/build.gradle

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ apply plugin: 'com.jfrog.bintray'
33
apply plugin: 'com.github.dcendents.android-maven'
44

55
group = 'com.patloew.navigationviewfragmentadapters'
6-
version = '0.1.1'
6+
version = '0.2.0'
77
project.archivesBaseName = 'adapters'
88

99
android {
@@ -13,8 +13,8 @@ android {
1313
defaultConfig {
1414
minSdkVersion 9
1515
targetSdkVersion 24
16-
versionCode 2
17-
versionName "0.1.1"
16+
versionCode 3
17+
versionName "0.2.0"
1818
}
1919
buildTypes {
2020
release {

library/src/main/java/com/patloew/navigationviewfragmentadapters/BaseNavigationViewFragmentAdapter.java

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import android.support.design.widget.NavigationView;
2222
import android.support.v4.app.Fragment;
2323
import android.support.v4.app.FragmentManager;
24+
import android.view.MenuItem;
2425

2526
abstract class BaseNavigationViewFragmentAdapter {
2627

@@ -81,9 +82,9 @@ public final void setBackStackCustomAnimations(@AnimRes int enter, @AnimRes int
8182
}
8283

8384
/**
84-
* Sets an OnNavigationItemSelectedListener for adding additional
85-
* behavior (e.g. closing a drawer). This is called after the
86-
* fragment transaction is commited.
85+
* Sets an OnNavigationItemSelectedListener for adding additional behavior (e.g. closing
86+
* a drawer). This is called after the fragment transaction is commited. The return value of
87+
* OnNavigationItemSelectedListener.onNavigationItemSelected(MenuItem) is ignored.
8788
*
8889
* @param listener An OnNavigationItemSelectedListener
8990
*/
@@ -134,7 +135,7 @@ public String getTag(@IdRes int menuItemId) {
134135
public abstract Fragment getFragment(@IdRes int menuItemId);
135136

136137
/**
137-
* Can be overriden to declare that some menu items (e.g. settings)
138+
* Can be overriden to declare that some menu items (e.g. settings fragment)
138139
* should not simply replace the current fragment, but also be
139140
* added to the back stack.
140141
*
@@ -145,5 +146,15 @@ public boolean shouldAddToBackStack(@IdRes int menuItemId) {
145146
return false;
146147
}
147148

148-
149+
/**
150+
* Can be overriden to declare that some menu items should not be handled by the adapter (e.g. for
151+
* starting an Activity). You have to handle these items yourself by setting a listener with
152+
* setNavigationItemSelectedListener(NavigationView.OnNavigationItemSelectedListener).
153+
*
154+
* @param menuItemId
155+
* @return Whether menuItem should be handled by adapter
156+
*/
157+
public boolean shouldHandleMenuItem(@IdRes int menuItemId) {
158+
return true;
159+
}
149160
}

library/src/main/java/com/patloew/navigationviewfragmentadapters/NavigationViewFragmentAdapter.java

Lines changed: 38 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -56,49 +56,58 @@ private final class FragmentAdapterItemSelectedListener implements NavigationVie
5656
@Override
5757
public boolean onNavigationItemSelected(MenuItem item) {
5858
int itemId = item.getItemId();
59+
boolean handleItem = shouldHandleMenuItem(itemId);
60+
boolean selectItem = false;
5961

60-
if(shouldAddToBackStack(itemId)) {
61-
FragmentTransaction fragmentTransaction = fm.beginTransaction();;
62-
backstackAnimations.apply(fragmentTransaction);
63-
fragmentTransaction
64-
.replace(containerId, getFragment(itemId), getTag(itemId))
65-
.addToBackStack(null)
66-
.commit();
67-
fm.executePendingTransactions();
62+
if(handleItem) {
63+
if (shouldAddToBackStack(itemId)) {
64+
FragmentTransaction fragmentTransaction = fm.beginTransaction();
65+
;
66+
backstackAnimations.apply(fragmentTransaction);
67+
fragmentTransaction
68+
.replace(containerId, getFragment(itemId), getTag(itemId))
69+
.addToBackStack(null)
70+
.commit();
71+
fm.executePendingTransactions();
6872

69-
} else {
70-
String attachTag = getTag(itemId);
73+
} else {
74+
String attachTag = getTag(itemId);
7175

72-
Fragment attachFragment = fm.findFragmentByTag(attachTag);
76+
Fragment attachFragment = fm.findFragmentByTag(attachTag);
7377

74-
if(attachFragment == null || !attachFragment.isAdded()) {
75-
Fragment detachFragment = fm.findFragmentByTag(getTag(currentlyAttachedId));
78+
if (attachFragment == null || !attachFragment.isAdded()) {
79+
Fragment detachFragment = fm.findFragmentByTag(getTag(currentlyAttachedId));
7680

77-
FragmentTransaction fragmentTransaction = fm.beginTransaction();
78-
animations.apply(fragmentTransaction);
81+
FragmentTransaction fragmentTransaction = fm.beginTransaction();
82+
animations.apply(fragmentTransaction);
7983

80-
if (detachFragment != null && detachFragment != attachFragment) {
81-
fragmentTransaction.detach(detachFragment);
82-
}
84+
if (detachFragment != null && detachFragment != attachFragment) {
85+
fragmentTransaction.detach(detachFragment);
86+
}
87+
88+
if (attachFragment == null) {
89+
attachFragment = getFragment(itemId);
90+
fragmentTransaction.add(containerId, attachFragment, attachTag);
91+
} else {
92+
fragmentTransaction.attach(attachFragment);
93+
}
8394

84-
if (attachFragment == null) {
85-
attachFragment = getFragment(itemId);
86-
fragmentTransaction.add(containerId, attachFragment, attachTag);
87-
} else {
88-
fragmentTransaction.attach(attachFragment);
95+
fragmentTransaction.commitNow();
8996
}
9097

91-
fragmentTransaction.commitNow();
92-
}
98+
currentlyAttachedId = itemId;
9399

94-
currentlyAttachedId = itemId;
100+
selectItem = true;
101+
}
95102
}
96103

97104
if(listener != null) {
98-
return listener.onNavigationItemSelected(item);
99-
} else {
100-
return true;
105+
listener.onNavigationItemSelected(item);
106+
} else if(!handleItem) {
107+
throw new IllegalStateException("You have to set a listener with setNavigationItemSelectedListener() when menu items should not be handled by the adapter");
101108
}
109+
110+
return selectItem;
102111
}
103112
}
104113

library/src/main/java/com/patloew/navigationviewfragmentadapters/NavigationViewStateFragmentAdapter.java

Lines changed: 43 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -63,51 +63,59 @@ private final class FragmentAdapterItemSelectedListener implements NavigationVie
6363
@Override
6464
public boolean onNavigationItemSelected(MenuItem item) {
6565
int itemId = item.getItemId();
66+
boolean handleItem = shouldHandleMenuItem(itemId);
67+
boolean selectItem = false;
6668

67-
if(shouldAddToBackStack(itemId)) {
68-
FragmentTransaction fragmentTransaction = fm.beginTransaction();
69-
backstackAnimations.apply(fragmentTransaction);
70-
fragmentTransaction
71-
.replace(containerId, getFragment(itemId), getTag(itemId))
72-
.addToBackStack(null)
73-
.commit();
74-
fm.executePendingTransactions();
75-
76-
} else {
77-
String attachTag = getTag(itemId);
78-
79-
if(fm.findFragmentByTag(attachTag) == null) {
69+
if(handleItem) {
70+
if (shouldAddToBackStack(itemId)) {
8071
FragmentTransaction fragmentTransaction = fm.beginTransaction();
81-
animations.apply(fragmentTransaction);
82-
83-
String detachTag = getTag(currentlyAttachedId);
84-
85-
Fragment attachFragment = getFragment(itemId);
86-
Fragment detachFragment = fm.findFragmentByTag(detachTag);
87-
88-
if (detachFragment != null) {
89-
stateMap.put(detachTag, fm.saveFragmentInstanceState(detachFragment));
90-
fragmentTransaction.remove(detachFragment);
72+
backstackAnimations.apply(fragmentTransaction);
73+
fragmentTransaction
74+
.replace(containerId, getFragment(itemId), getTag(itemId))
75+
.addToBackStack(null)
76+
.commit();
77+
fm.executePendingTransactions();
78+
79+
} else {
80+
String addTag = getTag(itemId);
81+
82+
if (fm.findFragmentByTag(addTag) == null) {
83+
FragmentTransaction fragmentTransaction = fm.beginTransaction();
84+
animations.apply(fragmentTransaction);
85+
86+
String removeTag = getTag(currentlyAttachedId);
87+
88+
Fragment addFragment = getFragment(itemId);
89+
Fragment removeFragment = fm.findFragmentByTag(removeTag);
90+
91+
if (removeFragment != null) {
92+
stateMap.put(removeTag, fm.saveFragmentInstanceState(removeFragment));
93+
fragmentTransaction.remove(removeFragment);
94+
}
95+
96+
Fragment.SavedState fss = stateMap.get(addTag);
97+
if (fss != null) {
98+
addFragment.setInitialSavedState(fss);
99+
stateMap.remove(addTag);
100+
}
101+
fragmentTransaction.add(containerId, addFragment, addTag);
102+
103+
fragmentTransaction.commitNow();
91104
}
92105

93-
Fragment.SavedState fss = stateMap.get(attachTag);
94-
if (fss != null) {
95-
attachFragment.setInitialSavedState(fss);
96-
stateMap.remove(attachTag);
97-
}
98-
fragmentTransaction.add(containerId, attachFragment, attachTag);
106+
currentlyAttachedId = itemId;
99107

100-
fragmentTransaction.commitNow();
108+
selectItem = true;
101109
}
102-
103-
currentlyAttachedId = itemId;
104110
}
105111

106112
if(listener != null) {
107-
return listener.onNavigationItemSelected(item);
108-
} else {
109-
return true;
113+
listener.onNavigationItemSelected(item);
114+
} else if(!handleItem) {
115+
throw new IllegalStateException("You have to set a listener with setNavigationItemSelectedListener() when menu items should not be handled by the adapter");
110116
}
117+
118+
return selectItem;
111119
}
112120
}
113121

sample/build.gradle

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,14 @@ retrolambda {
3232
javaVersion JavaVersion.VERSION_1_6
3333
}
3434

35-
repositories {
36-
maven { url 'https://dl.bintray.com/patloew/maven' }
37-
}
38-
3935
dependencies {
4036
compile fileTree(dir: 'libs', include: ['*.jar'])
4137
testCompile 'junit:junit:4.12'
4238
compile 'com.android.support:appcompat-v7:24.0.0'
4339
compile "com.android.support:design:24.0.0"
4440

45-
//compile project(':library')
46-
compile 'com.patloew.navigationviewfragmentadapters:adapters:0.1.1'
41+
compile project(':library')
42+
//compile 'com.patloew.navigationviewfragmentadapters:adapters:0.2.0'
4743

4844
compile 'com.jakewharton:butterknife:8.1.0'
4945
apt 'com.jakewharton:butterknife-compiler:8.1.0'

sample/src/main/AndroidManifest.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
</intent-filter>
3030
</activity>
3131

32+
<activity android:name=".SampleActivity" />
33+
3234
</application>
3335

3436
</manifest>

sample/src/main/java/com/patloew/navigationviewfragmentadaptersample/MainActivity.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
package com.patloew.navigationviewfragmentadaptersample;
1616

17+
import android.content.Intent;
1718
import android.os.Bundle;
1819
import android.support.annotation.IdRes;
1920
import android.support.annotation.NonNull;
@@ -64,7 +65,16 @@ protected void onCreate(Bundle savedInstanceState) {
6465
myNavigationViewAdapter.attachTo(navigationView);
6566
myNavigationViewAdapter.setCustomAnimations(R.anim.abc_fade_in, 0);
6667
myNavigationViewAdapter.setBackStackCustomAnimations(R.anim.abc_grow_fade_in_from_bottom, 0, R.anim.abc_fade_in, R.anim.abc_shrink_fade_out_from_bottom);
67-
myNavigationViewAdapter.setNavigationItemSelectedListener(new CloseDrawerNavigationItemSelectedListener(drawerLayout));
68+
myNavigationViewAdapter.setNavigationItemSelectedListener(new CloseDrawerNavigationItemSelectedListener(drawerLayout) {
69+
@Override
70+
public boolean onNavigationItemSelected(MenuItem item) {
71+
if(item.getItemId() == R.id.navitem_sample_activity) {
72+
startActivity(new Intent(MainActivity.this, SampleActivity.class));
73+
}
74+
75+
return super.onNavigationItemSelected(item);
76+
}
77+
});
6878
}
6979

7080
@Override
@@ -119,5 +129,10 @@ public Fragment getFragment(@IdRes int menuItemId) {
119129
public boolean shouldAddToBackStack(@IdRes int menuItemId) {
120130
return menuItemId == R.id.navitem_settings;
121131
}
132+
133+
@Override
134+
public boolean shouldHandleMenuItem(@IdRes int menuItemId) {
135+
return menuItemId != R.id.navitem_sample_activity;
136+
}
122137
}
123138
}

0 commit comments

Comments
 (0)