0

In order to add a contextual action bar to my application using the support action bar v7 library I implemented it like this :

My ActionBarActivity (support v7) :

    package com.supinfo.cubbyhole.mobileapp.activities;

import com.supinfo.cubbyhole.mobileapp.R;

import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.view.ActionMode;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class Homy extends ActionBarActivity {

    private ActionMode mActionMode;
    private ListView list;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);

        // I instantiate and fill my list with custom adapter ... All is fine
        list = (ListView) findViewById(R.id.home_list);

        String[] array = {"test", "test2", "test3"};
        list.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, android.R.id.text1, array));

        list.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
         @Override
         public boolean onItemLongClick(AdapterView<?> adapterView, View view, int position, long l) {

                 if (mActionMode != null) {
                     return false;
                 }
                 mActionMode = startSupportActionMode(mActionModeCallback);
                 view.setSelected(true);
                 return true;
         }
     });

    } 

    private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {

        @Override
        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            // Inflate a menu resource providing context menu items
            MenuInflater inflater = mode.getMenuInflater();
            inflater.inflate(R.menu.menu, menu);
            return true;
        }

        // Called each time the action mode is shown. Always called after onCreateActionMode, but
        // may be called multiple times if the mode is invalidated.
        @Override
        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
            return false; // Return false if nothing is done
        }

        // Called when the user selects a contextual menu item
        @Override
        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
            switch (item.getItemId()) {
                case R.id.action_settings:
                    mode.finish(); // Action picked, so close the CAB
                    return true;
                default:
                    return false;
            }
        }

        // Called when the user exits the action mode
        @Override
        public void onDestroyActionMode(ActionMode mode) {
            mActionMode = null;
        }

    };

}

My contextual_menu.xml :

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
        android:id="@+id/test"
        android:icon="@android:drawable/ic_menu_delete"
        android:showAsAction="ifRoom|withText"
        android:title="@string/test"
        android:titleCondensed="Delete">
    </item>

</menu>

And when I try to long click on an item I got this stack error :

06-01 18:11:09.888: E/AndroidRuntime(1206): FATAL EXCEPTION: main
    06-01 18:11:09.888: E/AndroidRuntime(1206): android.view.InflateException: Binary XML file line #17: Error inflating class <unknown>
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at android.view.LayoutInflater.createView(LayoutInflater.java:613)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at android.view.LayoutInflater.onCreateView(LayoutInflater.java:660)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:685)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at android.view.LayoutInflater.inflate(LayoutInflater.java:466)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at com.android.internal.widget.ActionBarContextView.initForMode(ActionBarContextView.java:206)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at com.android.internal.app.ActionBarImpl.startActionMode(ActionBarImpl.java:448)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at android.app.Activity.onWindowStartingActionMode(Activity.java:4881)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at android.support.v7.app.ActionBarActivityDelegateICS$WindowCallbackWrapper.onWindowStartingActionMode(ActionBarActivityDelegateICS.java:341)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at com.android.internal.policy.impl.PhoneWindow$DecorView.startActionMode(PhoneWindow.java:2256)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at android.app.Activity.startActionMode(Activity.java:4864)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at android.support.v7.app.ActionBarActivityDelegateICS.startSupportActionMode(ActionBarActivityDelegateICS.java:185)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at android.support.v7.app.ActionBarActivity.startSupportActionMode(ActionBarActivity.java:194)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at com.supinfo.cubbyhole.mobileapp.activities.Home$4.onItemLongClick(Home.java:414)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at android.widget.AbsListView.performLongPress(AbsListView.java:2815)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at android.widget.AbsListView$CheckForLongPress.run(AbsListView.java:2765)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at android.os.Handler.handleCallback(Handler.java:725)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at android.os.Handler.dispatchMessage(Handler.java:92)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at android.os.Looper.loop(Looper.java:137)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at android.app.ActivityThread.main(ActivityThread.java:5041)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at java.lang.reflect.Method.invokeNative(Native Method)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at java.lang.reflect.Method.invoke(Method.java:511)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at dalvik.system.NativeStart.main(Native Method)
    06-01 18:11:09.888: E/AndroidRuntime(1206): Caused by: java.lang.reflect.InvocationTargetException
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at java.lang.reflect.Constructor.constructNative(Native Method)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at java.lang.reflect.Constructor.newInstance(Constructor.java:417)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at android.view.LayoutInflater.createView(LayoutInflater.java:587)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     ... 25 more
    06-01 18:11:09.888: E/AndroidRuntime(1206): Caused by: java.lang.StackOverflowError
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at android.graphics.drawable.StateListDrawable$StateListState.indexOfStateSet(StateListDrawable.java:295)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at android.graphics.drawable.StateListDrawable$StateListState.access$000(StateListDrawable.java:274)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at android.graphics.drawable.StateListDrawable.onStateChange(StateListDrawable.java:100)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at android.graphics.drawable.StateListDrawable.<init>(StateListDrawable.java:327)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at android.graphics.drawable.StateListDrawable.<init>(StateListDrawable.java:75)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at android.graphics.drawable.Drawable.createFromXmlInner(Drawable.java:843)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at android.graphics.drawable.Drawable.createFromXml(Drawable.java:822)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at android.content.res.Resources.loadDrawable(Resources.java:1950)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at android.content.res.Resources.getDrawable(Resources.java:660)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at android.graphics.drawable.StateListDrawable.inflate(StateListDrawable.java:173)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at android.graphics.drawable.Drawable.createFromXmlInner(Drawable.java:885)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at android.graphics.drawable.Drawable.createFromXml(Drawable.java:822)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at android.content.res.Resources.loadDrawable(Resources.java:1950)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at android.content.res.Resources.getDrawable(Resources.java:660)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at android.graphics.drawable.StateListDrawable.inflate(StateListDrawable.java:173)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at android.graphics.drawable.Drawable.createFromXmlInner(Drawable.java:885)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at android.graphics.drawable.Drawable.createFromXml(Drawable.java:822)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at android.content.res.Resources.loadDrawable(Resources.java:1950)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at android.content.res.Resources.getDrawable(Resources.java:660)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at android.graphics.drawable.StateListDrawable.inflate(StateListDrawable.java:173)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at android.graphics.drawable.Drawable.createFromXmlInner(Drawable.java:885)
    06-01 18:11:09.888: E/AndroidRuntime(1206):     at android.graphics.drawable

