上下文相关菜单(Context Menu)类同PC上按鼠标右键显示的菜单,在Android平台上是长按来激活Context Menu,Context Menu一般用来显示和当前UI内容相关的菜单。
Context Menu的用法和Option Menu非常类似:
首先是创建 菜单资源,在res\menu 下新建menu_context_shape.xml,用来显示Oval,Pear,Shape2D:
<?xml version=”1.0″ encoding=”utf-8″?>
<menu
xmlns:android=”http://schemas.android.com/apk/res/android“>
<item
android:id=”@+id/mnuOval”
android:title=”Oval”>
</item>
<item
android:id=”@+id/mnuPear”
android:title=”Pear”>
</item>
<item
android:id=”@+id/mnuShape2DDemo”
android:title=”Shape2D”>
</item>
</menu>
展开Context Menu,是通过onCreateContextMenu 方法:
@Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.menu_context_shape, menu); }
处理Context Menu事件:
@Override public boolean onContextItemSelected(MenuItem item) { menuOption = item.getItemId(); drawImage(); return super.onContextItemSelected(item); }
为了在长按时能在View上显示Context Menu,需要为View注册Context Menu:
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); registerForContextMenu(graphic2dView); }
完整代码如下:
public class Shape extends Graphics2DActivity { private int menuOption; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); registerForContextMenu(graphic2dView); } @Override protected void drawImage() { switch (menuOption) { case R.id.mnuOval: drawOval(); break; case R.id.mnuPear: drawPear(); break; case R.id.mnuShape2DDemo: drawShape2D(); break; default: drawOval(); break; } graphic2dView.refreshCanvas(); } @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.menu_context_shape, menu); } @Override public boolean onContextItemSelected(MenuItem item) { menuOption = item.getItemId(); drawImage(); return super.onContextItemSelected(item); } private void drawOval() { AffineTransform mat1; /** Colors */ Color redColor = new Color(0x96ff0000, true); Color greenColor = new Color(0xff00ff00); mat1 = new AffineTransform(); mat1.translate(30, 40); mat1.rotate(-30 * Math.PI / 180.0); // Clear the canvas with white color. graphics2D.clear(Color.WHITE); graphics2D.Reset(); graphics2D.setAffineTransform(new AffineTransform()); SolidBrush brush = new SolidBrush(greenColor); graphics2D.fillOval(brush, 20, 60, 100, 50); com.mapdigit.drawing.Pen pen = new com.mapdigit.drawing.Pen(redColor, 5); graphics2D.setAffineTransform(mat1); graphics2D.drawOval(pen, 20, 60, 100, 50); } private void drawPear() { Ellipse circle, oval, leaf, stem; Area circ, ov, leaf1, leaf2, st1, st2; circle = new Ellipse(); oval = new Ellipse(); leaf = new Ellipse(); stem = new Ellipse(); circ = new Area(circle); ov = new Area(oval); leaf1 = new Area(leaf); leaf2 = new Area(leaf); st1 = new Area(stem); st2 = new Area(stem); graphics2D.clear(Color.WHITE); graphics2D.Reset(); int w = SharedGraphics2DInstance.CANVAS_WIDTH; int h = SharedGraphics2DInstance.CANVAS_HEIGHT; int ew = w / 2; int eh = h / 2; SolidBrush brush = new SolidBrush(Color.GREEN); graphics2D.setDefaultBrush(brush); // Creates the first leaf by filling the //intersection of two Area // objects created from an ellipse. leaf.setFrame(ew - 16, eh - 29, 15, 15); leaf1 = new Area(leaf); leaf.setFrame(ew - 14, eh - 47, 30, 30); leaf2 = new Area(leaf); leaf1.intersect(leaf2); graphics2D.fill(null, leaf1); // Creates the second leaf. leaf.setFrame(ew + 1, eh - 29, 15, 15); leaf1 = new Area(leaf); leaf2.intersect(leaf1); graphics2D.fill(null, leaf2); brush = new SolidBrush(Color.BLACK); graphics2D.setDefaultBrush(brush); // Creates the stem by filling the Area //resulting from the subtraction of two //Area objects created from an ellipse. stem.setFrame(ew, eh - 42, 40, 40); st1 = new Area(stem); stem.setFrame(ew + 3, eh - 47, 50, 50); st2 = new Area(stem); st1.subtract(st2); graphics2D.fill(null, st1); brush = new SolidBrush(Color.YELLOW); graphics2D.setDefaultBrush(brush); // Creates the pear itself by filling the //Area resulting from the union of two Area //objects created by two different ellipses. circle.setFrame(ew - 25, eh, 50, 50); oval.setFrame(ew - 19, eh - 20, 40, 70); circ = new Area(circle); ov = new Area(oval); circ.add(ov); graphics2D.fill(null, circ); } private void drawShape2D() { Color bg = Color.white; Color fg = Color.black; Color red = Color.red; Color white = Color.white; com.mapdigit.drawing.Pen pen = new com.mapdigit.drawing.Pen(fg, 1); SolidBrush brush = new SolidBrush(red); // Clear the canvas with white color. graphics2D.clear(bg); graphics2D.Reset(); Dimension d = new Dimension(SharedGraphics2DInstance.CANVAS_WIDTH, SharedGraphics2DInstance.CANVAS_HEIGHT); int gridWidth = d.width / 2; int gridHeight = d.height / 6; int x = 5; int y = 7; int rectWidth = gridWidth - 2 * x; int stringY = gridHeight - 3 - 2 - 16; int rectHeight = stringY - y - 2; graphics2D.draw(pen, new Line(x, y + rectHeight - 1, x + rectWidth, y)); x += gridWidth; graphics2D.draw(pen, new Rectangle(x, y, rectWidth, rectHeight)); x += gridWidth; x = 5; y += gridHeight; stringY += gridHeight; graphics2D.draw(pen, new RoundRectangle(x, y, rectWidth, rectHeight, 10, 10)); x += gridWidth; graphics2D.draw(pen, new Arc(x, y, rectWidth, rectHeight, 90, 135, Arc.OPEN)); x = 5; y += gridHeight; stringY += gridHeight; graphics2D.draw(pen, new Ellipse(x, y, rectWidth, rectHeight)); x += gridWidth; // draw GeneralPath (polygon) int x1Points[] = { x, x + rectWidth, x, x + rectWidth }; int y1Points[] = { y, y + rectHeight, y + rectHeight, y }; com.mapdigit.drawing.geometry.Path polygon = new com.mapdigit.drawing.geometry.Path( com.mapdigit.drawing.geometry.Path.WIND_EVEN_ODD, x1Points.length); polygon.moveTo(x1Points[0], y1Points[0]); for (int index = 1; index < x1Points.length; index++) { polygon.lineTo(x1Points[index], y1Points[index]); } polygon.closePath(); graphics2D.draw(pen, polygon); x = 5; y += gridHeight; stringY += gridHeight; int x2Points[] = { x, x + rectWidth, x, x + rectWidth }; int y2Points[] = { y, y + rectHeight, y + rectHeight, y }; com.mapdigit.drawing.geometry.Path polyline = new com.mapdigit.drawing.geometry.Path( com.mapdigit.drawing.geometry.Path.WIND_EVEN_ODD, x2Points.length); polyline.moveTo(x2Points[0], y2Points[0]); for (int index = 1; index < x2Points.length; index++) { polyline.lineTo(x2Points[index], y2Points[index]); } graphics2D.draw(pen, polyline); x += gridWidth; graphics2D.setPenAndBrush(pen, brush); graphics2D.fill(null, new Rectangle(x, y, rectWidth, rectHeight)); graphics2D.draw(null, new Rectangle(x, y, rectWidth, rectHeight)); x = 5; y += gridHeight; stringY += gridHeight; Color[] colors = new Color[] { red, white }; int[] fractions = new int[] { 0, 255 }; LinearGradientBrush redtowhite = new LinearGradientBrush(x, y, x + rectWidth, y, fractions, colors, com.mapdigit.drawing.Brush.NO_CYCLE); graphics2D.setPenAndBrush(pen, redtowhite); graphics2D.fill(null, new RoundRectangle(x, y, rectWidth, rectHeight, 10, 10)); graphics2D.draw(null, new RoundRectangle(x, y, rectWidth, rectHeight, 10, 10)); x += gridWidth; graphics2D.setPenAndBrush(pen, brush); graphics2D.fill(null, new Arc(x, y, rectWidth, rectHeight, 90, 135, Arc.CHORD)); graphics2D.draw(null, new Arc(x, y, rectWidth, rectHeight, 90, 135, Arc.CHORD)); x = 5; y += gridHeight; stringY += gridHeight; int x3Points[] = { x, x + rectWidth, x, x + rectWidth }; int y3Points[] = { y, y + rectHeight, y + rectHeight, y }; com.mapdigit.drawing.geometry.Path filledPolygon = new com.mapdigit.drawing.geometry.Path( com.mapdigit.drawing.geometry.Path.WIND_EVEN_ODD, x3Points.length); filledPolygon.moveTo(x3Points[0], y3Points[0]); for (int index = 1; index < x3Points.length; index++) { filledPolygon.lineTo(x3Points[index], y3Points[index]); } filledPolygon.closePath(); graphics2D.setPenAndBrush(pen, brush); graphics2D.fill(null, filledPolygon); graphics2D.draw(null, filledPolygon); } }
菜单除了这里介绍的功能外,Android也支持动态菜单或动态修改菜单。具体可以参见Android 文档。