问题
I need to have dynamic Menu Item, a circle of user defined color, like this:

touching this menu item will open a color picker.
Now, I have sample ColorPickerIcon which extends View
public class ColorPickerIcon extends View { private Paint mPaint; private int mColor; private final int mRadius = 20; public ColorPickerIcon(Context context) { super(context); mColor = Color.BLACK; mPaint = createPaint(); } public ColorPickerIcon(Context context, AttributeSet attrs) { super(context, attrs); mColor = Color.BLACK; mPaint = createPaint(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawCircle(0, 0, mRadius, mPaint); } public void setPaintColor(int color) { mColor = color; } private Paint createPaint() { Paint temp = new Paint(); temp.setAntiAlias(true); temp.setStyle(Paint.Style.STROKE); temp.setStrokeJoin(Paint.Join.ROUND); temp.setStrokeWidth(6f); temp.setColor(mColor); return temp; } }
and menu.xml
<item android:id="@+id/menu_pick_color" android:title="@string/pick_color" yourapp:showAsAction="always" yourapp:actionViewClass="com.example.widgets.ColorPickerIcon"/> <item android:id="@+id/menu_clear" android:icon="@null" android:title="@string/clear" yourapp:showAsAction="always"/> <item android:id="@+id/menu_save" android:icon="@null" android:title="@string/save" yourapp:showAsAction="always"/>
But it doesn't work this way, neither can I instantiate the class nor it's rendered. Is there a way to use custom class and custom dynamic view as Menu Item?
回答1:
What you need to do is create a layout file with the view that you want for the item, the when you declare the item on the menu, assign the layout like this:
<item android:id="@+id/menu_pick_color" android:title="@string/pick_color" app:showAsAction="always" app:actionLayout="@layout/my_custom_item"/>
And that's it!
EDIT:
To access the custom item and modify it's color at runtime you can do this.
In your activity (or fragment) override the onPrepareOptionsMenu
(Assuming you already inflated your menu with 'onCreateOptionsMenu')
@Override public boolean onPrepareOptionsMenu(Menu menu) { //Get a reference to your item by id MenuItem item = menu.findItem(R.id.menu_pick_color); //Here, you get access to the view of your item, in this case, the layout of the item has a FrameLayout as root view but you can change it to whatever you use FrameLayout rootView = (FrameLayout)item.getActionView(); //Then you access to your control by finding it in the rootView YourControlClass control = (YourControlClass) rootView.findViewById(R.id.control_id); //And from here you can do whatever you want with your control return true; }
回答2:
Okay, so it turned out to be simpler than that.
In the DrawingActivity
@Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.menu_drawing, menu); MenuItem colorPicker = menu.findItem(R.id.menu_pick_color); ShapeDrawable circle = new ShapeDrawable(new OvalShape()); circle.getPaint().setColor(Color.GREEN); circle.setIntrinsicHeight(120); circle.setIntrinsicWidth(120); circle.setBounds(0, 0, 120, 120); colorPicker.setIcon(circle); return true; }
in menu.xml
<item android:id="@+id/menu_pick_color" android:title="@string/pick_color" yourapp:showAsAction="always"/>

That's all.
来源:https://stackoverflow.com/questions/26259162/custom-view-for-menu-item