I have second problem today with android developing.
I get error:
Cannot make a static reference to the non-static method getActionBar() from the type NavigationDrawerFragment
With code:
ActionBar actionBar = NavigationDrawerFragment.getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
and NavigationDrawerFragment.java:
public ActionBar getActionBar() {
return getActivity().getActionBar();
}
Thank you :)
Did your IDE set this up for you? If so, there should be a NavigationDrawerFragment Object (maybe called "mNavigationDrawerFragment")
Then use
mNavigationDrawerFragment.getActionBar();
But you should probably learn the Java basics first.
For that to work you would have to make the method like this
public static ActionBar getActionBar(){
return getActivity.getActionBar();
}
EDIT:
Create a field at the top of your fragment class
private static ActionBar mActionBar;
Then in the onCreate method add this
mActionBar = getActivity.getActionBar();
Now you can create your static method and return the actionbar
public static ActionBar getActionBar(){
return mActionBar;
}
Related
On my application I have only one activity (that extends ActionBarActivity ) and various Fragments (that extends Fragment).
When the user click on a menu option, the application change the Fragment.
At this moment I want to change de title and the background color of the ActionBar.
When I try ActionBar actionBar = getActivity().getActionBar(); I got a null exception.
I'm using support library, and on the Activity I'm using android.support.v7.app.ActionBar actionBar = getSupportActionBar(); successfully.
On the Fragment:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.material_cadastro, container, false);
viewHolder = new MaterialViewHolder(view);
ActionBar actionBar = getActivity().getActionBar();
actionBar.setTitle(R.string.inserir_material);
return view;
}
Debuging I got that the Activity is returning OK, but the ActionBar is null:
getActivity() = {br.com.americocarelli.vendasfacil.ui.MenuPrincipal#3b56766f}
getActivity().getActionBar() = null
Override your onAttach(Activity), then cast your Activity to ActionBarActivity, the you can get an ActionBar.
Like:
#Override
public void onAttach(Activity activity) {
// TODO Auto-generated method stub
super.onAttach(activity);
ActionBar actionBar=((ActionBarActivity)activity).getSupportActionBar();
}
Since you use the support library (ActionBarActivity), then use ((ActionBarActivity)getActivity()).getSupportActionBar(); to get access to the support action bar.
You are probably building it with build tools >=21, that versions causes activity.getActionBar() returns null, you should use getSupportActionBar() instead.
EDIT: if you get NPE at exactly this line: getActivity(). ... then you are probably referencing it before or after fragment is attached to activity. Could you please paste the context (place, in what function) you are using it?
When I call getActionBar throws me: "The return type is incompatible with Activity.getActionBar()"
I know it's a dumb question but I can´t find the solution.
public class ClaseContacto extends Activity{...
...
private void showGlobalContextActionBar() {
ActionBar actionBar = getActionBar();
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setHomeButtonEnabled(true);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
actionBar.setTitle(R.string.app_name);
}
private ActionBar getActionBar() {
return ( (ActionBarActivity) getActivity() ).getSupportActionBar();
}
...
//More code here
getSupportActionBar()? Are you using the android.support.v7 library?
If so, then extend ActionBarActivity instead of Activity. Then remove the getActionBar() method and Call getSupportActionBar() directly.
You don't need to override getActionBar();
In Activity, you just need to call
getActionBar()
and it will return ActionBar object for you
You can check this tutorial
You need to extend ActionBarActivity from support-v7-appcompat library.
And then you should use getSupportActionBar()
e.g.
public class SampleActivity extends ActionBarActivity {
}
and inside onCreate() function use below code to get action bar :-
ActionBar actionBar = getSupportActionBar();
Make sure you have imported android-support-v7-appcompat library in your IDE and added that as library project in your application project from build path -> android.
I am studying on the ActionBar and saw this abstract method
public abstract Tab newTab();
However the implementation of newTab is only seen in ActionBarImpl.java.
From android http://developer.android.com/reference/android/support/v4/view/ViewPager.html
It is showed that
final ActionBar bar = getActionBar();
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
bar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);
mTabsAdapter = new TabsAdapter(this, mViewPager);
mTabsAdapter.addTab(bar.newTab().setText("Simple"), CountingFragment.class, null);
So, where is the bar.newTab() actually instantiated?
I saw a related post What class should I extend, AcionBar or ActionBarImpl? but it doesn't seem to answer my question directly.
The ActionBar class is an abstract class, like you already found out. It's actually implemented in the ActionBarImp class. Everything related to the ActionBar will be instantiated inside the Activity class. getActionBar() will return this implementation of the ActionBar:
/**
* Retrieve a reference to this activity's ActionBar.
*
* #return The Activity's ActionBar, or null if it does not have one.
*/
public ActionBar getActionBar() {
initActionBar();
return mActionBar;
}
/**
* Creates a new ActionBar, locates the inflated ActionBarView,
* initializes the ActionBar with the view, and sets mActionBar.
*/
private void initActionBar() {
[...]
mActionBar = new ActionBarImpl(this);
[...]
}
Source.
I'm starting a new project that uses the AppCompat/ActionBarCompat in v7 support library. I'm trying to figure out how to use the getSupportActionBar from within a fragment. My activity that hosts the fragment extends ActionBarActivity, but I don't see a similar support class for Fragments.
From within my fragment
public class CrimeFragment extends Fragment {
//...
getActivity().getSupportActionBar().setSubtitle(R.string.subtitle); // getSupportActionBar is not defined in the v4 version of Fragment
//...
}
The google page for using it (http://android-developers.blogspot.in/2013/08/actionbarcompat-and-io-2013-app-source.html) says there should be no changes for the v4 fragment. Do I need to cast all my getActivity() calls to an ActionBarActivity? That seems like poor design.
After Fragment.onActivityCreated(...) you'll have a valid activity accessible through getActivity().
You'll need to cast it to an ActionBarActivity then make the call to getSupportActionBar().
((AppCompatActivity)getActivity()).getSupportActionBar().setSubtitle(R.string.subtitle);
You do need the cast. It's not poor design, it's backwards compatibility.
While this question has an accepted answer already, I must point out that it isn't totally correct: calling getSupportActionBar() from Fragment.onAttach() will cause a NullPointerException when the activity is rotated.
Short answer:
Use ((ActionBarActivity)getActivity()).getSupportActionBar() in onActivityCreated() (or any point afterwards in its lifecycle) instead of onAttach().
Long answer:
The reason is that if an ActionBarActivity is recreated after a rotation, it will restore all Fragments before actually creating the ActionBar object.
Source code for ActionBarActivity in the support-v7 library:
#Override
protected void onCreate(Bundle savedInstanceState) {
mImpl = ActionBarActivityDelegate.createDelegate(this);
super.onCreate(savedInstanceState);
mImpl.onCreate(savedInstanceState);
}
ActionBarActivityDelegate.createDelegate() creates the mImpl object depending on the Android version.
super.onCreate() is FragmentActivity.onCreate(), which restores any previous fragments after a rotation (FragmentManagerImpl.dispatchCreate(), &c).
mImpl.onCreate(savedInstanceState) is ActionBarActivityDelegate.onCreate(), which reads the mHasActionBar variable from the window style.
Before mHasActionBar is true, getSupportActionBar() will always return null.
Source for ActionBarActivityDelegate.getSupportActionBar():
final ActionBar getSupportActionBar() {
// The Action Bar should be lazily created as mHasActionBar or mOverlayActionBar
// could change after onCreate
if (mHasActionBar || mOverlayActionBar) {
if (mActionBar == null) {
... creates the action bar ...
}
} else {
// If we're not set to have a Action Bar, null it just in case it's been set
mActionBar = null;
}
return mActionBar;
}
If someone uses com.android.support:appcompat-v7: and AppCompatActivity as activity then this will work
((AppCompatActivity)getActivity()).getSupportActionBar().setSubtitle(R.string.subtitle);
For those using kotlin,
(activity as AppCompatActivity).supportActionBar.setSubtitle(R.string.subtitle)
As an updated answer for Pierre-Antoine LaFayette's answer
ActionBarActivity is deprecated; use AppCompatActivity instead
((AppCompatActivity)getActivity()).getSupportActionBar();
in your fragment.xml add Toolbar Tag from support library
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light" />
Now how we can control it from MyFragment class? let's see
inside onCreateView function add the following
mToolbar = (Toolbar) view.findViewById(R.id.toolbar);
((AppCompatActivity)getActivity()).setSupportActionBar(mToolbar);
//add this line if you want to provide Up Navigation but don't forget to to
//identify parent activity in manifest file
((AppCompatActivity)getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(true);
and if you want to add items to the toolbar within MyFragment
you must add this line inside onCreateView function
setHasOptionsMenu(true);
this line is important, if you forget it, android will not populate your menu Items.
assume we identify them in menu/fragment_menu.xml
after that override the following functions
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.fragment_menu, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
switch (id) {
case R.id.action_1:
// do stuff
return true;
case R.id.action_2:
// do more stuff
return true;
}
return false;
}
hope this helps
As an addendum to GzDev's answer, if you already have the string, you can use kotlin's auto-setter:
(activity as AppCompatActivity).supportActionBar?.subtitle = my_string
And you can turn it off by simply using an empty string.
Note that this works for both the title and the subtitle.
In my Activity I want to show arrow to left of ActionBar icon, so in Activity I write:
ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
It works fine, but I decide move ActionBar initialization to another class and use it for all activities in my application, new class for this:
public class Utils {
public static void initActionBar(Activity activity, boolean homeIconNeeded) {
ActionBar actionBar = activity.getActionBar();
actionBar.setIcon(R.drawable.logo);
actionBar.setHomeButtonEnabled(homeIconNeeded);
actionBar.setBackgroundDrawable(activity.getResources().getDrawable(R.drawable.action_bar_background));
}
public static void initActionBar(ActionBar actionBar, boolean homeIconNeeded) {
actionBar.setIcon(R.drawable.logo);
actionBar.setHomeButtonEnabled(true);
actionBar.setBackgroundDrawable(SmartVmsApplication.getContext().getResources().getDrawable(R.drawable.action_bar_background));
}
}
Then in my activity I insert in onCreate() callback initActionBar(this, true), however arrow doesn’t appear, no matters I passed Activity or ActionBar as parameter and it is an issue.
You forgot to call the setDisplayHomeAsUpEnabled() method.