Add Context Menu Icon in android

2020-02-08 15:42发布

I have a Listview with a ContextMenu, but when I setIcon for ContextMenu look like it doesn't work

public void onCreateContextMenu(ContextMenu menu , View v, 
        ContextMenuInfo menuInfo){

    super.onCreateContextMenu(menu, v, menuInfo);
    menu.add(0, DELETE_ID, 0, R.string.context_menu_favorite)
        .setIcon(android.R.drawable.btn_star);      
}

6条回答
太酷不给撩
2楼-- · 2020-02-08 16:05

Context menus do not support icons.

Note: Context menu items do not support icons or shortcut keys.

查看更多
干净又极端
3楼-- · 2020-02-08 16:10

While the Android API does not allow for Icons in Context menus you can see many places where Android is using them. Long pressing your home screen is one good example.

I took the time to dig through the Launcher and AnyCut source and found that Google is using their own custom class that extends a BaseAdapter along with their own custom layout.

I was able to copy their class and layout almost exactly and use it in my own app to accomplish. The class if you want to search for it is called AddAdapter.java.

Enjoy!

查看更多
Explosion°爆炸
4楼-- · 2020-02-08 16:11

This library allows you to have a context menu (implemented as AlertDialog) with icons using a standard XML menu.

https://code.google.com/p/android-icon-context-menu/

查看更多
来,给爷笑一个
5楼-- · 2020-02-08 16:15

check this one....

@Override
    public void onCreateContextMenu(ContextMenu menu, View v,
   ContextMenuInfo menuInfo) {
  super.onCreateContextMenu(menu, v, menuInfo);
  menu.setHeaderTitle("Settings");
  menu.setHeaderIcon(R.drawable.ic_settings);
  menu.add(0, v.getId(), 0, "Action 1");
  menu.add(0, v.getId(), 0, "Action 2");
  menu.add(0, v.getId(), 0, "Action 3");
 }

 @Override
 public boolean onContextItemSelected(MenuItem item) {
  if (item.getTitle() == "Action 1") {
   Toast.makeText(this, "Action 1 invoked", Toast.LENGTH_SHORT).show();
  } else if (item.getTitle() == "Action 2") {
   Toast.makeText(this, "Action 2 invoked", Toast.LENGTH_SHORT).show();
  } else if (item.getTitle() == "Action 3") {
   Toast.makeText(this, "Action 3 invoked", Toast.LENGTH_SHORT).show();
  } else {
   return false;
  }
  return true;
 }
查看更多
Juvenile、少年°
6楼-- · 2020-02-08 16:16

While the API doesn't support icons in Context Menu, but we can always fake it by inflating a Dialog with our own view that looks like context menu.

Copy-pasting the following files exactly will do the job:

MainActivity.java

public class MainActivity extends Activity {

List<ContextMenuItem> contextMenuItems;
Dialog customDialog;

LayoutInflater inflater;
View child;
ListView listView;
ContextMenuAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    inflater = (LayoutInflater) this
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    child = inflater.inflate(R.layout.listview_context_menu, null);
    listView = (ListView) child.findViewById(R.id.listView_context_menu);

    contextMenuItems = new ArrayList<ContextMenuItem>();
    contextMenuItems.add(new ContextMenuItem(getResources().getDrawable(
            R.drawable.ic_launcher), "Facebook"));
    contextMenuItems.add(new ContextMenuItem(getResources().getDrawable(
            R.drawable.ic_launcher), "Scanner"));

    adapter = new ContextMenuAdapter(this,
            contextMenuItems);
    listView.setAdapter(adapter);

            listView.setOnItemClickListener(new OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View v,
                int position, long id) {
            customDialog.dismiss();
            if (position == 0)
                Toast.makeText(MainActivity.this, "00", Toast.LENGTH_SHORT)
                        .show();

            if (position == 1)
                Toast.makeText(MainActivity.this, "11", Toast.LENGTH_SHORT)
                        .show();

        }
    });

    customDialog = new Dialog(this);
    customDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
    customDialog.setContentView(child);
    customDialog.show();
    }

}

ContextMenuItem.java

public class ContextMenuItem {

Drawable drawable;
String text;

public ContextMenuItem(Drawable drawable, String text) {
    super();
    this.drawable = drawable;
    this.text = text;
}

public Drawable getDrawable() {
    return drawable;
}

public void setDrawable(Drawable drawable) {
    this.drawable = drawable;
}

public String getText() {
    return text;
}

public void setText(String text) {
    this.text = text;
}

}

