Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Toolbar don´t work with pre-lollipops devices using appcompat v7

I'm doing a simple code for a toolbar and menu drawer, using material appcompatv7. Everything works perfectly on the Nexus 5 with lollipop, but in a pre-lollipop (4.1 or 4.4) device crashes. The problem comes in defining the style. I put my code if anyone can tell me where the fault is.

This is my main activity:

import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.widget.Toolbar;
import android.content.res.Configuration;
import android.os.Bundle;
import android.view.MenuItem;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class Hello extends ActionBarActivity {

    private ActionBarDrawerToggle toggle;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_hello);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        toggle = new ActionBarDrawerToggle(
                this, 
                drawerLayout, 
                R.string.navigation_drawer_open, 
                R.string.navigation_drawer_close);
        toggle.setDrawerIndicatorEnabled(true);
        drawerLayout.setDrawerListener(toggle);

        ListView lv_navigation_drawer = (ListView) findViewById(R.id.lv_navigation_drawer);
        lv_navigation_drawer.setAdapter(new ArrayAdapter<String>(
                this, 
                android.R.layout.simple_list_item_1, 
                new String[] {"Screen 1", "Screen 2", "Screen 3"}));
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (toggle.onOptionsItemSelected(item))
            return true;
        return super.onOptionsItemSelected(item);
    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        toggle.syncState();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        toggle.onConfigurationChanged(newConfig);
    }
}

The main layout:

<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:orientation="vertical" >

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        theme="@style/ThemeOverlay.AppCompat.ActionBar"
        android:background="?attr/colorPrimary"
        android:minHeight="?attr/actionBarSize" />

    <android.support.v4.widget.DrawerLayout
        android:id="@+id/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <FrameLayout
            android:id="@+id/container"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

        <ListView
            android:id="@+id/lv_navigation_drawer"
            android:layout_width="240dp"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            android:background="@android:color/white" />
    </android.support.v4.widget.DrawerLayout>

</LinearLayout>

Style by simply extending Theme.AppCompat.Light.NoActionBar (I have no style defined for values-v21)

<resources>
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">

    </style>
</resources>

This all works correctly on devices lollipop and pre-lollipop. The problem comes when want to customize the colors of the toolbar and status bar

I make this change in values/styles

<resources>
    <style name="AppTheme" parent="Base.Theme.AppCompat"/>

    <style name="AppTheme.Base" parent="Theme.AppCompat">
        <item name="colorPrimary">#2ecc71</item>
        <item name="colorPrimaryDark">#27ae60</item>
        <item name="android:windowNoTitle">true</item>
        <item name="windowActionBar">false</item>
        <item name="drawerArrowStyle">@style/DrawerArrowStyle</item>
    </style>

    <style name="DrawerArrowStyle" parent="Widget.AppCompat.DrawerArrowToggle">
        <item name="spinBars">true</item>
        <item name="color">@android:color/white</item>
    </style>

    <color name="primary">#457C50</color>
    <color name="primaryDarker">#580C0C</color>
</resources>

and I add style to the values-v21

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <style name="AppTheme" parent="AppTheme.Base">
        <item name="android:windowContentTransitions">true</item>
        <item name="android:windowAllowEnterTransitionOverlap">true</item>
        <item name="android:windowAllowReturnTransitionOverlap">true</item>
        <item name="android:windowSharedElementEnterTransition">@android:transition/move</item>
        <item name="android:windowSharedElementExitTransition">@android:transition/move</item>
    </style>

</resources>

As said earlier, this works fine on the Nexus 5 but although the UI comes with correct colors, I can not see the ListView is inside the Menu Drawer (I do not understand why) ...but in the "pre-lollipop" devices crashes. The error throws me is this:

...java.lang.IllegalStateException: This Activity already has an action bar supplied by the window decor. Do not request Window.FEATURE_ACTION_BAR and set windowActionBar to false in your theme to use a Toolbar instead.

I searched a lot of information about this error and tried many options: the item windowActionBar within the style is "false" in the main activity have become "Toolbar" to "android.support.v7.widget.Toolbar toolbar" but without success ... I have also searched for examples already given, but not working for me I'm using Eclipse, the target of manifiest 21 and the minimum is 16, I have also updated sdk and adt ...

Can anyone help to work correctly on devices pre-lollipop?

like image 305
Sergio76 Avatar asked Nov 17 '14 11:11

Sergio76


1 Answers

Use Theme.AppCompat.Light.NoActionBar instead.

To call setSupportActionBar you can't have another action bar. That's why you get

This Activity already has an action bar supplied by the window decor

Make sure your theme doesn't have an actionbar to use toolbar.

like image 190
Pedro Oliveira Avatar answered Oct 29 '22 09:10

Pedro Oliveira