How to check if Up button enabled? - android

Some where in code I add
ActionBar ab = ((AuthActivity) getActivity()).getSupportActionBar();
if (ab != null) {
ab.hide();
ab.show();
ab.setTitle(R.string.auth_tt_title);
ab.setDisplayHomeAsUpEnabled(true);
}
Later, I add fiew fragments one of which may change title and display home button.Thus, I wat to save state for ActionBar before I made changes, to be able to restore it asfter fragment will be gone.
I can get title as
private String getAbStatus(AppCompatActivity activity) {
String title="";
boolean visible;
ActionBar ab = activity.getSupportActionBar();
if (ab != null) {
if (ab.getTitle() != null) title = ab.getTitle().toString();
}
return title;
}
But how can I get state of HomeAsUp?

Short answer:
if (ab.getDisplayOptions() & ActionBar.DISPLAY_HOME_AS_UP != 0) {}
Long answer here: How do I get ActionBar attribute in my class

Related

How can I change the ActionBar color of individual fragments in Android?

Is there any way to change the ActionBar color of fragments and change the title displayed in the ActionBar to the title of the menu option that was pressed?
If you are using AppCompat you always have to call getSupportActionBar()
Change Title :
getSupportActionBar().setTitle("Your Title");
Change Color :
getSupportActionBar().setBackgroundDrawable(new ColorDrawable(Color.YOUR_COLOR));
If in Fragment :
Change Title :
getActivity().getActionBar().setTitle("YOUR TITLE");
Change Color :
getActivity().getAcationBar().setBackgroundDrawable(new ColorDrawable(Color.YOUR_COLOR));
Hope this help you
This is the suggested answer written in java :
getActionBar().setTitle("Test");
getActionBar().setBackgroundDrawable(new ColorDrawable("COLOR"));
If you're using support libraries:
android.support.v7.app.ActionBar supportActionBar = ((AppCompatActivity) getActivity()).getSupportActionBar();
if (supportActionBar != null) {
supportActionBar.setTitle("My action bar title");
View view = new View(getContext());
view.setBackgroundColor(getResources().getColor(R.color.my_color));
supportActionBar.setBackgroundDrawable(view.getBackground());
}
Otherwise:
android.app.ActionBar actionBar = getActivity().getActionBar();
if (actionBar != null) {
actionBar.setTitle("My action bar title");
View view = new View(getContext());
view.setBackgroundColor(getResources().getColor(R.color.my_color));
actionBar.setBackgroundDrawable(view.getBackground());
}

How to keep drawer menu open after item selection?

I have used drawer menu from android.support.v4.widget.DrawerLayout for my xamarin application. Currently when I click each item in the drawer list the drawer layout closes automatically. I don't remember that I have set up anywhere that I want to close the layout after selection! If this is the default behavior please tell me where can I say I want to keep it open after I select an Item?
In the NavigationDrawerFragment class
just comment the line where it closes the drawer after item selection
private void selectItem(int position) {
mCurrentSelectedPosition = position;
if (mDrawerListView != null) {
mDrawerListView.setItemChecked(position, true);
}
if (mDrawerLayout != null) {
//mDrawerLayout.closeDrawer(mFragmentContainerView);
}
if (mCallbacks != null) {
mCallbacks.onNavigationDrawerItemSelected(position);
}
}

CollapsingToolbarLayout setTitle() doesn't work after activity created

In my activity I've created a method for the fragments to update the title :
public void setTitle(String title) {
ActionBar ab = getSupportActionBar();
if (ab != null) {
if (title == null) {
title = getString(R.string.string_title);
}
ab.setTitle(title);
}
}
The toolbar is part of a CollapsingToolbarLayout.
It looks like the title is set correctly for the first fragment, however, when the second one tries to update it, it doesn't get updated.
I'm running with v 23 so this is not the known bug.

How to fix getActionBar method may produce java.lang.NullPointerException