ContextMenuAdapter.java

public class ContextMenuAdapter extends BaseAdapter {
Context context;
List<ContextMenuItem> listContextMenuItems;
LayoutInflater inflater;

public ContextMenuAdapter(Context context,
        List<ContextMenuItem> listContextMenuItems) {
    super();
    this.context = context;
    this.listContextMenuItems = listContextMenuItems;
}

static class ViewHolder {
    protected ImageView imageView;
    protected TextView textView;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder viewHolder;
    if (convertView == null) {
        inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        viewHolder = new ViewHolder();
        convertView = inflater.inflate(R.layout.context_menu_item, parent,
                false);
        viewHolder.imageView = (ImageView) convertView
                .findViewById(R.id.imageView_menu);
        viewHolder.textView = (TextView) convertView
                .findViewById(R.id.textView_menu);
        convertView.setTag(viewHolder);
    } else {
        viewHolder = (ViewHolder) convertView.getTag();
    }

    viewHolder.imageView.setImageDrawable(listContextMenuItems
            .get(position).getDrawable());
    viewHolder.textView.setText(listContextMenuItems.get(position)
            .getText());
    return convertView;

}

@Override
public int getCount() {
    return listContextMenuItems.size();
}

@Override
public Object getItem(int position) {
    return null;
}

@Override
public long getItemId(int position) {
    return 0;
}

}

context_menu_item.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="10dp"
android:paddingLeft="10dp"
android:paddingTop="10dp" >

<ImageView
    android:id="@+id/imageView_menu"
    android:layout_width="70dp"
    android:layout_height="70dp"
    android:scaleType="fitXY" />

<TextView
    android:id="@+id/textView_menu"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerVertical="true"
    android:layout_marginLeft="10dp"
    android:layout_toRightOf="@+id/imageView_menu" />

</RelativeLayout>

listview_context_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/listView_context_menu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/view" />
查看更多
孤傲高冷的网名
7楼-- · 2020-02-08 16:19

I did it by this way:

Reference screenshot:

enter image description here

Menu:

menu_patient_language.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context=".activities.PatientSelectionActivity">

    <item
        android:id="@+id/menuEnglish"
        android:icon="@drawable/language_english"
        android:title="@string/english" />

    <item
        android:id="@+id/menuFrench"
        android:icon="@drawable/language_french"
        android:title="@string/french" />

</menu>

Style:

style.xml:

  <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->

        <item name="android:popupMenuStyle">@style/popupMenuStyle</item>

    </style>

  <!--- Language selection popup -->

    <style name="popupMenuStyle" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="android:textColor">@color/colorPrimary</item>
        <item name="android:itemBackground">@android:color/white</item>
    </style>

Java code:

 private void showPopup(View v) {

        Context wrapper = new ContextThemeWrapper(this, R.style.popupMenuStyle);
        PopupMenu mypopupmenu = new PopupMenu(wrapper, v);

        setForceShowIcon(mypopupmenu);
        MenuInflater inflater = mypopupmenu.getMenuInflater();
        inflater.inflate(R.menu.menu_patient_language, mypopupmenu.getMenu());
        mypopupmenu.show();
//        mypopupmenu.getMenu().getItem(0).setIcon(getResources().getDrawable(R.mipmap.ic_launcher));
        mypopupmenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                txtPreferredLanguage.setText(item.getTitle().toString());
                switch (item.getItemId()) {
                    case R.id.menuEnglish:
                        // Your code goes here
                        break;

                    case R.id.menuFrench:
                        // Your code goes here
                        break;
                }
                return false;
            }
        });
    }

    private void setForceShowIcon(PopupMenu popupMenu) {
        try {
            Field[] mFields = popupMenu.getClass().getDeclaredFields();
            for (Field field : mFields) {
                if ("mPopup".equals(field.getName())) {
                    field.setAccessible(true);
                    Object menuPopupHelper = field.get(popupMenu);
                    Class<?> popupHelper = Class.forName(menuPopupHelper.getClass().getName());
                    Method mMethods = popupHelper.getMethod("setForceShowIcon", boolean.class);
                    mMethods.invoke(menuPopupHelper, true);
                    break;
                }
            }
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }

Hope this would help you sure.

Done

查看更多
登录 后发表回答