سؤال

I'm trying to make the actionbar menu (onCreateOptionsMenu) open ONLY on a long-click. How would I achieve this? At the moment I have it working for just a single short press/click using the following code:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    // TODO: Only onlongclick should the menu be revealed
    getMenuInflater().inflate(R.menu.my_menu_id, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.menu_home:
            open_home();
            return true;
        case R.id.menu_how_to:
            open_how_to();
            return true;
        case R.id.menu_rate:
            open_rate();
            return true;
        case R.id.menu_about:
            open_about();
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}

I'd like the menu to ONLY open for a long click (sort of like a hidden/trick feature). I've looked into onLongClickListener but can't get it to work. After the menu is opened it can behave normally (no more longclicks needed). Thanks for your help! Really appreciate it.

هل كانت مفيدة؟

المحلول 2

Okay so there's 2 answers to this depending on whether you would like icons in the menu:

  1. Create a context menu, however each row of the menu cannot have icons next to it. This is the simpler method.

  2. Create an alert dialog with a menu. This is much more complex but you can add icons and make the menu much more customisable.

I personally prefer method 2 because of the icons. I'll run through these methods below. First I'll just setup the action bar and button for the menu.

Sp first create an image button to open the menu somewhere. Also open up the custom action bar. This code is for BOTH methods:

// This goes somewhere in the activity's onCreate
ImageButton menu_home_button = (ImageButton) findViewById(R.id.action_bar_menu_home);
registerForContextMenu(menu_home_button); //ONLY USE THIS FOR METHOD1
menu_home_button.setLongClickable(true);
menu_home_button.setClickable(true);

// Custom action bar
actionBar = getActionBar();
actionBar.setCustomView(R.layout.my_custom_actionbar);
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setDisplayShowCustomEnabled(true);
actionBar.setDisplayUseLogoEnabled(false);
actionBar.setDisplayShowHomeEnabled(false);

My ImageButton was overlayed on top of the action bar on the right and looked like this in my_custom_actionbar.xml:

<ImageButton
    android:background="?android:selectableItemBackground"
    android:id="@+id/action_bar_menu_home"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/menu_icon"
    android:layout_alignParentTop="true"
    android:layout_alignParentRight="true"
    android:layout_alignParentEnd="true"
    android:layout_marginRight="4dp"
    android:clickable="true"
    android:focusable="true"
    android:longClickable="true" />

--------------------------------------

METHOD 1:

Add this to onCreate in WebViewActivity.java:

// Do the long press stuff
menu_home_button.setOnLongClickListener(new View.OnLongClickListener() {
    @Override
    public boolean onLongClick(View v) {
        Toast.makeText(getApplicationContext(), "Long Press works...", Toast.LENGTH_SHORT).show();
        // Do whatever you want on the longclick
    }
});

The following code goes where onCreateOptionsMenu and onOptionsItemSelected would go (at the end of the java class -- mine was called WebViewActivity.java).

@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
    super.onCreateContextMenu(menu, v, menuInfo);
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.my_menu_id, menu);
}

@Override
public boolean onContextItemSelected(MenuItem item) {
    AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
    switch (item.getItemId()) {
        case R.id.menu_home:
            open_home();
            return true;
        case R.id.menu_how_to:
            open_how_to();
            return true;
        case R.id.menu_rate:
            open_rate();
            return true;
        case R.id.menu_about:
            open_about();
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}

Then you create your menu in my_menu_id.xml. Including icons in the XML won't work so don't bother trying:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context="com.example.yourapp.WebViewActivity" >

    <item
        android:id="@+id/menu_home"
        android:title="@string/menu_home"
        android:showAsAction="never"/>

    <item
        android:id="@+id/menu_how_to"
        android:title="@string/menu_how_to"
        android:showAsAction="never"/>

    <item
        android:id="@+id/menu_rate"
        android:title="@string/menu_rate"
        android:showAsAction="never"/>

    <item
        android:id="@+id/menu_about"
        android:title="@string/menu_about"
        android:showAsAction="never"/>
</menu>

-----------------------------------------

METHOD 2:

Add this to onCreate in WebViewActivity.java:

menu_home_button.setOnLongClickListener(new View.OnLongClickListener() {
    @Override
    public boolean onLongClick(View v) {
        // Menu text
        final String[] items = {"Home", "How To", "Rate", "About"};

        // Menu Icons in Drawable
        final Drawable[] item_icons = {
            getResources().getDrawable(R.drawable.home_icon),
            getResources().getDrawable(R.drawable.how_to_icon),
            getResources().getDrawable(R.drawable.rate_icon),
            getResources().getDrawable(R.drawable.about_icon),
        };

        ListAdapter adapter = new ArrayAdapter<String>(getApplicationContext(), R.layout.custom_menu_dialog, items) {
            ViewHolder holder;

            class ViewHolder {
                ImageView icon;
                TextView title;
            }

            public View getView(int position, View convertView, ViewGroup parent) {
                final LayoutInflater inflater = (LayoutInflater)getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);

                if (convertView == null) {
                    convertView = inflater.inflate(R.layout.custom_menu_dialog, null);
                    holder = new ViewHolder();
                    holder.icon = (ImageView) convertView.findViewById(R.id.icon);
                    holder.title = (TextView) convertView.findViewById(R.id.title);
                    convertView.setTag(holder);
                } else {
                    // view already defined, retrieve view holder
                    holder = (ViewHolder) convertView.getTag();
                }

                holder.title.setText(items[position]);
                holder.icon.setImageDrawable(item_icons[position]);
                return convertView;
            }
        };

        Toast.makeText(getApplicationContext(), "Long Press works...", Toast.LENGTH_SHORT).show();

        AlertDialog.Builder menu_dialog = new AlertDialog.Builder(WebViewActivity.this); 

        menu_dialog.setTitle(getResources().getString("My Menu Name");
        menu_dialog.setAdapter(adapter, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int item) {
            //Toast.makeText(WebViewActivity.this, "You selected: " + items[item], Toast.LENGTH_LONG).show();
                switch (item) {
                    case 0:
                        open_home();
                        break;
                    case 1: // HOW TO
                        open_how_to();
                        break;
                    case 2:
                        open_rate();
                        break;
                    case 3: // ABOUT
                        open_about();
                        break;
                    default: // Do Case 0
                        open_home();
                        break;
                }
                dialog.dismiss();
           }
       });
       AlertDialog alert = menu_dialog.create();
       alert.show();
       return true;
    }
});

Finally here is the custom_menu_dialog.xml file with the base info for the text and icon of the menu:

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

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content">

    <ImageView
        android:id="@+id/icon"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:layout_gravity="center"
        android:paddingLeft="16dp"/>

    <TextView
        android:id="@+id/title"
        android:text=""
        android:layout_gravity="center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#fff6f6f6"
        android:textSize="18sp"
        android:paddingLeft="16dp"
        android:paddingTop="12dp"
        android:paddingBottom="12dp"/>

    </LinearLayout>

Hopw this helps at least one other person out. It certainly works for me.

نصائح أخرى

This is not possible. LongClick on the ActionBar buttons is not overridable.

It will always show a toast with the name of the button you long pressed. This is a help and discovery feature.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top