I don't understand why the contextual menu doesn't display...

-- EDIT --

Issue was due to the Override of the close icon in my auto generated theme... I just had to comment this line :

<item name="android:actionModeCloseButtonStyle">@style/ActionButton.CloseMode.Cubbyhole</item>
Charles
  • 50,943
  • 13
  • 104
  • 142
eento
  • 761
  • 4
  • 20
  • 53
  • You've never assigned the list view. – Ivan Skoric Jun 01 '14 at 18:29
  • Man, not all code is written there, just the main for my issue.. – eento Jun 01 '14 at 18:32
  • The problem is probably within your adapter because when I try your code with a simple ArrayAdapter, it has no problems. – Ivan Skoric Jun 01 '14 at 18:40
  • Impossible.. I restarted eclipse and my computer and now I have some import issues on extarnal projects library.. eclipse sucks and Android Studio is still in beta... I think it's an Eclipse issue – eento Jun 01 '14 at 18:49
  • I tried with ArrayAdapter and got same error! (restarting eclipse removed the imports bug) – eento Jun 01 '14 at 18:55

1 Answers1

0

The exception is an stack overflow (how appropriate) while expanding the "close" icon in the CAB. Probably because of a state-list drawable that references itself.

The relevant code in ActionBarContextView.java is:

LayoutInflater inflater = LayoutInflater.from(mContext);
mClose = inflater.inflate(R.layout.action_mode_close_item, this, false);

The problem might be related to an incorrect definition of the actionModeCloseDrawable drawable, or the actionModeCloseButtonStyle style.

Is either one of them customized in your theme, possibly with an recursive state-list drawable?

In case everything is correctly defined, I would suggest cleaning and rebuilding the project (the resource ids may be incorrect).

matiash
  • 54,791
  • 16
  • 125
  • 154
  • Yes my theme is auto generated using Android Action Bar Style Generator and this line set the value for the closedrawable : @drawable/abc_ic_cab_done_holo_dark – eento Jun 01 '14 at 19:20
  • @eento Is abc_ic_cab_done_holo_dark a png file or an xml file? – matiash Jun 01 '14 at 19:22
  • It's a png resource, I tried to comment lines with this set and the problem is still there – eento Jun 01 '14 at 19:24
  • @eento ok, it may be the other style (edited my answer) please check `actionModeCloseButtonStyle` too (and the drawables it references). – matiash Jun 01 '14 at 19:25
  • actionModeCloseButtonStyle is set by sub themes, and the final theme just set a drawable.. What do you expect I can do ?? – eento Jun 01 '14 at 19:29
  • @eento well, the "reasonable" causes seem to be out, sorry :/ have you both refreshed and cleaned the project in eclipse? – matiash Jun 01 '14 at 19:31
  • But do you know how can I set a different Drawable for actionModeCloseDrawable ? – eento Jun 01 '14 at 19:37
  • Just find the file that `actionModeCloseDrawable` points to and change it for the one you want. – matiash Jun 01 '14 at 19:50
  • ok, but this stack overflow is very strange.. thx for help, I think i will not use this CAB because it doesnt take all the space available in my action bar to display Menus... – eento Jun 01 '14 at 19:56