I am using a toolbar as my actionbar in an activity. I am trying to add the method getActionBar().setDisplayHomeAsUpEnabled(true); to the Activity.java file for Up navigation for older devices.
The method produces the following error message in Android Studio:
Method invocation may produce java.lang.NullPointerException
The Up navigation on the toolbar works fine on newer devices...now I'm trying to figure out how to make sure it will work for older devices.
Please advise.
From build.gradle:
dependencies {
compile "com.android.support:appcompat-v7:22.1.0"
}
From AndroidManifest.xml:
android:theme="#style/Theme.AppCompat.NoActionBar.FullScreen"
From styles.xml
<style name="Theme.AppCompat.NoActionBar.FullScreen" parent="AppTheme">
<item name="android:windowNoTitle">true</item>
<item name="windowActionBar">false</item>
<item name="android:windowFullscreen">true</item>
from Activity.java
public class CardViewActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.cardviewinput);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
if (toolbar != null) {
// Up navigation to the parent activity for 4.0 and earlier
getActionBar().setDisplayHomeAsUpEnabled(true);
toolbar.setNavigationIcon(R.drawable.ic_action_previous_item);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
}
}
Actually Android Studio isn't showing you an "error message", it's just a warning.
Some answers propose the use of an assertion, Dalvik runtime has assertion turned off by default, so you have to actually turn it on for it to actually do something. In this case (assertion is turned off), what you're essentially doing is just tricking Android Studio to not show you the warning. Also, I prefer not to use "assert" in production code.
In my opinion, what you should do is very simple.
if(getActionBar() != null){
getActionBar().setDisplayHomeAsUpEnabled(true);
}
Update:
In case you're using the support library version of the Action Bar, you should replace getActionBar() with getSupportActionBar().
if(getSupportActionBar() != null){
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
First off, you need to set the toolbar as the support ActionBar.
Then if you're certain it's going to be there all the time, just assert it as != null. This will tell the compiler it won't be null, so the null check passes.
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.cardviewinput);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
assert getSupportActionBar() != null;
getSupportActionBar().setDisplayHomeAsUpEnabled(true); // it's getSupportActionBar() if you're using AppCompatActivity, not getActionBar()
}
Thank You Andrew for your answer.
If you have a Nav Drawer or something else that uses getSupportActionBar() you need to add assert getSupportActionBar() != null;
Peace,
Example:
#Override
public void setTitle(CharSequence title) {
mTitle = title;
assert getSupportActionBar() != null;
getSupportActionBar().setTitle(mTitle);
}
Try this :
private ActionBar getActionBar() {
return ((AppCompatActivity) getActivity()).getSupportActionBar();
}
What I have done is override the getSupportActionBar() method in my base Activity and add a #NonNull annotation. This way, I only get one lint warning in the base activity about how I use #NonNull annotation for something that has a #Nullable annotation.
#NonNull
#Override
public ActionBar getSupportActionBar() {
// Small hack here so that Lint does not warn me in every single activity about null
// action bar
return super.getSupportActionBar();
}
I created a generic class such as:
public final class Cast
{
private Cast() {}
/**
* Helps to eliminate annoying NullPointerException lint warning.
*/
#android.support.annotation.NonNull
public static <T> T neverNull(T value)
{
return value;
}
}
then I can use it for any call with NullPointerException warning for which I am sure that it will never happen, e.g.
final ActionBar actionBar = Cast.neverNull(getSupportActionBar());
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
P.S. don't forget to add "com.android.support:support-annotations" to your gradle file.
add assert getSupportActionBar() != null; before getSupportActionBar().setDisplayHomeAsUpEnabled(true);
if(actionBar != null) {
actionBar.setHomeButtonEnabled(true);
actionBar.setBackgroundDrawable(ContextCompat.getDrawable(mContext,
R.drawable.action_bar_gradient));
}
use this theme: android:theme="#style/Theme.AppCompat.Light.NoActionBar"
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.setTitle("Title");
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
actionBar.setHomeButtonEnabled(true);
actionBar.setHomeAsUpIndicator(R.drawable.ic_action_previous_item);
actionBar.setDisplayHomeAsUpEnabled(true);
Alternatively you could assert actionbar to not null.Add the assertion before calling your actionbar as follows
assert getSupportActionBar() != null;
Final snippet would therefore look as follows:
setSupportActionBar((Toolbar) findViewById(R.id.toolbar));
assert getSupportActionBar() != null;
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Try this :
setSupportActionBar (toolbar);
if(getSupportActionBar () != null) {
assert getSupportActionBar () != null;
getSupportActionBar ().setDisplayHomeUpEnabled(true);
}
Note that setSupportActionBar(toolbar) should be before getSupportActionBar().
if(getSupportActionBar() != null){
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
OR
Replace the MainActivity extends AppCompatActivity to public class MainActivity extends AppCompatActivity
just check getSupportActionBar not equal to null
setSupportActionBar(toolbar);
if(getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setTitle("Daily Shopping List");
}
If you are importing
android.app.ActionBar
you have to use getActionBar()
and if you are importing
android.support.v7.app.ActionBar
use getSupportActionBar()

Up navigation not appearing for single activity app with multiple fragments

I have an android application that has a single main activity that employs many fragments that switch into view. I'm not sure if that's the right way to do it, but I have inherited this project and would like to avoid doing any major refactors like changing the fragments to all be activities or something like that.
According to the android documentation, it looks like calling the setDisplayHomeAsUp(bool) function should just display the up button by default:
Set whether home should be displayed as an "up" affordance. Set this
to true if selecting "home" returns up by a single level in your UI
rather than back to the top level or front page.
The main issue is that when I use the function:
actionBar.setDisplayHomeAsUpEnabled(true);
It does not set the button that opens the navigation drawer to instead turn into an 'Up' button. It just removes the 'hamburger' ic_drawer icon from the side. The navigation drawer still opens.
Here is the custom code for the NavigationDrawerFragment (I copy+pasted the exact file that you get when you create a new application with a navigation drawer within android studio):
NavigationDrawerFragment.java
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
mDrawerListView = (ListView) inflater.inflate(
R.layout.fragment_navigation_drawer, container, false);
mDrawerListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
selectItem(position);
}
});
PopulateAppDrawerList();
return mDrawerListView;
}
public void PopulateAppDrawerList() {
List<AppOption> allApps = getAllApps();
List<AppOption> filteredApps = new ArrayList<AppOption>();
for (int i = 0; i < allApps.size(); i++) {
if (allApps.get(i).getLaunchable()) {
filteredApps.add(allApps.get(i));
}
}
NavDrawerListAdapter adapter = new NavDrawerListAdapter(filteredApps, MainActivity.getInstance());
mDrawerListView.setAdapter(adapter);
mDrawerListView.setItemChecked(mCurrentSelectedPosition, true);
}
Then, I have the other fragments that all extend 'BaseAppFragment', which contains the following:
BaseAppFragment.java
public class BaseAppFragment extends Fragment {
#Override
public void onStart() {
super.onStart();
MainActivity.getInstance().onSectionAttached(this);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
} }
This is what allows me to change the title on the action bar in one single area and set whether or not it should have the back button set by default.
MainActivity.java
public void onSectionAttached(android.app.Fragment fragment) {
Class fragmentType = fragment.getClass();
ActionBar actionBar = getActionBar();
mNavigationDrawerFragment.PopulateAppDrawerList();
if (fragmentType != null) {
if (fragmentType.equals(AuthenticationFragment.class)) {
actionBar.setDisplayHomeAsUpEnabled(false);
mTitle = "Login";
} else if (fragmentType.equals(MyOptionsFragment.class)) {
actionBar.setDisplayHomeAsUpEnabled(false);
mTitle = "My Options";
} else if (fragmentType.equals(GLAuthenticationFragment.class)) {
actionBar.setDisplayHomeAsUpEnabled(false);
mTitle = "Login";
} else if (fragmentType.equals(InitialLoginFragment.class)) {
actionBar.setDisplayHomeAsUpEnabled(false);
mTitle = "Login";
} else if (fragmentType.equals(LoginFragment.class)) {
actionBar.setDisplayHomeAsUpEnabled(false);
mTitle = "Login";
} else if (fragmentType.equals(DailyOverviewFragment.class)) {
actionBar.setDisplayHomeAsUpEnabled(true);
mTitle = "Overview";
} else if (fragmentType.equals(SingleComponentFragment.class)) {
actionBar.setDisplayHomeAsUpEnabled(true);
SingleComponentFragment singleComponentFragment = (SingleComponentFragment) fragment;
if (singleComponentFragment != null && singleComponentFragment .mComponent != null) {
mTitle = String.format("Back To Day %s", singleComponentFragment.mComponent.getDay() + "");
}
else {
mTitle = "";
}
} else if (fragmentType.equals(singleDayOverviewFragment.class)) {
actionBar.setDisplayHomeAsUpEnabled(true);
mTitle = "Back To Overview";
}
}
actionBar.setTitle(mTitle);
}
The title setting works perfectly and there are no errors when the setDisplayHomeAsUpEnabled(true) is called, but it still shows no Up button. I know that right now I am not setting any type of fragment navigation hierarchy other than the addToBackStack(null) call in the Fragment Transaction, but it still seems like this code should be enough to have the up button replace the navigation drawer button.
The problem is that the navigation drawer icon hijacks the up indicator. In terms of which View in the action bar is displaying the icon, the navigation drawer icon is also the up icon. This is why you need to call actionBar.setDisplayHomeAsUpEnabled(true); for the navigation drawer icon to show.
To fix this, you need to use ActionBarDrawerToggle#setDrawerIndicatorEnabled(false). This will replace the navigation drawer icon with the up icon. From the documentation for this method:
When the indicator is disabled, the ActionBar will revert to displaying the home-as-up indicator provided by the Activity's theme in the android.R.attr.homeAsUpIndicator attribute instead of the animated drawer glyph.
Had the same problem as you, and I struggled getting a consistent Up arrow behaviour. I made this example to show how to properly do it when using a single activity with navigation drawer and multiple levels.
https://github.com/tskulbru/android-navdrawer-up-pattern-example

Categories

Resources