I am using Android studio 3.3 canary 8 and my API level is 28. I have an activity which has the action bar and another PagerSlidingTabStrip. The action bar has a title and a close button to go home. Now, I want to get rid of these two toolbars and one toolbar either the action bar or the tabstrip, but I want the close button and the tabs as well. Can the action bar contain tabs? Or can I include the close button in the tabstrip anyhow? If it is not possible then can I do any trick to have something like this? The relevant part of my activity is here:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_info);
ViewPager viewPager = findViewById(R.id.viewPager);
InfoFragmentPagerAdapter adapter = new InfoFragmentPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new InfoAboutFragment (), getString(R.string.about));
adapter.addFragment(new InfoHelpFragment(), getString(R.string.help));
PagerSlidingTabStrip tabsStrip = findViewById(R.id.tabs);
tabsStrip.setViewPager(viewPager);
tabsStrip.setShouldExpand(true);
tabsStrip.setAllCaps(true);
tabsStrip.setTextColor(Color.WHITE);
tabsStrip.setDividerColor(Color.TRANSPARENT);
tabsStrip.setDividerPadding(20);
tabsStrip.setIndicatorColor(Color.WHITE);
tabsStrip.setIndicatorHeight(12);
tabsStrip.setUnderlineColor(Color.TRANSPARENT);
setupActionBar();
}
private void setupActionBar() {
getLayoutInflater().inflate(R.layout.toolbar, findViewById(android.R.id.content));
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
if (getSupportActionBar() != null) {
getSupportActionBar().setTitle(R.string.about);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_close_white_36dp);
}
}
I'm using android.support.v7.widget.Toolbar and AppCompatActivity. I've enabled back up button like this supportActionBar.setDisplayHomeAsUpEnabled(true);.
The fragment in side the activity will set the title and subtitle in onResume() like this
AppCompatActivity activity = (AppCompatActivity) getActivity();
activity.setTitle(title);
activity.getSupportActionBar().setSubtitle("Bingo");
The problem is, when the fragment shows up onResume is called but subtitle is not shown. When I press power OFF and ON, means fragment goes to pause and resumes again. Now, subtitle is visible. I've tested on other android phone as well.
Can you please help me finding out the problem?
This is because the toolbar is not rendered when you are setting the subtitle.
Try this code,Set title and subtitle inside this method
private void setupToolbar(){
toolbar = (Toolbar) findViewById(R.id.detail_toolbar);
if(toolbar != null){
setSupportActionBar(toolbar);
}
toolbar.post(new Runnable()
{
#Override
public void run()
{
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setTitle(mTitle);
getSupportActionBar().setSubtitle("Subtitle);
}
});
}
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()
In my Android application I'm using the ActionBar. I want to show users some status using logo placed in the left side of the ActionBar. I can do this:
ActionBar actionBar = getSupportActionBar();
actionBar.setIcon(R.drawable.new_icon);
and it works.
The problem is that this state in to persistent. If I change activity ActionBar reset itself, so default logo is shown. Is there any way to save state of the ActionBar during application runtime?
Use the standar lifecycle callbacks from Activities
In the OnCreate method of your activity try to read the state
public void onCreate(Bundle icicle) {
if (data!=null)
{
ActionBar actionBar = getSupportActionBar();
int state = data.getInt("status");
if (state==1)
actionBar.setIcon(R.drawable.icon_a);
else
actionBar.setIcon(R.drawable.icon_b);
}
}
And save the state to recovery it later
protected void onSaveInstanceState(Bundle data) {
super.onSaveInstanceState(data);
data.putInt(icon_state);
}
I'm using the AppCompat/ActionBarCompat library and I need to create a custom ActionBar. I need to open the activity without an ActionBar and enable it only when I add the custom view. How can I do this?
PS: I need to define the activity to not use an ActionBar through the AndroidManifest.xml and my application minimum API level is 10.
.hide() the action bar and then .show() the action bar when your ready for it
import android.support.v7.app.ActionBar;
...
private ActionBar mActionbar;
...
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mActionbar = getSupportActionBar();
mActionbar.hide()
}
...
somewhere when something cool happens
mActionbar.show();