Android ActoinBar homeAsUp only works once - android

I'm working on an app that only uses a single Activity and switches out fragments as they are needed with the navigation drawer.
Now we want to navigate back from one of these fragments by using the homeAsUp button in the ActionBar.
I have followed all the steps to set the button up. From disabling the navigation drawer setDrawerIndicatorEnabled(false) and calling setDisplayHomeAsUpEnabled(true) in the fragment's onCreateView().
I also set setHomeButtonEnabled(true) in the MainActivity's onCreate() however because the app is already in the MainActivity, we cannot specify a Parent Activity.
Whenever I run a fresh install of the app, the homeAsUp button works and is registered in the onBackPressed(), not onOptionsItemSelected() method. However, when I close the app and run it again the button does not even register clicks.
In onBackPressed() I check a few conditions, but it does not block the button press.
In onOptionsItemSelected() I check for android.R.id.home.
Unfortunately, I cannot post the code.
This post describes what I'm trying to achieve: Switching between Android Navigation Drawer image and Up caret when using fragments

I managed to fix the issue I was experiencing. It was a very simple mistake.
Because I'm not the original author of this code, I went through the MainActivity thoroughly.
As it turns out the original author called setDisplayHomeAsUpEnabled in the onCreate function (which is extremely long), but near the end he also called setSupportActionBar, which made the first call of setDisplayHomeAsUpEnabled useless. Moving setDisplayHomeAsUpEnabled below setSupportActionBar fixed my problem.
If you did everything correctly, make sure that your code is written in the correct order.
Furthermore, if you use custom toolbars in other fragments, remember to set your original Support Action Bar by calling setSupportActionBar(toolbar.find(this)) in onResume of your MainActivity.

Related

Display Navigation Drawer in each Activity after connecting Fragments with Activities (Android - Github tutorial)

I am trying to implement a navigation drawer (left slide menu) in my Android project. My application has a main activity till now, in which you could navigate to others with Intent method through buttons.
So, I searched for a navigation drawer and I found/followed the exact steps of THIS tutorial. My code related to the menu is exactly the same, so for that reason, I am not posting it below.
Related to my code:
The three fragments that I created, were just extended the class Fragment and where completely empty.
The ONLY change from the code in the tutorial, is inside the res/layout/activity_main.xml, because I changed the com.codepath.examples.navdrawerdemo.FragmentNavigationDrawer to 'my_project's_name'.FragmentNavigationDrawer.
What I managed to do:
I managed to create the menu that I want and display it ONLY if I make the MainActivity.java as the launcher inside the AndroidManifest. When I see the menu, I can go to each fragment through it, but I can't go to any of my Activities because I didn't link the fragments with the activities that I want. My menu, also does this transition that it should, so I am completely fine with the style of it.
What I want to do:
I just want to have the same menu inside every activity that I have already created, and when I click in an item in the menu, I want to navigate to an activity that I want BUT I want the activity to still display the menu.
I searched for solutions, but when I put back my first Activity as launcher in the Android Manifest, and set a layout for example inside the Fragment for it, it's just a useless layout. And when I tried to do an Intent to call my Activity inside the Fragment, the menu disappeared.
P.S I didn't changed any of my Activitie's code or of their layouts. I added only the code from the tutorial!

Back button behavior differs depending on whether I entered activity from the nav drawer or from a UI element

