如何使用isInEditMode()在编辑器中查看具有自定义视图的布局

我必须编辑一个具有自定义视图的软件,当我尝试编辑布局xml时,Eclipse对我说:

在Eclipse中显示时,在自定义视图中使用View.isInEditMode()可以跳过代码

但我不知道如何以及在哪里必须在应用程序中使用isInEditMode()

我的XML文件是

<?xml version="1.0" encoding="utf-8"?> <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" > <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" /> <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" /> <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" /> <calculator.GraphView android:id="@+id/graph" android:layout_width="fill_parent" android:layout_height="0dip" android:layout_weight="1" android:visibility="gone" /> <include layout="@layout/keyboard" /> </LinearLayout> 

而我的GraphView是

 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<Function> funcs = new ArrayList<Function>(); 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 < GRAPHS_SIZE; ++i) { graphs[i].clear(); } } public void setFunctions(ArrayList<Function> 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 < -10000f) { return -10000f; } if (v > 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 < -10000f) { v = -10000f; } if (v > 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 >= 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 > 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 && rightY != rightY) { // NaN continue; } float dx = rightX - leftX; float middleX = (leftX + rightX) / 2; float middleY = eval(f, middleX); ++nEval; boolean middleIsOutside = (middleY < leftY && middleY < rightY) || (leftY < middleY && rightY < middleY); if (dx < minStep) { if (middleIsOutside) { graph.push(rightX, Float.NaN); } graph.push(rightX, rightY); continue; } if (middleIsOutside && ((leftY < minY && rightY > maxY) || (leftY > maxY && rightY < minY))) { graph.push(rightX, Float.NaN); graph.push(rightX, rightY); continue; } if (!middleIsOutside) { if (distance2(leftX, leftY, rightX, rightY, middleY) < 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 < 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 > NTICKS) { f *= 10; } while (w / f < NTICKS / 10) { f /= 10; } float r = w / f; if (r < NTICKS / 5) { return f / 5; } else if (r < 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 < 0; v = isNeg ? -v : v; for (int i = 0; i < 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 < boundMinY || maxY > 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 < 25) { x0 = 25; // drawYAxis = false; } else if (x0 > width - 3) { x0 = width - 3; // drawYAxis = false; } float y0 = maxY * scale; if (y0 < 3) { y0 = 3; } else if (y0 > 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 <= width; x += stepScale, v += step) { canvas.drawLine(x, 0, x, height, paint); if (!(-.001f < v && v < .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 >= 0; y -= stepScale, v += step) { canvas.drawLine(0, y, width, y, paint); if (!(-.001f < v && v < .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 < 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 > 1f; } private boolean canZoomOut() { return gwidth < 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 < -1 || deltaX > 1 || deltaY < -1 || deltaY > 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 < asy / 3) { sx = 0; } else if (asy < 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 > .25f && targetGwidth < 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 < ady / 3) { dx = 0; } else if (ady < adx / 3) { dy = 0; } currentX += dx; currentY += dy; } } 

XML编辑器的错误日志

 java.lang.NullPointerException at android.widget.ZoomButtonsController.createContainer(ZoomButtonsController.java:266) at android.widget.ZoomButtonsController.<init>(ZoomButtonsController.java:212) at calculator.GraphView.<init>(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) 

应该在Custom View构造函数中使用isInEditMode() 。 试试下面的代码:

  public class GraphView extends View implements Grapher { public GraphView(Context context, AttributeSet attrs) { super(context, attrs); if(!isInEditMode()) init(context); } public GraphView(Context context) { super(context); if(!isInEditMode()){ touchHandler = new TouchHandler(this); init(context); } } 
 public class CustomTextView extends TextView { public CustomTextView(Context context) { super(context); } public CustomTextView(Context context, AttributeSet attrs) { super(context, attrs); if (!isInEditMode()) { createTypeface(context, attrs); //whatever added functionality you are trying to add to Widget, call that inside this condition. } } public CustomTextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } //Typeface I wan to set to my Custom TextView It can be any other functionality of your choice private void createTypeface(Context context, AttributeSet attrs) { TypedArray styledAttrs = context.obtainStyledAttributes(attrs, R.styleable.CustomTextView); String fontName = styledAttrs .getString(R.styleable.CustomTextView_Typeface); styledAttrs.recycle(); if (fontName != null) { Typeface typeface = Typeface.createFromAsset(context.getAssets(), "fonts/" + fontName); setTypeface(typeface); styledAttrs.recycle(); } } } 

试试这为我工作

 public class MyOwnTextView extends TextView { public MyOwnTextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); // TODO Auto-generated constructor stub isInEditMode(); } public MyOwnTextView(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub isInEditMode(); } public MyOwnTextView(Context context) { super(context); // TODO Auto-generated constructor stub isInEditMode(); } public void setTypeface(Typeface tf, int style) { if(!this.isInEditMode()){ Typeface normalTypeface = Typeface.createFromAsset(getContext().getAssets(), "font/Roboto-Light.ttf"); Typeface boldTypeface = Typeface.createFromAsset(getContext().getAssets(), "font/Roboto-Light.ttf"); if (style == Typeface.BOLD) { super.setTypeface(boldTypeface/*, -1*/); } else { super.setTypeface(normalTypeface/*, -1*/); } } } } 

然后在XML

 <com.xxxxx.appname.MyOwnTextView android:layout_width="fill_parent" android:layout_height="fill_parent" />