I have an activity with a navigation drawer that flicks between fragments. Nothing special.
However what I want is the action bar to appear at the top of the activity. The issue is that I keep getting a nullpointerexception
for the Actionbar
.
I've tried answers from the following pages:
getActionBar returns null
getActionBar() returns Null (AppCompat-v7 21)
None of these have worked so I thought I'd submit my own question with my own code.
package com.jampez.smalltalk;
import com.jampez.smalltalk.fragments.HomeFragment;
import com.jampez.smalltalk.fragments.MessageFragment;
import com.jampez.smalltalk.fragments.PreferencesFragment;
import com.jampez.smalltalk.fragments.SettingsFragment;
import com.jampez.smalltalk.helper.SessionManager;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarDrawerToggle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public class MainActivity extends FragmentActivity {
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
private ActionBarDrawerToggle mDrawerToggle;
private String[] items;
int selectedPosition;
private SessionManager session;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getActionBar().setTitle("");
// Session manager
session = new SessionManager(getApplicationContext());
if (!session.isLoggedIn()) {
// User is already logged in. Take him to main activity
Intent intent = new Intent(MainActivity.this, LoginActivity.class);
startActivity(intent);
finish();
}
items = getResources().getStringArray(R.array.menus);
// Getting reference to the DrawerLayout
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.drawer_list);
/* Creating an ArrayAdapter to add items to mDrawerList */
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.drawer_list_item, items);
mDrawerList.setAdapter(adapter);
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
R.drawable.ic_drawer,
R.string.drawer_open) {
/* Called when drawer is closed */
public void onDrawerClosed(View view) {
//Put your code here
}
/* Called when a drawer is opened */
public void onDrawerOpened(View drawerView) {
//Put your code here
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
// Enabling Home button
getActionBar().setHomeButtonEnabled(true);
getActionBar().setDisplayHomeAsUpEnabled(true);
// Setting item click listener for the listview mDrawerList
mDrawerList.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
selectedPosition = position;
/* Replace fragment content */
displayView(position);
/* Closing the drawer */
mDrawerLayout.closeDrawer(mDrawerList);
}
});
/* Setting default fragment */
selectedPosition = 0;
displayView(0);
}
private void displayView(int position) {
// update the main content by replacing fragments
android.app.Fragment fragment = null;
Log.i("position", position+"");
switch (position) {
case 0:
fragment = new HomeFragment();
break;
case 1:
fragment = new MessageFragment();
break;
case 2:
fragment = new PreferencesFragment();
break;
case 3:
fragment = new SettingsFragment();
break;
case 4:
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, "This is my text to send.");
sendIntent.setType("text/plain");
startActivity(sendIntent);
break;
case 5:
String url = "http://www.example.com";
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
break;
default:
break;
}
if (fragment != null) {
android.app.FragmentManager fragmentManager = getFragmentManager();
android.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.content_frame, fragment);
fragmentTransaction.commit();
// update selected item and title, then close the drawer
mDrawerList.setItemChecked(position, true);
mDrawerList.setSelection(position);
//setTitle(navMenuTitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
} else {
// error in creating fragment
Log.e("MainActivity", "Error in creating fragment");
}
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
mDrawerToggle.syncState();
}
}
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:theme="@android:style/Theme.WithActionBar" >
<!-- The main content view -->
<FrameLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- The navigation drawer list-->
<ListView
android:id="@+id/drawer_list"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#111"
android:choiceMode="singleChoice"
android:divider="@android:color/transparent"
android:dividerHeight="0dp" />
</android.support.v4.widget.DrawerLayout>
package com.jampez.smalltalk.fragments;
import com.jampez.smalltalk.R;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class HomeFragment extends Fragment {
public HomeFragment(){}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_home, container, false);
//getActivity().getActionBar().setTitle(R.string.home);
return rootView;
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#e5e5e5"
android:orientation="vertical" >
<TextView
android:id="@+id/home_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_gravity="start|center_vertical"
android:text="@string/home"/>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.jampez.smalltalk"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="23" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- To auto-complete the email text field in the login form with the user's emails -->
<uses-permission android:name="android.permission.READ_PROFILE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<application
android:name=".app.AppController"
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="@string/facebook_app_id" />
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".LoginActivity"
android:label="@string/app_name"
android:windowSoftInputMode="adjustResize|stateHidden" >
</activity>
<activity
android:name="com.facebook.FacebookActivity"
android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
android:label="@string/app_name"
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
</application>
<resources>
<!--
Base application theme, dependent on API level. This theme is replaced
by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
-->
<style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar">
<!--
Theme customizations available in newer API levels can go in
res/values-vXX/styles.xml, while customizations related to
backward-compatibility can go here.
-->
</style>
<!-- Application theme. -->
<style name="AppTheme" parent="AppBaseTheme">
<!-- All customizations that are NOT specific to a particular API-level can go here. -->
<item name="android:actionBarStyle">@style/MyActionBar</item>
<item name="android:actionOverflowButtonStyle">@style/MyActionButtonOverflow</item>
<item name="drawerArrowStyle">@style/DrawerArrowStyle</item>
</style>
<style name="DrawerArrowStyle" parent="Widget.AppCompat.DrawerArrowToggle">
<item name="spinBars">true</item>
<item name="color">@color/white</item>
</style>
<style name="MyActionButtonOverflow" parent="android:style/Widget.Holo.ActionButton.Overflow">
<item name="android:color">@color/white</item>
</style>
<style name="MyActionBar" parent="@android:style/Widget.Holo.Light.ActionBar">
<item name="android:background">#25a0da</item>
</style>
11-08 19:17:38.618: E/AndroidRuntime(6347): FATAL EXCEPTION: main
11-08 19:17:38.618: E/AndroidRuntime(6347): Process: com.jampez.smalltalk, PID: 6347
11-08 19:17:38.618: E/AndroidRuntime(6347): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.jampez.smalltalk/com.jampez.smalltalk.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.app.ActionBar.setTitle(java.lang.CharSequence)' on a null object reference
11-08 19:17:38.618: E/AndroidRuntime(6347): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2658)
11-08 19:17:38.618: E/AndroidRuntime(6347): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2723)
11-08 19:17:38.618: E/AndroidRuntime(6347): at android.app.ActivityThread.access$900(ActivityThread.java:172)
11-08 19:17:38.618: E/AndroidRuntime(6347): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1422)
11-08 19:17:38.618: E/AndroidRuntime(6347): at android.os.Handler.dispatchMessage(Handler.java:102)
11-08 19:17:38.618: E/AndroidRuntime(6347): at android.os.Looper.loop(Looper.java:145)
11-08 19:17:38.618: E/AndroidRuntime(6347): at android.app.ActivityThread.main(ActivityThread.java:5832)
11-08 19:17:38.618: E/AndroidRuntime(6347): at java.lang.reflect.Method.invoke(Native Method)
11-08 19:17:38.618: E/AndroidRuntime(6347): at java.lang.reflect.Method.invoke(Method.java:372)
11-08 19:17:38.618: E/AndroidRuntime(6347): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
11-08 19:17:38.618: E/AndroidRuntime(6347): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
11-08 19:17:38.618: E/AndroidRuntime(6347): Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.app.ActionBar.setTitle(java.lang.CharSequence)' on a null object reference
11-08 19:17:38.618: E/AndroidRuntime(6347): at com.jampez.smalltalk.MainActivity.onCreate(MainActivity.java:37)
11-08 19:17:38.618: E/AndroidRuntime(6347): at android.app.Activity.performCreate(Activity.java:6221)
11-08 19:17:38.618: E/AndroidRuntime(6347): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
11-08 19:17:38.618: E/AndroidRuntime(6347): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2611)
11-08 19:17:38.618: E/AndroidRuntime(6347): ... 10 more
*First of all include this dependency in your gradle file
compile 'com.android.support:appcompat-v7:22.2.0'
*You should extend your activity to AppCompactActivity and start using toolbar instead of ActionBar.
*This is how you use Toolbar in your MainActivity
public class MainActivity extends AppCompatActivity {
private Toolbar mToolbar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mToolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayShowHomeEnabled(true);
}
}
*this is how to add toolbar in your activity_main.xml
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"
android:background="?attr/colorPrimary"
local:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
local:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
*your theme should look something like this styles.xml
<style name="MyMaterialTheme" parent="MyMaterialTheme.Base">
</style>
<style name="MyMaterialTheme.Base" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
make sure you add this style name in your manifest for your application.
*It will be better if you use v4.app.Fragment rather than using Fragment.
*this is how you should set title from your Fragment class
((AppCompatActivity)getActivity()).getSupportActionBar().setTitle(R.string.home);
Refer this clear Tutorial which will surely help you setting up material Navigation drawer.
If you want to quickly start off without much pain then you can try integrating this third party library.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With