I created a NavigationDrawerFragment, which is actually just a slightly modified version of the code Android Studio generates.
I have a Dashboard activity that contains NavigationDrawerFragment and that can launch several other activities, each of which also contain the NavigationDrawerFragment. Let's call one of these activities Foo.
If I enter Foo from the Dashboard using the Dashboard's nav drawer, then open Foo's nav drawer, the back button will correctly close the nav drawer. HOWEVER, if I entered Foo using a UI element (that was in place before I implemented a nav drawer), then open Foo's nav drawer, the back button returns to the Dashboard activity rather than closing the nav drawer.
I can't figure out why this is occuring. For the NavigationDrawerFragment I have an ItemClickListener and for the UI element I have a ClickListener, but in both situations I am launching a new Foo activity using an intent.
I am wondering if there is something being set that I just don't realize, and if I have control over that something.
I know that I could override onBackPressed to check for the drawer being open (as shown here), but that feels hacky as there is obviously some behavior happening here that I am not aware of.
Edit: This has something to do with ActionBar-PullToRefresh. I removed it from Foo and the nav drawer works correctly.
Edit 2: I was wrong about pull-to-refresh, as #adneal pointed out. There must have been a coincidence that made me think that. I ended up overriding onBackPressed and conditionally checking if the drawer is open or not. Also as #adneal pointed out, the problem has to do with focus. I am still so very curious as to how the focus could be different when launching the activities the same way, but from different places.
So, I'm fairly certain I understand what's going on, but I'm still unsure about why it only seem to happen when you use a View.OnClicklistener. Maybe there's a little more to your code that I don't know about or maybe I overlooked something in those regards.
But the reason you're having this problem is due to how Android handles the View.onKey... event. DrawerLayout overrides View.onKeyDown and View.onKeyUp, checking each time if you're pressing the "back" button so it can determine whether or not to close the drawer. But this event isn't taking place, in your case, because the AdapterView you have set will take the focus away from the DrawerLayout after you call AdapterView.setAdpater.
How to fix it
Short of copying over the DrawerLayout source and modifying it, which you could definitely do; it's only one class, I would recommend converting each Foo Activity into a Fragment, then use the FrameLayout you typically place when creating a DrawerLayout to display them. You should create a NavigationDrawerActivity instead of a Fragment to host everything.
This has to do with the way DrawerLayout is laid out, in that it has to use MeasureSpec.EXACTLY. In other words, when you place your NavigationDrawerFragment ontop of your Foo layout, it takes up the entire space. If you called View.setFocusableInTouchMode after you set your ListAdapter in Foo, the DrawerLayout would work like it should, but the AdapterView wouldn't scroll anymore. And you can't toggle that focus based on the open or closed position of the DrawerLayout, because either way it takes up the entire space and always return true in View.onTouchEvent.
Or just override Activity.onBackPressed, which really isn't as "hacky" as you may think, but I understand what you mean.
At any rate, I hope this is clear and/or helpful at the very least. Took me a little bit to reproduce your problem, but after I did it didn't take long to rule out the pull-to-refresh library. In short, I think it's a focus issue. Prove me wrong.
Source
You can view the source for the DrawerLayout here to look over how it handles the "back" event
You can see here how AdapterView.checkFocus works
You can see here in ListView (GridView is the same), when AdapterView.checkFocus is called

Options menu not showing up in Android

My objective is to you use one menu for all activities. For that, I have a base activity which consists of 2 methods: onCreateOptionsMenu() and onOptionsItemSelected(). In onCreateOptionsMenu(), I am creating a menu using MenuInflater.
Further, I have 2 activities which extends the above BaseActivity so that same menu is shown for both the activities. My issue is that, when my first activity is launched, options menu is shown, I move to second activity from the first. In the second activity also, when I press the menu button, I am able to view the menu. After that, using Back key press, I come to first activity again, the menu is also shown up there, But when I move to the second activity thereafter, menu is not shown to me.
Can you please post code of your Base Activity's onOptionsItemSelected and onCreateOptionsMenu?
Anyway, with no code available. And not enough clarity, I assume that the following will work for you...
add #Override
public void onBackPressed() {
finish();
}
to your base activity
Minimum SDK version could be the cause. If you reduce it to 13-, you should probably see the menu show up again. Good article on this subject: POST

Why does my ivar become null when reloading fragment through action bar button

I have an app with 3 tabs. The fragments for each tab are created with a SectionsViewPager. I've created a Reloadable interface with 1 method void reload(Context ctx);. On the actionBar I've added a reload button. When the button is pressed I'm checking if the fragment implements Reloadable and if it does, I call reload(this);.
So far so good...
In the app I've previously included a pull-to-refresh functionality, but because this does not feel very "Androidy" I want to replace it with the above described functionality (reload button in actionBar, when pressed, refresh fragment). The pull-to-refresh function worked fine by the way. I've remapped the reload function to the new one from the Reloadable interface.
Now I'm testing my reload button and the app crashes.
The app crashes because apparently one of my TextViews isn't bound to my ivar when using the reload button. It is bound when I use pull-to-refresh though. The following is the relevant code:
mTextView.setVisibility(isEmpty ? View.VISIBLE : View.INVISIBLE);
mTextView is null when called through the reload button on actionBar. It's not null when using the pullToRefresh functionality that's part of the fragment. What is going wrong here?

ActionBar refresh

I am using Android compat library to show a ActionBar at the top of the screen.
The actionBar contains a refresh button which is a rotating circle if it is pressed.
To activate the rotation of the circle in the actionBar I use following:
getActionBarHelper().setRefreshActionItemState(true);
This works fine, if I call it via a button click or via onOptionsItemSelected().
But if I call it in onCreate or onStart nothing happens. I am wondering why?
Remember that the rotating circle only appears once onCreateOptionsMenu has been executed. It means that it will not appear if you try to execute getActionBarHelper().setRefreshActionItemState(true) on your Activity "onCreate". If you try on "onResume" it will work. You can use it wherever you need once onCreateOptionsMenu has been executed.
I hope it helps you.

Categories

Resources