protected boolean dispatchTouchEvent(MotionEvent event) {
   int x = (int) event.getX();
   int y = (int) event.getY();
   int action = event.getAction();
   if (mMotionTarget != null) {
     if (action == MotionEvent.ACTION_DOWN) {
       MotionEvent cancel = MotionEvent.obtain(event);
       cancel.setAction(MotionEvent.ACTION_CANCEL);
       dispatchTouchEvent(cancel, x, y, mMotionTarget, false);
       mMotionTarget = null;
     } else {
       dispatchTouchEvent(event, x, y, mMotionTarget, false);
       if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
         mMotionTarget = null;
       }
       return true;
     }
   }
   if (action == MotionEvent.ACTION_DOWN) {
     // in the reverse rendering order
     for (int i = getComponentCount() - 1; i >= 0; --i) {
       GLView component = getComponent(i);
       if (component.getVisibility() != GLView.VISIBLE) continue;
       if (dispatchTouchEvent(event, x, y, component, true)) {
         mMotionTarget = component;
         return true;
       }
     }
   }
   return onTouch(event);
 }
 protected void onVisibilityChanged(int visibility) {
   for (int i = 0, n = getComponentCount(); i < n; ++i) {
     GLView child = getComponent(i);
     if (child.getVisibility() == GLView.VISIBLE) {
       child.onVisibilityChanged(visibility);
     }
   }
 }
 // ********************************************************************
 // *                              MTK                                 *
 // ********************************************************************
 protected void dispatchKeyEvent(KeyEvent event) {
   for (int i = getComponentCount() - 1; i >= 0; --i) {
     GLView component = getComponent(i);
     if (component.getVisibility() != GLView.VISIBLE) {
       continue;
     }
     if (component != null) {
       component.onKeyEvent(event);
     }
   }
 }
  protected void renderChild(GLCanvas canvas, GLView component) {
    if (component.getVisibility() != GLView.VISIBLE && component.mAnimation == null) return;

    int xoffset = component.mBounds.left - mScrollX;
    int yoffset = component.mBounds.top - mScrollY;

    canvas.translate(xoffset, yoffset);

    CanvasAnimation anim = component.mAnimation;
    if (anim != null) {
      canvas.save(anim.getCanvasSaveFlags());
      if (anim.calculate(AnimationTime.get())) {
        invalidate();
      } else {
        component.mAnimation = null;
      }
      anim.apply(canvas);
    }
    component.render(canvas);
    if (anim != null) canvas.restore();
    canvas.translate(-xoffset, -yoffset);
  }