Android简明开发教程十四:Context Menu 绘制几何图形

jerry Android 2015年08月24日 收藏

上下文相关菜单(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 方法:

  1. @Override
  2. public void onCreateContextMenu(ContextMenu menu, View v,
  3.   ContextMenuInfo menuInfo) {
  4.  super.onCreateContextMenu(menu, v, menuInfo);
  5.  MenuInflater inflater = getMenuInflater();
  6.  inflater.inflate(R.menu.menu_context_shape, menu);
  7. }

处理Context Menu事件:

  1. @Override
  2. public boolean onContextItemSelected(MenuItem item) {
  3.  
  4.  menuOption = item.getItemId();
  5.  drawImage();
  6.  return super.onContextItemSelected(item);
  7.  
  8. }

为了在长按时能在View上显示Context Menu,需要为View注册Context Menu:

  1. public void onCreate(Bundle savedInstanceState) {
  2.  super.onCreate(savedInstanceState);
  3.  registerForContextMenu(graphic2dView);
  4. }

完整代码如下:

  1. public class Shape extends Graphics2DActivity {
  2.  
  3.  private int menuOption;
  4.  
  5.  public void onCreate(Bundle savedInstanceState) {
  6.   super.onCreate(savedInstanceState);
  7.   registerForContextMenu(graphic2dView);
  8.  }
  9.  
  10.  @Override
  11.  protected void drawImage() {
  12.   switch (menuOption) {
  13.   case R.id.mnuOval:
  14.    drawOval();
  15.    break;
  16.   case R.id.mnuPear:
  17.    drawPear();
  18.    break;
  19.   case R.id.mnuShape2DDemo:
  20.    drawShape2D();
  21.    break;
  22.   default:
  23.    drawOval();
  24.    break;
  25.   }
  26.   graphic2dView.refreshCanvas();
  27.  
  28.  }
  29.  
  30.  @Override
  31.  public void onCreateContextMenu(ContextMenu menu, View v,
  32.    ContextMenuInfo menuInfo) {
  33.   super.onCreateContextMenu(menu, v, menuInfo);
  34.   MenuInflater inflater = getMenuInflater();
  35.   inflater.inflate(R.menu.menu_context_shape, menu);
  36.  }
  37.  
  38.  @Override
  39.  public boolean onContextItemSelected(MenuItem item) {
  40.  
  41.   menuOption = item.getItemId();
  42.   drawImage();
  43.   return super.onContextItemSelected(item);
  44.  
  45.  }
  46.  
  47.  private void drawOval() {
  48.   AffineTransform mat1;
  49.  
  50.   /** Colors */
  51.   Color redColor = new Color(0x96ff0000, true);
  52.   Color greenColor = new Color(0xff00ff00);
  53.   mat1 = new AffineTransform();
  54.   mat1.translate(30, 40);
  55.   mat1.rotate(-30 * Math.PI / 180.0);
  56.   // Clear the canvas with white color.
  57.   graphics2D.clear(Color.WHITE);
  58.   graphics2D.Reset();
  59.  
  60.   graphics2D.setAffineTransform(new AffineTransform());
  61.   SolidBrush brush = new SolidBrush(greenColor);
  62.   graphics2D.fillOval(brush, 20, 60, 100, 50);
  63.  
  64.   com.mapdigit.drawing.Pen pen
  65.      = new com.mapdigit.drawing.Pen(redColor, 5);
  66.   graphics2D.setAffineTransform(mat1);
  67.   graphics2D.drawOval(pen, 20, 60, 100, 50);
  68.  }
  69.  
  70.  private void drawPear() {
  71.   Ellipse circle, oval, leaf, stem;
  72.   Area circ, ov, leaf1, leaf2, st1, st2;
  73.   circle = new Ellipse();
  74.   oval = new Ellipse();
  75.   leaf = new Ellipse();
  76.   stem = new Ellipse();
  77.   circ = new Area(circle);
  78.   ov = new Area(oval);
  79.   leaf1 = new Area(leaf);
  80.   leaf2 = new Area(leaf);
  81.   st1 = new Area(stem);
  82.   st2 = new Area(stem);
  83.   graphics2D.clear(Color.WHITE);
  84.   graphics2D.Reset();
  85.   int w = SharedGraphics2DInstance.CANVAS_WIDTH;
  86.   int h = SharedGraphics2DInstance.CANVAS_HEIGHT;
  87.   int ew = w / 2;
  88.   int eh = h / 2;
  89.   SolidBrush brush = new SolidBrush(Color.GREEN);
  90.   graphics2D.setDefaultBrush(brush);
  91.   // Creates the first leaf by filling the
  92.   //intersection of two Area
  93.   // objects created from an ellipse.
  94.   leaf.setFrame(ew - 16, eh - 29, 15, 15);
  95.   leaf1 = new Area(leaf);
  96.   leaf.setFrame(ew - 14, eh - 47, 30, 30);
  97.   leaf2 = new Area(leaf);
  98.   leaf1.intersect(leaf2);
  99.   graphics2D.fill(null, leaf1);
  100.  
  101.   // Creates the second leaf.
  102.   leaf.setFrame(ew + 1, eh - 29, 15, 15);
  103.   leaf1 = new Area(leaf);
  104.   leaf2.intersect(leaf1);
  105.   graphics2D.fill(null, leaf2);
  106.  
  107.   brush = new SolidBrush(Color.BLACK);
  108.   graphics2D.setDefaultBrush(brush);
  109.  
  110.   // Creates the stem by filling the Area
  111.   //resulting from the subtraction of two
  112.   //Area objects created from an ellipse.
  113.   stem.setFrame(ew, eh - 42, 40, 40);
  114.   st1 = new Area(stem);
  115.   stem.setFrame(ew + 3, eh - 47, 50, 50);
  116.   st2 = new Area(stem);
  117.   st1.subtract(st2);
  118.   graphics2D.fill(null, st1);
  119.  
  120.   brush = new SolidBrush(Color.YELLOW);
  121.   graphics2D.setDefaultBrush(brush);
  122.  
  123.   // Creates the pear itself by filling the
  124.   //Area resulting from the union of two Area
  125.   //objects created by two different ellipses.
  126.   circle.setFrame(ew - 25, eh, 50, 50);
  127.   oval.setFrame(ew - 19, eh - 20, 40, 70);
  128.   circ = new Area(circle);
  129.   ov = new Area(oval);
  130.   circ.add(ov);
  131.   graphics2D.fill(null, circ);
  132.  }
  133.  
  134.  private void drawShape2D() {
  135.   Color bg = Color.white;
  136.   Color fg = Color.black;
  137.   Color red = Color.red;
  138.   Color white = Color.white;
  139.   com.mapdigit.drawing.Pen pen
  140.      = new com.mapdigit.drawing.Pen(fg, 1);
  141.   SolidBrush brush = new SolidBrush(red);
  142.   // Clear the canvas with white color.
  143.   graphics2D.clear(bg);
  144.   graphics2D.Reset();
  145.   Dimension d = new Dimension(SharedGraphics2DInstance.CANVAS_WIDTH,
  146.     SharedGraphics2DInstance.CANVAS_HEIGHT);
  147.   int gridWidth = d.width / 2;
  148.   int gridHeight = d.height / 6;
  149.  
  150.   int x = 5;
  151.   int y = 7;
  152.   int rectWidth = gridWidth - 2 * x;
  153.   int stringY = gridHeight - 3 - 2 - 16;
  154.   int rectHeight = stringY - y - 2;
  155.   graphics2D.draw(pen, new Line(x, y + rectHeight - 1,
  156.     x + rectWidth, y));
  157.   x += gridWidth;
  158.   graphics2D.draw(pen, new Rectangle(x, y, rectWidth,
  159.     rectHeight));
  160.   x += gridWidth;
  161.   x = 5;
  162.   y += gridHeight;
  163.   stringY += gridHeight;
  164.   graphics2D.draw(pen, new RoundRectangle(x, y, rectWidth,
  165.     rectHeight,
  166.     10, 10));
  167.   x += gridWidth;
  168.   graphics2D.draw(pen, new Arc(x, y, rectWidth,
  169.     rectHeight, 90, 135,
  170.     Arc.OPEN));
  171.   x = 5;
  172.   y += gridHeight;
  173.   stringY += gridHeight;
  174.   graphics2D.draw(pen, new Ellipse(x, y, rectWidth,
  175.     rectHeight));
  176.   x += gridWidth;
  177.   // draw GeneralPath (polygon)
  178.   int x1Points[] = { x, x + rectWidth, x,
  179.     x + rectWidth };
  180.   int y1Points[] = { y, y + rectHeight,
  181.     y + rectHeight, y };
  182.   com.mapdigit.drawing.geometry.Path polygon
  183.     = new com.mapdigit.drawing.geometry.Path(
  184.     com.mapdigit.drawing.geometry.Path.WIND_EVEN_ODD,
  185.     x1Points.length);
  186.   polygon.moveTo(x1Points[0], y1Points[0]);
  187.   for (int index = 1; index < x1Points.length; index++) {
  188.    polygon.lineTo(x1Points[index], y1Points[index]);
  189.   }
  190.   polygon.closePath();
  191.   graphics2D.draw(pen, polygon);
  192.   x = 5;
  193.   y += gridHeight;
  194.   stringY += gridHeight;
  195.   int x2Points[] = { x, x + rectWidth, x, x + rectWidth };
  196.   int y2Points[] = { y, y + rectHeight, y + rectHeight, y };
  197.   com.mapdigit.drawing.geometry.Path polyline
  198.     = new com.mapdigit.drawing.geometry.Path(
  199.     com.mapdigit.drawing.geometry.Path.WIND_EVEN_ODD,
  200.     x2Points.length);
  201.   polyline.moveTo(x2Points[0], y2Points[0]);
  202.   for (int index = 1; index < x2Points.length; index++) {
  203.    polyline.lineTo(x2Points[index], y2Points[index]);
  204.   }
  205.   graphics2D.draw(pen, polyline);
  206.   x += gridWidth;
  207.   graphics2D.setPenAndBrush(pen, brush);
  208.   graphics2D.fill(null,
  209.     new Rectangle(x, y, rectWidth, rectHeight));
  210.   graphics2D.draw(null,
  211.     new Rectangle(x, y, rectWidth, rectHeight));
  212.   x = 5;
  213.   y += gridHeight;
  214.   stringY += gridHeight;
  215.   Color[] colors = new Color[] { red, white };
  216.   int[] fractions = new int[] { 0, 255 };
  217.   LinearGradientBrush redtowhite
  218.       = new LinearGradientBrush(x, y, x
  219.     + rectWidth, y, fractions, colors,
  220.     com.mapdigit.drawing.Brush.NO_CYCLE);
  221.   graphics2D.setPenAndBrush(pen, redtowhite);
  222.   graphics2D.fill(null, new RoundRectangle(x, y, rectWidth,
  223.     rectHeight,
  224.     10, 10));
  225.   graphics2D.draw(null, new RoundRectangle(x, y, rectWidth,
  226.     rectHeight,
  227.     10, 10));
  228.   x += gridWidth;
  229.   graphics2D.setPenAndBrush(pen, brush);
  230.   graphics2D.fill(null, new Arc(x, y, rectWidth,
  231.     rectHeight, 90, 135,
  232.     Arc.CHORD));
  233.   graphics2D.draw(null, new Arc(x, y, rectWidth,
  234.     rectHeight, 90, 135,
  235.     Arc.CHORD));
  236.   x = 5;
  237.   y += gridHeight;
  238.   stringY += gridHeight;
  239.   int x3Points[] = { x, x + rectWidth, x, x + rectWidth };
  240.   int y3Points[] = { y, y + rectHeight, y + rectHeight, y };
  241.   com.mapdigit.drawing.geometry.Path filledPolygon
  242.   = new com.mapdigit.drawing.geometry.Path(
  243.     com.mapdigit.drawing.geometry.Path.WIND_EVEN_ODD,
  244.     x3Points.length);
  245.   filledPolygon.moveTo(x3Points[0], y3Points[0]);
  246.   for (int index = 1; index < x3Points.length; index++) {
  247.    filledPolygon.lineTo(x3Points[index], y3Points[index]);
  248.   }
  249.   filledPolygon.closePath();
  250.   graphics2D.setPenAndBrush(pen, brush);
  251.   graphics2D.fill(null, filledPolygon);
  252.   graphics2D.draw(null, filledPolygon);
  253.  
  254.  }
  255. }

菜单除了这里介绍的功能外,Android也支持动态菜单或动态修改菜单。具体可以参见Android 文档。