Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android ActionBar always null

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.

MainActivity.java

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();
}
}

activity_main.xml

<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>

HomeFragment.java

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;
}
}

fragment_home.xml

<?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>

Android Manifest

<?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>

styles.xml

<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>

Logcat Output

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
like image 984
jampez77 Avatar asked Nov 08 '15 19:11

jampez77


1 Answers

*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.

like image 105
Veer3383 Avatar answered Nov 16 '22 02:11

Veer3383