So my situation is that i've implemented navigation drawer correctly (so to speak, it displays properly and calls out method (in a weird way but it triggers)) but it acts weird and I don't know what else to do but to ask u peeps !
Once i've started binding methods to drawer's menu items (options) i've begun to notice weird behavior. Let me explain by words first :
Let this be dummy menu :
Ok so you see the order goes: home - history - favourite - logout
So far i've implemented history and favorite this is the behaviour i get :
If i call history it will open activity properly and display data
If i call favourite i will open HISTORY FIRST then FAVOURITE SECOND (i can see that because when i press back it closes favourite, opens history)
I've added a dummy activity as third option to menu (not displayed on pic) and i get the same behaviour but this time it opens History - Favourite - Dummy if i click on dummy activity.
One more thing before i post the code of how i implemented it.
Lets take 2 of mine activities and make real time example ( all in same ciclus).
1) From home page i try to use drawer and call out history/fav it works perfectly, i enter search i try to use drawer call out history/fav works perfeclty, i press back return to main activity (home) press drawer to open history/favourite and puuf it's not working anymore... any idea if it's connected or just an separate problem to solve?
Implementation:
final NavigationView navigationView = findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(
new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
// set item as selected to persist highlight
menuItem.setChecked(true);
// close drawer when item is tapped
switch (menuItem.getItemId()) {
case R.id.nav_home: {
if (checkInternetConnection(getApplicationContext())) {
Log.i(LOG_TAG, "PROVJERA NETA POVEZAN");
start_loader();
} else {
mEmptyStateTextView.setText("Cannot connect to network, please check your network status and try again.");
// Clear the adapter of previous earthquake data
}
}
case R.id.nav_history: {
pozoviHistory(null);
}
case R.id.nav_favourite: {
pozoviFavorites();
}
}
mDrawerLayout.closeDrawers();
// Add code here to update the UI based on the item selected
// For example, swap UI fragments here
return true;
}
}
);
mDrawerLayout.addDrawerListener(
new DrawerLayout.DrawerListener() {
#Override
public void onDrawerSlide(View drawerView, float slideOffset) {
// Respond when the drawer's position changes
}
#Override
public void onDrawerOpened(View drawerView) {
// Respond when the drawer is opened
}
#Override
public void onDrawerClosed(View drawerView) {
// Respond when the drawer is closed
navigationView.getMenu().getItem(0).setChecked(true);
}
#Override
public void onDrawerStateChanged(int newState) {
// Respond when the drawer motion state changes
}
}
);
****** EDIT ********
Okay so from the answer below adding the break; to each case resolved issue of opening everything. I've managed to find more symptoms causing drawer to act dumb.
So the action i'm doing that's causing drawer to act dumb is :
- I've got inside activity a thread which makes http request and starts media player.
- Once the thread is finished through the listener i've added i begin reproduction of media player
- Once it initializes i inflate my layout with some layout that represents media player( could this be the issue of making drawer dumbs ? )
- Also slide right-to-left (for closing) is not working but clicking outside drawer (on activity layout) closes it normally
This is how i inflate :
DrawerLayout myLayout = (DrawerLayout) findViewById(R.id.cili_test);
View itemInfo1 = getLayoutInflater().inflate(R.layout.player2, myLayout, true);
You need to add break; in your switch case
Like this:
switch (menuItem.getItemId()) {
case R.id.nav_home: {
if (checkInternetConnection(getApplicationContext())) {
Log.i(LOG_TAG, "PROVJERA NETA POVEZAN");
start_loader();
} else {
mEmptyStateTextView.setText("Cannot connect to network, please check your network status and try again.");
// Clear the adapter of previous earthquake data
}
break;
}
case R.id.nav_history: {
pozoviHistory(null);
break;
}
case R.id.nav_favourite: {
pozoviFavorites();
break;
}
}
Related
I want Auto open drawable after start app android
used library https://github.com/mikepenz/MaterialDrawer
this code from Main Activity
If it possible
if possible
And the second question is, can I open the menu on all activities after the swipe to the right? Only the back button now works
drawer = new DrawerBuilder()
.withActivity(this)
.withToolbar(mToolbar)
.withSelectedItem(1)
.withAccountHeader(headerResult)
.addDrawerItems(
new PrimaryDrawerItem().withIdentifier(1).withName(R.string.Home).withIcon(FontAwesome.Icon.faw_home),
new PrimaryDrawerItem().withIdentifier(2).withName(R.string.News).withIcon(FontAwesome.Icon.faw_newspaper),
new PrimaryDrawerItem().withIdentifier(3).withName("About").withIcon(FontAwesome.Icon.faw_question_circle),
new PrimaryDrawerItem().withIdentifier(4).withName("Open Source").withIcon(FontAwesome.Icon.faw_github_square),
new PrimaryDrawerItem().withIdentifier(5).withName("Rate on Google Play").withIcon(FontAwesome.Icon.faw_thumbs_up)
)
.withTranslucentStatusBar(false)
.build();
drawer.setOnDrawerItemClickListener(new Drawer.OnDrawerItemClickListener() {
#Override
public boolean onItemClick(View view, int position, IDrawerItem drawerItem) {
switch (position) {
case 1:
drawer.closeDrawer();
return true;
case 2:
drawer.closeDrawer();
drawer.setSelection(1);
startActivity(new Intent(context, NewsListActivity.class));
return true;
case 3:
drawer.closeDrawer();
drawer.setSelection(1);
startActivity(new Intent(context, AboutTheDevActivity.class));
return true;
case 4:
drawer.closeDrawer();
drawer.setSelection(1);
libsBuilder.start(context);
default:
return true;
}
}
});
I suggest to refactor your application to single activity structure. This will help to solve both of your problems.
You may just open the drawer in activity onCreate method. It is called when activity created, with single activity - when app started.
Save that drawer was opened to instance state if you need more accuracy here and don't want the drawer to be opened on activity recreation events (states when system decides to destroy your activity to release memory)
use fragments for showing app screens
open drawer in this single activity and manage toolbar from activity so it could be opened on every screen
Single activity is the way google recommends to structure apps.
How can I prevent the ActionBar back button (we gonna say ABBB) of my SecondActivity to recreate the MainActivitywhen clicked ?
I have a ListView in the MainActivity and it can be edited using the SecondActivity. The problem is that when the user presses the ABBB, the ListView is reset to default...
However, when the user clicks my OK button or presses physical back button, there is not any problem because I'm using finish();
#Override
public void onBackPressed() {
finish();
}
If I use this code... :
switch (item.getItemId()) {
case (android.R.id.home):
finish();
}
...there is the same problem because, I guess, this method is called after "Android's code".
How can I totally override Android ABBB's clicked code to set it to just call finish(); ?
The ideal scenario is, when are you in the SecondActivity (I take it that, this means that you are in Edit mode), and you press the device back button or ABBB, you show a subtle alert to the user saying "do they really want to dismiss the editing", or go ahead and apply the edit done as in the Contacts application.
So that being said, if all you require is to finish() the activity on press of ABBB, the code that you shown above should work fine (though you need to put return true; after finish()). It works for me. Try the below one in your activity.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed(); // or finish();
return true;
}
return super.onOptionsItemSelected(item);
}
I put onBackPressed(); because your ABBB with now imitate your device back button.
Or, you can set your parent activity's launch mode as -
android:launchMode="singleTop"
that will do all without changing anything.
Reference
The official page for the Navigation Drawer design pattern states:
Sometimes the user will be in a state where a contextual action bar
(CAB) appears instead of the app’s action bar. This typically happens
when the user selects text or selects multiple items after a
press-and-hold gesture. While the CAB is visible, you should still
allow the user to open the navigation drawer using an edge swipe.
However, replace the CAB with the standard action bar while the navigation drawer is open. When the user dismisses the drawer,
re-display the CAB.
But after researching I can't seem to find a way to "dismiss" the Contextual Action Bar inside my
#Override
public void onDrawerOpened(View drawerView) {
// ... My Code ...
}
method.
In my case a CAB (with copy, paste, etc. options) may appear when a user selects text from an EditText in an Activity which itself displays a Nav. Drawer.
I've seen this question+answer but it doesn't quite fix my problem as it's related to a custom ActionMode. How can I "dismiss" the CAB - the one that shows up when a user selects text - whenever the navigation drawer is toggled?
It is possible. You have to grab a reference to the ActionMode when it is created, and the ActionMode.Callback in your Activity:
#Override
public void onActionModeStarted(ActionMode mode) {
super.onActionModeStarted(mode);
mActionMode = mode;
}
#Override
public void onActionModeFinished(ActionMode mode) {
super.onActionModeFinished(mode);
mActionMode = null;
}
#Override
public ActionMode onWindowStartingActionMode(ActionMode.Callback callback) {
mActionModeCallback = callback;
return super.onWindowStartingActionMode(callback);
}
Then when your drawer opens/closes, finish the ActionMode or start a new ActionMode from the ActionMode.Callback:
#Override
public void onDrawerOpened(View drawerView) {
if (mActionMode != null) {
mActionMode.finish();
}
}
#Override
public void onDrawerClosed(View drawerView) {
if (mActionModeCallback != null) {
startActionMode(mActionModeCallback);
}
}
Action Bar
I'm talking about the (Number 1, in the pic), button with a little arrow and the app icon and the top left side of the screen. It is automatically defined when we select the "Black activity" template.
My app has a pretty huge hierarchy graph, got about 25 activities now.
I'm basically just showing a few tutorials and one can navigate to it according to the categories.
Now that "Back" (?) button thingy on action bar is on every screen I have, and I do want to keep it. The code shows no error, but when I actually press that button, the app stops working.
What I want, is to just replicate the actual back button function with that (Number 1) button, that I showed in the image.
When I press it, the top most screen should close, and the last one should open. Just close the screen.
What I tried :
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
this is the the function that inflates that buggy button along with the action bar. I tried to replace the entire code, and call "Finish" function, but that failed miserably.
I was unable to find a function specifically made for that top left most button...
I want the top most screen on the stack(the one in the foreground) to close, when this button is touched.
How to do this ?
I think the easiest way out is follows:
I am assuming that from activity A you are starting the activity B. Now from activity B you want to go back to activity A on pressing the top left back button on action bar. simply call this.finish() or ActivityName.this.finish() from there:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
this.finish();
return true;
}
return super.onOptionsItemSelected(item);
}
This should finish your current activity. However if you have lot of activities, then you might have to do this in all the activities. To save yourself from that effort, you can make a class lets call it AbstractActivity; that extends Activity. Then you can extend all your other activity classes to extend that class(AbstractActivity). Inside AbstractActivity you can put the above code. So now that piece of code would be valid for all your activities and that feature would be implemented for all of them. Basically this sort of thing (Inheritance)can be used any time, when there are some common features which would be applicable to your many classes.
If you are receiving any errors, please do post your LogCat if you require further help.
Hope this helps you.
just giving basic code given by #shobhit puri...
for invoking the action bar back button..add the following code in the onCreate() method along with the onOptionsItemSelected....
protected void onCreate(Bundle savedInstanceState)
{
ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_information);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
this.finish();
return true;
}
return super.onOptionsItemSelected(item);
}
I found a workaround to actually enable the ActionBar home button on the nested PreferenceScreen... however it doesn't call OnOptionsItemSelected in my PreferenceActivity. Anyone know a way to actually use the home button on a nested PreferenceScreen?
Modification of post 35 here:
http://code.google.com/p/android/issues/detail?id=4611
#Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference)
{
super.onPreferenceTreeClick(preferenceScreen, preference);
if (preference!=null)
if (preference instanceof PreferenceScreen)
if (((PreferenceScreen)preference).getDialog()!=null)
((PreferenceScreen)preference).getDialog().getActionBar().setHomeButtonEnabled(true);
return false;
}
I had this problem recently and this is how I solved it. Firstly to access the PreferenceScreen I use the exact same method you mentioned above.
#Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
super.onPreferenceTreeClick(preferenceScreen, preference);
// If the user has clicked on a preference screen, set up the action bar
if (preference instanceof PreferenceScreen) {
initializeActionBar((PreferenceScreen) preference);
}
return false;
}
From here I looked into what a PreferenceScreen is, and I was saddened to find out it is just wrapper of a Dialog. Moving forward, I then set the actionbar display options and attempt find the home button area. This unfortunately wasn't too easy to get, but with the help of the hierarchy viewer I managed to gain access by finding the home icon and then its parent views. Once we have access to the containing LinearLayout, we can attach an onClickListener where we dismiss the PreferenceScreen's dialog, which calls PreferenceScreen's onDismissListener and returns us to the previous screen.
/** Sets up the action bar for an {#link PreferenceScreen} */
public static void initializeActionBar(PreferenceScreen preferenceScreen) {
final Dialog dialog = preferenceScreen.getDialog();
if (dialog != null) {
// Inialize the action bar
dialog.getActionBar().setDisplayHomeAsUpEnabled(true);
// Apply custom home button area click listener to close the PreferenceScreen because PreferenceScreens are dialogs which swallow
// events instead of passing to the activity
// Related Issue: https://code.google.com/p/android/issues/detail?id=4611
View homeBtn = dialog.findViewById(android.R.id.home);
if (homeBtn != null) {
OnClickListener dismissDialogClickListener = new OnClickListener() {
#Override
public void onClick(View v) {
dialog.dismiss();
}
};
// Prepare yourselves for some hacky programming
ViewParent homeBtnContainer = homeBtn.getParent();
// The home button is an ImageView inside a FrameLayout
if (homeBtnContainer instanceof FrameLayout) {
ViewGroup containerParent = (ViewGroup) homeBtnContainer.getParent();
if (containerParent instanceof LinearLayout) {
// This view also contains the title text, set the whole view as clickable
((LinearLayout) containerParent).setOnClickListener(dismissDialogClickListener);
} else {
// Just set it on the home button
((FrameLayout) homeBtnContainer).setOnClickListener(dismissDialogClickListener);
}
} else {
// The 'If all else fails' default case
homeBtn.setOnClickListener(dismissDialogClickListener);
}
}
}
}