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.
Related
I have created a custom action bar which works fine on my starting activity but gives an error when I call the method from other activities in the same application.
This is the code I am using to set the ActionBar in my first activity
firstAct.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
actionBarSetup(this);
}
void actionBarSetup(Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
ActionBar ab = getActionBar();
ab.setDisplayShowCustomEnabled(true);
ab.setDisplayShowTitleEnabled(false);
ab.setBackgroundDrawable(new ColorDrawable(Color.WHITE));
LayoutInflater inflator = LayoutInflater.from(context);
View v = inflator.inflate(R.layout.actionbar_layout, null);
//assign the view to the actionbar
ab.setCustomView(v);
}
}
**secondAct.java**
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_pg);
(new firstAct()).actionBarSetup(secondAct.this);
}
I get NullPointerException when i call actionBarSetup() from secondAct.java
on line ActionBar ab = getActionBar().
Is it that getActionBar() cannot be called directly from other activities besides the main activity ie. firstAct.
How to call it from other Activities then?
You don't create new activities by calling their constructor. You have the system create and open them for you. I'm talking about the line
(new firstAct()).actionBarSetup(secondAct.this)
What are you trying to do here?
You probably want to make the actionBarSetup method accessible for all classes and not just instances of firstAct. Then declare it like this (maybe move it to a utility class?):
public static void actionBarSetup(Activity activity) {
ActionBar ab = activity.getActionBar(); // you need activity, not just context
// ...
}
Then call it from other classes like this:
firstAct.actionBarSetup(this);
Making a method static detaches it from an instances resources. You were taking in second activity (context parameter) but asking for an action bar from instance of the first activity (essentially this.getActionBar()) which was not setup by system (because you misused constructor).
Note: Please use PascalCase notation for class names (capital first letter).
EDIT
Warning: Your action bar may have different styling from your activity (e.g. black toolbar and white activity). In that case using the activity's inflater to inflate contents of the action bar will produce undesired results (inverted text color mainly). The following line is safer. But it's available no sooner than API 14.
LayoutInflater inflator = LayoutInflater.from(ab.getThemedContext());
You need create BaseActivity like
public class BaseActivity extends Activity {
public void actionBarSetup(Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
ActionBar ab = getActionBar();
ab.setDisplayShowCustomEnabled(true);
ab.setDisplayShowTitleEnabled(false);
ab.setBackgroundDrawable(new ColorDrawable(Color.WHITE));
LayoutInflater inflator = LayoutInflater.from(context);
View v = inflator.inflate(R.layout.actionbar_layout, null);
//assign the view to the actionbar
ab.setCustomView(v);
}
}
then you need firstAct and secondAct extend BaseActivity then in onCreate method call actionBarSetup()
This may help
private void showCustoNavBar(){
getSupportActionBar().setBackgroundDrawable(getResources().getDrawable(R.drawable.new_gradient));
getSupportActionBar().setDisplayShowCustomEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(false);
View customNav = LayoutInflater.from(this).inflate(R.layout.actioncustomview, null);
getSupportActionBar().setCustomView(customNav);
}
I have developed an Android application which has 4 TabHost's which are in fragments.
I Know how to customize the ActionBar in MainActivity.
But problem is how can I customize my ActionBar according to the 4 different TabHost's in different Fragments?
Here is my tabHost code -
public class MainActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
/** Creating ANDROID Tab */
Tab tab = actionBar.newTab()
//.setText("Android")
.setTabListener(new CustomTabListener<PlayFragment01>(this, "play",
PlayFragment01.class))
.setIcon(R.drawable.playtabhosticon);
actionBar.addTab(tab);
/** Creating APPLE Tab */
Tab tab1 = actionBar.newTab()
//.setText("Apple")
.setTabListener(new CustomTabListener<VenueFragment01>(this, "venu",
VenueFragment01.class))
.setIcon(R.drawable.venutabhosticon);
actionBar.addTab(tab1);
/** Creating APPLE Tab */
Tab tab3 = actionBar.newTab()
//.setText("Apple")
.setTabListener(new CustomTabListener<SocialFragment01>(this, "social", SocialFragment01.class))
.setIcon(R.drawable.socialtabhosticon);
actionBar.addTab(tab3);
/** Creating APPLE Tab */
Tab tab4 = actionBar.newTab()
//.setText("Apple")
.setTabListener(new CustomTabListener<ActivityFragment01>(this, "activity",
ActivityFragment01.class))
.setIcon(R.drawable.actionbartabhosticon);
actionBar.addTab(tab4);
}
}
Here is my first fragment code -
package in.wptrafficanalyzer.actionbarnavtab;
/** This is a listfragment class */
public class PlayFragment01 extends Fragment {
/** An array of items to display in ArrayList */
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
/** Creating array adapter to set data in listview */
View rootView = inflater.inflate(R.layout.fragment_play, container, false);
//new DownloadJSON().execute();
ActionBar actionBar = getActivity().getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
getActivity().getActionBar().setBackgroundDrawable(
new ColorDrawable(Color.parseColor("#0077d1")));
ActionBar mActionBar = getActivity().getActionBar();
getActivity().getActionBar().setIcon(
new ColorDrawable(getResources().getColor(android.R.color.transparent)));
mActionBar.setDisplayShowHomeEnabled(true);
mActionBar.setDisplayShowTitleEnabled(false);
LayoutInflater mInflater = LayoutInflater.from(this);
View mCustomView = mInflater.inflate(R.layout.custom_actionbar2, null);
mActionBar.setCustomView(mCustomView);
mActionBar.setDisplayShowCustomEnabled(true);
return rootView;
}
}
The question your asking is not very clear but you can get the ActionBar instance from within a Fragment using getActivity().getActionBar().
ActionBar.setNavigationMode() and TabHost is now deprecated.
The new ToolBar introduced in API-21 is more powerfull.
But since you asked for a solution, here is a simple one from Google SlidingTabLayout:
This is like a PagerTabStrip that you can easily customize and works like great.
It works with ViewPager and Fragments of course.
In my point of view ,you should read this ,so that you can get the basic idea for creating a fragment.
http://developer.android.com/guide/components/fragments.html
Try this sample code..this sample code includes 3 tab ,first try to understand this code ,then you can make your own app with 4 tabs
http://www.androidhive.info/2013/10/android-tab-layout-with-swipeable-views-1/
Also try to modify your question ,It is unclear and also it will be good that you post your errors
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;
}
I want to replace a SherlockListFragment with other SherlockListFragment but I don´t know how to accomplish this
I use this code to create the fragment tabs:
public class MyTabsViewPager extends SherlockFragmentActivity
{
....
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
mViewPager = new ViewPager(this);
mViewPager.setId(R.id.pager);
setContentView(mViewPager);
bar = getSupportActionBar();
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
bar.setTitle("TAB");
mTabsAdapter = new TabsAdapter(this, mViewPager);
mTabsAdapter.addTab(
bar.newTab().setIcon(R.drawable.icon),
Fragment1.class, null);
mTabsAdapter.addTab(
bar.newTab().setIcon(R.drawable.icon2),
FragmentList.class, null);
}
}
What i need is to replace in the same tab the FragmentList.class with other fragment Class
Thanks in advance!
Well actually you can just replace the name of the class there. Is that what you are trying achieve?
Don't know if this is too late but you can replace fragments dynamically. There's only one catch, you cannot add a fragment to the layout statically in this case. For more details - refer the solution to this StackOverflow post
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.