title: How to use isInEditMode() to see layout with custom View in the editor
body: <p>I must edit a software that have a custom view, when I try to edit layout xml, Eclipse says me: </p>
  
  <blockquote>
    <p>Use View.isInEditMode() in your custom views to skip code when shown
    in Eclipse</p>
  </blockquote>
  
  <p>But I have no idea about <em>how</em> and <em>where</em> I must use <em>isInEditMode()</em> in the app</p>
  
  <p>My xml file is</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;LinearLayout 
       xmlns:android="http://schemas.android.com/apk/res/android"
       android:orientation="vertical"
       android:layout_width="fill_parent"
       android:layout_height="fill_parent"
       android:background="#ff000000"
      &gt;
  &lt;TextView
       android:id="@+id/result"
       android:layout_width="fill_parent" 
       android:layout_height="wrap_content"
       android:gravity="right"
       android:textSize="32dip"
       android:scrollbars="none"
       android:lines="1"
       android:freezesText="true"
       android:textColor="@color/result"
      /&gt;
  &lt;EditText
       android:id="@+id/input"
       android:layout_width="fill_parent"
       android:layout_height="wrap_content"
       android:gravity="left"
       android:textSize="28dip"
       android:scrollbars="none"
       android:singleLine="true"
       android:autoText="false"
       android:imeOptions="flagNoEnterAction|flagNoExtractUi"
       /&gt;
  &lt;ListView
       android:id="@+id/history"
       android:layout_width="fill_parent"
       android:layout_height="0dip"
       android:layout_weight="1"
       android:cacheColorHint="#ff000000"
       android:choiceMode="singleChoice"
       android:scrollbarStyle="outsideInset"
       android:scrollbars="none"
      /&gt;
  &lt;calculator.GraphView
       android:id="@+id/graph"
       android:layout_width="fill_parent"
       android:layout_height="0dip"
       android:layout_weight="1"
       android:visibility="gone"
       /&gt;
  &lt;include layout="@layout/keyboard" /&gt;
  &lt;/LinearLayout&gt;
  </code></pre>
  
  <p>And my GraphView is</p>
  
  <pre><code>public class GraphView extends View implements Grapher,
          ZoomButtonsController.OnZoomListener,
          TouchHandler.TouchHandlerInterface {
      private int width, height;
      private Matrix matrix = new Matrix();
      private Paint paint = new Paint();
      private Paint textPaint = new Paint();
      private ArrayList&lt;Function&gt; funcs = new ArrayList&lt;Function&gt;();
      private Data next = new Data(), endGraph = new Data();
      private Data graphs[] = { new Data(), new Data(), new Data(), new Data(),
              new Data() };
      private static final int GRAPHS_SIZE = 5;
      private float gwidth = 8;
      private float currentX, currentY;
      private float lastMinX;
      private Scroller scroller;
      private float boundMinY, boundMaxY;
      protected ZoomButtonsController zoomController = new ZoomButtonsController(
              this);
      private ZoomTracker zoomTracker = new ZoomTracker();
      private TouchHandler touchHandler;
      private float lastTouchX, lastTouchY;
  
      private static final int COL_AXIS = 0xff00a000, COL_GRID = 0xff004000,
              COL_TEXT = 0xff00ff00;
  
      private static final int COL_GRAPH[] = { 0xffffffff, 0xff00ffff,
              0xffffff00, 0xffff00ff, 0xff80ff80 };
  
      public GraphView(Context context, AttributeSet attrs) {
          super(context, attrs);
          init(context);
      }
  
      public GraphView(Context context) {
          super(context);
          touchHandler = new TouchHandler(this);
          init(context);
      }
  
      private void init(Context context) {
          zoomController.setOnZoomListener(this);
          scroller = new Scroller(context);
          paint.setAntiAlias(false);
          textPaint.setAntiAlias(true);
      }
  
      @SuppressLint("WrongCall")
      public String captureScreenshot() {
          Bitmap bitmap = Bitmap.createBitmap(width, height,
                  Bitmap.Config.RGB_565);
          Canvas canvas = new Canvas(bitmap);
          onDraw(canvas);
          return Util.saveBitmap(bitmap, Grapher.SCREENSHOT_DIR, "calculator");
      }
  
      private void clearAllGraph() {
          for (int i = 0; i &lt; GRAPHS_SIZE; ++i) {
              graphs[i].clear();
          }
      }
  
      public void setFunctions(ArrayList&lt;Function&gt; fs) {
          funcs.clear();
          for (Function f : fs) {
              int arity = f.arity();
              if (arity == 0 || arity == 1) {
                  funcs.add(f);
              }
          }
          clearAllGraph();
          invalidate();
      }
  
      public void setFunction(Function f) {
          funcs.clear();
          if (f != null) {
              funcs.add(f);
          }
          clearAllGraph();
          invalidate();
      }
  
      public void onVisibilityChanged(boolean visible) {
      }
  
      public void onZoom(boolean zoomIn) {
          if (zoomIn) {
              if (canZoomIn()) {
                  gwidth /= 2;
                  invalidateGraphs();
              }
          } else {
              if (canZoomOut()) {
                  gwidth *= 2;
                  invalidateGraphs();
              }
          }
          zoomController.setZoomInEnabled(canZoomIn());
          zoomController.setZoomOutEnabled(canZoomOut());
      }
  
      public void onResume() {
      }
  
      public void onPause() {
      }
  
      public void onDetachedFromWindow() {
          zoomController.setVisible(false);
          super.onDetachedFromWindow();
      }
  
      protected void onSizeChanged(int w, int h, int ow, int oh) {
          width = w;
          height = h;
          clearAllGraph();
      }
  
      protected void onDraw(Canvas canvas) {
          if (funcs.size() == 0) {
              return;
          }
          if (scroller.computeScrollOffset()) {
              final float scale = gwidth / width;
              currentX = scroller.getCurrX() * scale;
              currentY = scroller.getCurrY() * scale;
              if (!scroller.isFinished()) {
                  invalidate();
              }
          }
          drawGraph(canvas);
      }
  
      private float eval(Function f, float x) {
          float v = (float) f.eval(x);
  
          if (v &lt; -10000f) {
              return -10000f;
          }
          if (v &gt; 10000f) {
              return 10000f;
          }
          return v;
      }
  
      private float distance2(float x1, float y1, float x2, float y2, float y) {
          final float dx = x2 - x1;
          final float dy = y2 - y1;
          final float up = dx * (y1 + y2 - y - y);
          return up * up / (dx * dx + dy * dy);
      }
  
      private void computeGraph(Function f, float minX, float maxX, float minY,
              float maxY, Data graph) {
          if (f.arity() == 0) {
              float v = (float) f.eval();
              if (v &lt; -10000f) {
                  v = -10000f;
              }
              if (v &gt; 10000f) {
                  v = 10000f;
              }
              graph.clear();
              graph.push(minX, v);
              graph.push(maxX, v);
              return;
          }
  
          final float scale = width / gwidth;
          final float maxStep = 15.8976f / scale;
          final float minStep = .05f / scale;
          float ythresh = 1 / scale;
          ythresh = ythresh * ythresh;
          if (!graph.empty()) {
              if (minX &gt;= lastMinX) {
                  graph.eraseBefore(minX);
              } else {
                  graph.eraseAfter(maxX);
                  maxX = Math.min(maxX, graph.firstX());
                  graph.swap(endGraph);
              }
          }
          if (graph.empty()) {
              graph.push(minX, eval(f, minX));
          }
          float leftX, leftY;
          float rightX = graph.topX(), rightY = graph.topY();
          int nEval = 1;
          while (true) {
              leftX = rightX;
              leftY = rightY;
              if (leftX &gt; maxX) {
                  break;
              }
              if (next.empty()) {
                  float x = leftX + maxStep;
                  next.push(x, eval(f, x));
                  ++nEval;
              }
              rightX = next.topX();
              rightY = next.topY();
              next.pop();
  
              if (leftY != leftY &amp;&amp; rightY != rightY) { // NaN
                  continue;
              }
  
              float dx = rightX - leftX;
              float middleX = (leftX + rightX) / 2;
              float middleY = eval(f, middleX);
              ++nEval;
              boolean middleIsOutside = (middleY &lt; leftY &amp;&amp; middleY &lt; rightY)
                      || (leftY &lt; middleY &amp;&amp; rightY &lt; middleY);
              if (dx &lt; minStep) {
                  if (middleIsOutside) {
                      graph.push(rightX, Float.NaN);
                  }
                  graph.push(rightX, rightY);
                  continue;
              }
              if (middleIsOutside
                      &amp;&amp; ((leftY &lt; minY &amp;&amp; rightY &gt; maxY) || (leftY &gt; maxY &amp;&amp; rightY &lt; minY))) {
                  graph.push(rightX, Float.NaN);
                  graph.push(rightX, rightY);
                  continue;
              }
  
              if (!middleIsOutside) {
  
                  if (distance2(leftX, leftY, rightX, rightY, middleY) &lt; ythresh) {
                      graph.push(rightX, rightY);
                      continue;
                  }
              }
              next.push(rightX, rightY);
              next.push(middleX, middleY);
              rightX = leftX;
              rightY = leftY;
          }
          if (!endGraph.empty()) {
              graph.append(endGraph);
          }
          long t2 = System.currentTimeMillis();
  
          next.clear();
          endGraph.clear();
      }
  
      private static Path path = new Path();
  
      private Path graphToPath(Data graph) {
          boolean first = true;
          int size = graph.size;
          float[] xs = graph.xs;
          float[] ys = graph.ys;
          path.rewind();
          for (int i = 0; i &lt; size; ++i) {
              float y = ys[i];
              float x = xs[i];
              // Calculator.log("path " + x + ' ' + y);
              if (y == y) { // !NaN
                  if (first) {
                      path.moveTo(x, y);
                      first = false;
                  } else {
                      path.lineTo(x, y);
                  }
              } else {
                  first = true;
              }
          }
          return path;
      }
  
      private static final float NTICKS = 15;
  
      private static float stepFactor(float w) {
          float f = 1;
          while (w / f &gt; NTICKS) {
              f *= 10;
          }
          while (w / f &lt; NTICKS / 10) {
              f /= 10;
          }
          float r = w / f;
          if (r &lt; NTICKS / 5) {
              return f / 5;
          } else if (r &lt; NTICKS / 2) {
              return f / 2;
          } else {
              return f;
          }
      }
  
      private static StringBuilder b = new StringBuilder();
      private static char[] buf = new char[20];
  
      private static StringBuilder format(float fv) {
          int pos = 0;
          boolean addDot = false;
          int v = Math.round(fv * 100);
          boolean isNeg = v &lt; 0;
          v = isNeg ? -v : v;
          for (int i = 0; i &lt; 2; ++i) {
              int digit = v % 10;
              v /= 10;
              if (digit != 0 || addDot) {
                  buf[pos++] = (char) ('0' + digit);
                  addDot = true;
              }
          }
          if (addDot) {
              buf[pos++] = '.';
          }
          if (v == 0) {
              buf[pos++] = '0';
          }
          while (v != 0) {
              buf[pos++] = (char) ('0' + (v % 10));
              v /= 10;
          }
          if (isNeg) {
              buf[pos++] = '-';
          }
          b.setLength(0);
          b.append(buf, 0, pos);
          b.reverse();
          return b;
      }
  
      private void drawGraph(Canvas canvas) {
          long t1 = System.currentTimeMillis();
          float minX = currentX - gwidth / 2;
          float maxX = minX + gwidth;
          float ywidth = gwidth * height / width;
          float minY = currentY - ywidth / 2;
          float maxY = minY + ywidth;
          if (minY &lt; boundMinY || maxY &gt; boundMaxY) {
              float halfw = ywidth / 2;
              boundMinY = minY - halfw;
              boundMaxY = maxY + halfw;
              clearAllGraph();
          }
  
          canvas.drawColor(0xff000000);
  
          paint.setStrokeWidth(0);
          paint.setAntiAlias(false);
          paint.setStyle(Paint.Style.STROKE);
  
          final float h2 = height / 2f;
          final float scale = width / gwidth;
  
          float x0 = -minX * scale;
          boolean drawYAxis = true;
          if (x0 &lt; 25) {
              x0 = 25;
              // drawYAxis = false;
          } else if (x0 &gt; width - 3) {
              x0 = width - 3;
              // drawYAxis = false;
          }
          float y0 = maxY * scale;
          if (y0 &lt; 3) {
              y0 = 3;
          } else if (y0 &gt; height - 15) {
              y0 = height - 15;
          }
  
          final float tickSize = 3;
          final float y2 = y0 + tickSize;
          paint.setColor(COL_GRID);
          float step = stepFactor(gwidth);
          float v = ((int) (minX / step)) * step;
          textPaint.setColor(COL_TEXT);
          textPaint.setTextSize(12);
          textPaint.setTextAlign(Paint.Align.CENTER);
          float stepScale = step * scale;
          for (float x = (v - minX) * scale; x &lt;= width; x += stepScale, v += step) {
              canvas.drawLine(x, 0, x, height, paint);
              if (!(-.001f &lt; v &amp;&amp; v &lt; .001f)) {
                  StringBuilder b = format(v);
                  canvas.drawText(b, 0, b.length(), x, y2 + 10, textPaint);
              }
          }
  
          final float x1 = x0 - tickSize;
          v = ((int) (minY / step)) * step;
          textPaint.setTextAlign(Paint.Align.RIGHT);
          for (float y = height - (v - minY) * scale; y &gt;= 0; y -= stepScale, v += step) {
              canvas.drawLine(0, y, width, y, paint);
              if (!(-.001f &lt; v &amp;&amp; v &lt; .001f)) {
                  StringBuilder b = format(v);
                  canvas.drawText(b, 0, b.length(), x1, y + 4, textPaint);
              }
          }
  
          paint.setColor(COL_AXIS);
          if (drawYAxis) {
              canvas.drawLine(x0, 0, x0, height, paint);
          }
          canvas.drawLine(0, y0, width, y0, paint);
  
          matrix.reset();
          matrix.preTranslate(-currentX, -currentY);
          matrix.postScale(scale, -scale);
          matrix.postTranslate(width / 2, height / 2);
  
          paint.setStrokeWidth(0);
          paint.setAntiAlias(false);
  
          int n = Math.min(funcs.size(), GRAPHS_SIZE);
          for (int i = 0; i &lt; n; ++i) {
              computeGraph(funcs.get(i), minX, maxX, boundMinY, boundMaxY,
                      graphs[i]);
              Path path = graphToPath(graphs[i]);
              path.transform(matrix);
              paint.setColor(COL_GRAPH[i]);
              canvas.drawPath(path, paint);
          }
          lastMinX = minX;
      }
  
      private boolean canZoomIn() {
          return gwidth &gt; 1f;
      }
  
      private boolean canZoomOut() {
          return gwidth &lt; 50;
      }
  
      private void invalidateGraphs() {
          clearAllGraph();
          boundMinY = boundMaxY = 0;
          invalidate();
      }
  
      @Override
      public boolean onTouchEvent(MotionEvent event) {
          return touchHandler != null ? touchHandler.onTouchEvent(event) : super
                  .onTouchEvent(event);
      }
  
      public void onTouchDown(float x, float y) {
          zoomController.setVisible(true);
          if (!scroller.isFinished()) {
              scroller.abortAnimation();
          }
          lastTouchX = x;
          lastTouchY = y;
      }
  
      public void onTouchMove(float x, float y) {
          float deltaX = x - lastTouchX;
          float deltaY = y - lastTouchY;
          if (deltaX &lt; -1 || deltaX &gt; 1 || deltaY &lt; -1 || deltaY &gt; 1) {
              scroll(-deltaX, deltaY);
              lastTouchX = x;
              lastTouchY = y;
              invalidate();
          }
      }
  
      public void onTouchUp(float x, float y) {
          final float scale = width / gwidth;
          float sx = -touchHandler.velocityTracker.getXVelocity();
          float sy = touchHandler.velocityTracker.getYVelocity();
          final float asx = Math.abs(sx);
          final float asy = Math.abs(sy);
          if (asx &lt; asy / 3) {
              sx = 0;
          } else if (asy &lt; asx / 3) {
              sy = 0;
          }
          scroller.fling(Math.round(currentX * scale),
                  Math.round(currentY * scale), Math.round(sx), Math.round(sy),
                  -10000, 10000, -10000, 10000);
          invalidate();
      }
  
      public void onTouchZoomDown(float x1, float y1, float x2, float y2) {
          zoomTracker.start(gwidth, x1, y1, x2, y2);
      }
  
      public void onTouchZoomMove(float x1, float y1, float x2, float y2) {
          if (!zoomTracker.update(x1, y1, x2, y2)) {
              return;
          }
          float targetGwidth = zoomTracker.value;
          if (targetGwidth &gt; .25f &amp;&amp; targetGwidth &lt; 200) {
              gwidth = targetGwidth;
          }
          invalidateGraphs();
      }
  
      private void scroll(float deltaX, float deltaY) {
          final float scale = gwidth / width;
          float dx = deltaX * scale;
          float dy = deltaY * scale;
          final float adx = Math.abs(dx);
          final float ady = Math.abs(dy);
          if (adx &lt; ady / 3) {
              dx = 0;
          } else if (ady &lt; adx / 3) {
              dy = 0;
          }
          currentX += dx;
          currentY += dy;
      }
  }
  </code></pre>
  
  <p>The error Log of the XML editor</p>
  
  <pre><code>java.lang.NullPointerException
      at android.widget.ZoomButtonsController.createContainer(ZoomButtonsController.java:266)
      at android.widget.ZoomButtonsController.&lt;init&gt;(ZoomButtonsController.java:212)
      at calculator.GraphView.&lt;init&gt;(GraphView.java:43)
      at sun.reflect.NativeConstructorAccessorImpl.newInstance0(    at sun.reflect.NativeConstructorAccessorImpl.newInstance(    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(    at java.lang.reflect.Constructor.newInstance(    at com.android.ide.eclipse.adt.internal.editors.layout.ProjectCallback.instantiateClass(ProjectCallback.java:422)
      at com.android.ide.eclipse.adt.internal.editors.layout.ProjectCallback.loadView(ProjectCallback.java:179)
      at android.view.BridgeInflater.loadCustomView(BridgeInflater.java:207)
      at android.view.BridgeInflater.createViewFromTag(BridgeInflater.java:135)
      at android.view.LayoutInflater.rInflate_Original(LayoutInflater.java:746)
      at android.view.LayoutInflater_Delegate.rInflate(LayoutInflater_Delegate.java:64)
      at android.view.LayoutInflater.rInflate(LayoutInflater.java:718)
      at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
      at android.view.LayoutInflater.inflate(LayoutInflater.java:372)
  </code></pre>