如何使用isInEditMode(),看看在编辑器中使用自定义视图布局 [英] How to use isInEditMode() to see layout with custom View in the editor

查看:370
本文介绍了如何使用isInEditMode(),看看在编辑器中使用自定义视图布局的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  

使用View.isInEditMode()在你的自定义视图跳过code时,显示   在Eclipse

但我不知道有关的如何其中的我必须使用的 isInEditMode()的应用程序中的

我的XML文件是

 < XML版本=1.0编码=UTF-8&GT?;
<的LinearLayout
     的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
     机器人:方向=垂直
     机器人:layout_width =FILL_PARENT
     机器人:layout_height =FILL_PARENT
     机器人:后台=#FF000000
    >
<的TextView
     机器人:ID =@ + ID /结果
     机器人:layout_width =FILL_PARENT
     机器人:layout_height =WRAP_CONTENT
     机器人:重力=右
     机器人:TEXTSIZE =32dip
     机器人:滚动条=无
     机器人:行=1
     机器人:freezesText =真
     机器人:文字颜色=@色/结果
    />
<的EditText
     机器人:ID =@ + ID /输入
     机器人:layout_width =FILL_PARENT
     机器人:layout_height =WRAP_CONTENT
     机器人:重力=左
     机器人:TEXTSIZE =28DIP
     机器人:滚动条=无
     机器人:单线=真
     机器人:自动图文集=假
     机器人:imeOptions =flagNoEnterAction | flagNoExtractUi
     />
<的ListView
     机器人:ID =@ + ID /史
     机器人:layout_width =FILL_PARENT
     机器人:layout_height =0dip
     机器人:layout_weight =1
     机器人:cacheColorHint =#FF000000
     机器人:choiceMode =singleChoice
     机器人:scrollbarStyle =outsideInset
     机器人:滚动条=无
    />
< calculator.GraphView
     机器人:ID =@ + ID /图
     机器人:layout_width =FILL_PARENT
     机器人:layout_height =0dip
     机器人:layout_weight =1
     机器人:能见度=水涨船高
     />
<包括布局=@布局/键盘/>
< / LinearLayout中>
 

和我GraphView是

 公共类GraphView扩展视图实现绘图,
        ZoomButtonsController.OnZoomListener,
        TouchHandler.TouchHandlerInterface {
    私人诠释的宽度,高度;
    私人矩阵的矩阵=新的Matrix();
    民营涂料粉刷=新的油漆();
    民营涂料textPaint =新的油漆();
    私人的ArrayList<作用> funcs中=新的ArrayList<作用>();
    私人数据下一=新的Data(),endGraph =新的Data();
    私人数据图[] = {新的Data(),新的Data(),新的Data(),新的Data()
            新的Data()};
    私有静态最终诠释GRAPHS_SIZE = 5;
    私人浮动gwidth = 8;
    私人浮动currentX,currentY;
    私人浮动lastMinX;
    私人滚轮滚动;
    私人浮动boundMinY,boundMaxY;
    保护ZoomButtonsController zoomController =新ZoomButtonsController(
            本);
    私人ZoomTracker zoomTracker =新ZoomTracker();
    私人TouchHandler touchHandler;
    私人浮动lastTouchX,lastTouchY;

    私有静态最终诠释COL_AXIS = 0xff00a000,COL_GRID = 0xff004000,
            COL_TEXT = 0xff00ff00;

    私有静态最终诠释COL_GRAPH [] = {为0xffffffff,0xff00ffff,
            0xffffff00,0xffff00ff,0xff80ff80};

    公共GraphView(上下文的背景下,ATTRS的AttributeSet){
        超(背景下,ATTRS);
        的init(上下文);
    }

    公共GraphView(上下文的背景下){
        超(上下文);
        touchHandler =新TouchHandler(本);
        的init(上下文);
    }

    私人无效的init(上下文的背景下){
        zoomController.setOnZoomListener(本);
        滚动=新的滚轮(上下文);
        paint.setAntiAlias​​(假);
        textPaint.setAntiAlias​​(真正的);
    }

    @燮pressLint(WrongCall)
    公共字符串captureScreenshot(){
        点阵位图= Bitmap.createBitmap(宽度,高度,
                Bitmap.Config.RGB_565);
        帆布油画=新的Canvas(位);
        的OnDraw(画布);
        返回Util.saveBitmap(位图,Grapher.SCREENSHOT_DIR,计算器);
    }

    私人无效clearAllGraph(){
        的for(int i = 0; I< GRAPHS_SIZE ++我){
            图[我] .clear();
        }
    }

    公共无效setFunctions(ArrayList的<作用> FS){
        funcs.clear();
        对于(功能F:FS){
            INT元数= f.arity();
            如果(参数数量== 0 ||元数== 1){
                funcs.add(F);
            }
        }
        clearAllGraph();
        无效();
    }

    公共无效setFunction(功能F){
        funcs.clear();
        如果(F!= NULL){
            funcs.add(F);
        }
        clearAllGraph();
        无效();
    }

    公共无效onVisibilityChanged(布尔可见){
    }

    公共无效onZoom(布尔zoomIn){
        如果(zoomIn){
            如果(canZoomIn()){
                gwidth / = 2;
                invalidateGraphs();
            }
        } 其他 {
            如果(canZoomOut()){
                gwidth * = 2;
                invalidateGraphs();
            }
        }
        zoomController.setZoomInEnabled(canZoomIn());
        zoomController.setZoomOutEnabled(canZoomOut());
    }

    公共无效onResume(){
    }

    公共无效的onPause(){
    }

    公共无效onDetachedFromWindow(){
        zoomController.setVisible(假);
        super.onDetachedFromWindow();
    }

    保护无效onSizeChanged(INT W,INT小时,INT流,诠释哦){
        宽= W;
        高度= H;
        clearAllGraph();
    }

    保护无效的OnDraw(帆布油画){
        如果(funcs.size()== 0){
            返回;
        }
        如果(scroller.computeScrollOffset()){
            最终浮动规模= gwidth /宽;
            currentX = scroller.getCurrX()*规模;
            currentY = scroller.getCurrY()*规模;
            如果(!scroller.isFinished()){
                无效();
            }
        }
        drawGraph(画布);
    }

    私人浮动的eval(功能楼浮动X){
        浮动V =(浮点)f.eval(X);

        如果(V族; -10000f){
            返回-10000f;
        }
        如果(V> 1000°F){
            返回10000F;
        }
        返回伏;
    }

    私人浮动距离2(浮动X1,Y1浮球,浮球X2,Y2浮球,浮球Y){
        最终浮动DX = X2  -  X1;
        最终浮动DY = Y2  -  Y1;
        最终浮动起来= DX *(Y1 + Y2  -  Y  -  Y);
        返回最多*升/(DX * DX + DY * DY);
    }

    私人无效computeGraph(功能楼飘了minX,浮MAXX,浮MINY,
            浮MAXY,数据图表){
        如果(f.arity()== 0){
            浮动V =(浮点)f.eval();
            如果(V族; -10000f){
                V = -10000f;
            }
            如果(V> 1000°F){
                V = 10000F;
            }
            graph.clear();
            graph.push(其minX,V);
            graph.push(MAXX,V);
            返回;
        }

        最终浮动规模=宽/ gwidth;
        最终浮动maxStep = 15.8976f /规模;
        最终浮动minStep = .05f /规模;
        浮ythresh = 1 /规模;
        ythresh = ythresh * ythresh;
        如果(!graph.empty()){
            如果(其minX> = lastMinX){
                graph.eraseBefore(其minX);
            } 其他 {
                graph.eraseAfter(MAXX);
                MAXX = Math.min(MAXX,graph.firstX());
                graph.swap(endGraph);
            }
        }
        如果(graph.empty()){
            graph.push(其minX中,eval(F,其minX));
        }
        浮leftX,左撇子;
        浮rightX = graph.topX(),用右手= graph.topY();
        INT nEval = 1;
        而(真){
            leftX = rightX;
            左撇子=右倾;
            如果(leftX> MAXX){
                打破;
            }
            如果(next.empty()){
                浮动X = leftX + maxStep;
                next.push(X中,eval(F,X));
                ++ nEval;
            }
            rightX = next.topX();
            右倾= next.topY();
            next.pop();

            如果(左撇子=左手和放大器;!&安培;!用右手=用右手){//为NaN
                继续;
            }

            浮DX = rightX  -  leftX;
            浮middleX =(leftX + rightX)/ 2;
            浮middleY =的eval(F,middleX);
            ++ nEval;
            布尔middleIsOutside =(middleY<左撇子和放大器;&安培; middleY<用右手)
                    || (左撇子< middleY和放大器;&安培;右倾< middleY);
            如果(DX< minStep){
                如果(middleIsOutside){
                    graph.push(rightX,的Float.NaN);
                }
                graph.push(rightX,用右手);
                继续;
            }
            如果(middleIsOutside
                    &功放;&安培; ((左撇子< MINY和放大器;&安培;右倾> MAXY)||(左撇子> MAXY和放大器;&安培;右倾< MINY))){
                graph.push(rightX,的Float.NaN);
                graph.push(rightX,用右手);
                继续;
            }

            如果(!middleIsOutside){

                如果(距离2(leftX,左撇子,rightX,用右手,middleY)< ythresh){
                    graph.push(rightX,用右手);
                    继续;
                }
            }
            next.push(rightX,用右手);
            next.push(middleX,middleY);
            rightX = leftX;
            用右手=左撇子;
        }
        如果(!endGraph.empty()){
            graph.append(endGraph);
        }
        长T2 = System.currentTimeMillis的();

        next.clear();
        endGraph.clear();
    }

    私有静态路径path =新路径();

    私人路径graphToPath(资料图){
        布尔第一= TRUE;
        INT大小= graph.size;
        浮动[] XS = graph.xs;
        浮动[] YS = graph.ys;
        path.rewind();
        的for(int i = 0; I<大小; ++ I){
            浮动Y = YS [I]
            浮法X = XS [I]
            // Calculator.log(路径+ X +''+ Y);
            如果(Y == Y){//!NaN的
                如果(第一){
                    path.moveTo(X,Y);
                    第一= FALSE;
                } 其他 {
                    path.lineTo(X,Y);
                }
            } 其他 {
                第一= TRUE;
            }
        }
        返回路径;
    }

    私有静态最终浮动NTICKS = 15;

    私有静态浮动stepFactor(浮点W){
        浮动F = 1;
        而(W / F> NTICKS){
            F * = 10;
        }
        而(W / F< NTICKS / 10){
            的f / = 10;
        }
        浮动R = W / F;
        如果(R< NTICKS / 5){
            返回F / 5;
        }否则,如果(R< NTICKS / 2){
            返回的f / 2;
        } 其他 {
            返回F;
        }
    }

    私有静态StringBuilder的B =新的StringBuilder();
    私有静态的char [] buf中=新的字符[20];

    私有静态StringBuilder的格式(浮点FV){
        INT POS = 0;
        布尔addDot = FALSE;
        INT V = Math.round(FV * 100);
        布尔isNeg = V< 0;
        V = isNeg? -v:伏;
        对(INT I = 0; I&2 ++ⅰ){
            INT位= v%的10;
            体积/ = 10;
            如果(数字!= 0 || addDot){
                BUF [POS +] =(char)的('0'+数字);
                addDot =真;
            }
        }
        如果(addDot){
            BUF [POS +] ='';
        }
        如果(V == 0){
            BUF [POS +] ='0';
        }
        而(ⅴ!= 0){
            的buf [POS ++] =(char)的('0'+(v%的10));
            体积/ = 10;
        }
        如果(isNeg){
            的buf [POS ++] =' - ';
        }
        b.setLength(0);
        在b.append(BUF,0,POS);
        b.reverse();
        返回b;
    }

    私人无效drawGraph(帆布油画){
        长T1 = System.currentTimeMillis的();
        漂浮其minX = currentX  -  gwidth / 2;
        浮MAXX =其minX + gwidth;
        浮ywidth = gwidth *高度/宽度;
        浮MINY = currentY  -  ywidth / 2;
        浮MAXY = MINY + ywidth;
        如果(MINY< boundMinY || MAXY> boundMaxY){
            浮halfw = ywidth / 2;
            boundMinY = MINY  -  halfw;
            boundMaxY = MAXY + halfw;
            clearAllGraph();
        }

        canvas.drawColor(0xff000000);

        paint.setStrokeWidth(0);
        paint.setAntiAlias​​(假);
        paint.setStyle(Paint.Style.STROKE);

        最终浮动H2 =高度/ 2F;
        最终浮动规模=宽/ gwidth;

        浮X0 = -minX *规模;
        布尔drawYAxis = TRUE;
        如果(X0α25){
            X0 = 25;
            // drawYAxis = FALSE;
        }否则如果(X0>宽度 -  3){
            X0 =宽度 -  3;
            // drawYAxis = FALSE;
        }
        浮Y0 = MAXY *规模;
        如果(Y0 3;){
            Y0 = 3;
        }否则如果(Y0>高度 -  15){
            Y0 =身高 -  15;
        }

        最终浮动tickSize = 3;
        最终浮动Y2 = Y0 + tickSize;
        paint.setColor(COL_GRID);
        浮步= stepFactor(gwidth);
        浮动V =((INT)(其minX /步))*步骤;
        textPaint.setColor(COL_TEXT);
        textPaint.setTextSize(12);
        textPaint.setTextAlign(Paint.Align.CENTER);
        浮stepScale =步*规模;
        为(浮动X =(V  - 其minX)*规模,X< =宽度; X + = stepScale,V + =步){
            canvas.drawLine(X,0中,x,高度,漆);
            如果(( -  001F<!V&功放;&安培; V< .001f)){
                StringBuilder的B =格式(五);
                canvas.drawText(二,0,b.length个()中,x,Y2 + 10,textPaint);
            }
        }

        最终浮动X1 = X0  -  tickSize;
        V =((int)的(MINY /步骤))*步骤;
        textPaint.setTextAlign(Paint.Align.RIGHT);
        为(浮动Y =高度 - (五 -  MINY)*标y与其所连接; = 0; Y  -  = stepScale,V + =步骤){
            canvas.drawLine(0,Y,宽度,Y,油漆);
            如果(( -  001F<!V&功放;&安培; V< .001f)){
                StringBuilder的B =格式(五);
                canvas.drawText(B,0,b.length个(),X1,Y + 4,textPaint);
            }
        }

        paint.setColor(COL_AXIS);
        如果(drawYAxis){
            canvas.drawLine(X0,0,X0,高度,油漆);
        }
        canvas.drawLine(0,Y0,宽度,Y0,漆);

        matrix.reset();
        。矩阵preTranslate(-currentX,-currentY);
        matrix.postScale(规模,-scale);
        matrix.postTranslate(宽度/ 2,高度/ 2);

        paint.setStrokeWidth(0);
        paint.setAntiAlias​​(假);

        INT N = Math.min(funcs.size(),GRAPHS_SIZE);
        的for(int i = 0;我n种; ++ I){
            computeGraph(funcs.get(ⅰ),其minX,MAXX,boundMinY,boundMaxY,
                    图表[I]);
            路径path = graphToPath(图[I]);
            path.transform(矩阵);
            paint.setColor(COL_GRAPH [I]);
            canvas.drawPath(路径,油漆);
        }
        lastMinX =其minX;
    }

    私人布尔canZoomIn(){
        返回gwidth> 1F;
    }

    私人布尔canZoomOut(){
        返回gwidth< 50;
    }

    私人无效invalidateGraphs(){
        clearAllGraph();
        boundMinY = boundMaxY = 0;
        无效();
    }

    @覆盖
    公共布尔的onTouchEvent(MotionEvent事件){
        返回touchHandler!= NULL? touchHandler.onTouchEvent(事件):超
                .onTouchEvent(事件);
    }

    公共无效onTouchDown(浮X,浮动Y){
        zoomController.setVisible(真正的);
        如果(!scroller.isFinished()){
            scroller.abortAnimation();
        }
        lastTouchX = X;
        lastTouchY = Y;
    }

    公共无效onTouchMove(浮X,浮动Y){
        浮DELTAX = X  -  lastTouchX;
        漂浮移动deltaY = Y  -  lastTouchY;
        如果(DELTAX&所述-1 || DELTAX→1 ||移动deltaY&所述-1 ||移动deltaY→1){
            滚动(-deltaX,移动deltaY);
            lastTouchX = X;
            lastTouchY = Y;
            无效();
        }
    }

    公共无效onTouchUp(浮X,浮动Y){
        最终浮动规模=宽/ gwidth;
        浮SX = -touchHandler.velocityTracker.getXVelocity();
        浮SY = touchHandler.velocityTracker.getYVelocity();
        最终浮动ASX = Math.abs(SX);
        最终浮动ASY = Math.abs(SY);
        如果(ASX< ASY / 3){
            SX = 0;
        }否则如果(ASY< ASX / 3){
            SY = 0;
        }
        scroller.fling(Math.round(currentX *标度),
                Math.round(currentY *等级),Math.round(SX),Math.round(SY)
                -10000,10000,-10000,10000);
        无效();
    }

    公共无效onTouchZoomDown(浮动X1,Y1浮球,浮球X2,浮动Y2){
        zoomTracker.start(gwidth,X1,Y1,X2,Y2);
    }

    公共无效onTouchZoomMove(浮动X1,Y1浮球,浮球X2,浮动Y2){
        如果(!zoomTracker.update(X1,Y1,X2,Y2)){
            返回;
        }
        浮targetGwidth = zoomTracker.value;
        如果(targetGwidth> .25f&安培;&安培; targetGwidth&所述; 200){
            gwidth = targetGwidth;
        }
        invalidateGraphs();
    }

    私人无效滚动(浮动DELTAX,漂浮移动deltaY){
        最终浮动规模= gwidth /宽;
        浮DX = DELTAX *规模;
        浮DY =移动deltaY *规模;
        最终浮动ADX = Math.abs(DX);
        最终浮动安以轩= Math.abs(DY);
        如果(ADX<安以轩/ 3){
            DX = 0;
        }否则如果(安以轩< ADX / 3){
            DY = 0;
        }
        currentX + = DX;
        currentY + = DY;
    }
}
 

XML编辑器的错误日志

 显示java.lang.NullPointerException
    在android.widget.ZoomButtonsController.createContainer(ZoomButtonsController.java:266)
    在android.widget.ZoomButtonsController< INIT>(ZoomButtonsController.java:212)
    在calculator.GraphView< INIT>(GraphView.java:43)
    在sun.reflect.NativeConstructorAccessorImpl.newInstance0(在sun.reflect.NativeConstructorAccessorImpl.newInstance(在sun.reflect.DelegatingConstructorAccessorImpl.newInstance(在java.lang.reflect.Constructor.newInstance(在com.android.ide.eclipse.adt.internal.editors.layout.ProjectCallback.instantiateClass(ProjectCallback.java:422)
    在com.android.ide.eclipse.adt.internal.editors.layout.ProjectCallback.loadView(ProjectCallback.java:179)
    在android.view.BridgeInflater.loadCustomView(BridgeInflater.java:207)
    在android.view.BridgeInflater.createViewFromTag(BridgeInflater.java:135)
    在android.view.LayoutInflater.rInflate_Original(LayoutInflater.java:746)
    在android.view.LayoutInflater_Delegate.rInflate(LayoutInflater_Delegate.java:64)
    在android.view.LayoutInflater.rInflate(LayoutInflater.java:718)
    在android.view.LayoutInflater.inflate(LayoutInflater.java:489)
    在android.view.LayoutInflater.inflate(LayoutInflater.java:372)
 

解决方案

isInEditMode()应内部的自定义视图构造函数中使用。 试试下面的code:

 公共类GraphView扩展视图实现绘图
        {

         公共GraphView(上下文的背景下,ATTRS的AttributeSet){
                超(背景下,ATTRS);
                如果(!isInEditMode())
                 的init(上下文);
            }

            公共GraphView(上下文的背景下){
                超(上下文);
               如果(!isInEditMode()){
                touchHandler =新TouchHandler(本);
                的init(上下文);
              }
            }
 

I must edit a software that have a custom view, when I try to edit layout xml, Eclipse says me:

Use View.isInEditMode() in your custom views to skip code when shown in Eclipse

But I have no idea about how and where I must use isInEditMode() in the app

My xml file is

<?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>

And my GraphView is

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;
    }
}

The error Log of the XML editor

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)

解决方案

isInEditMode()should be used inside the Custom View constructor. Try the following code:

     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);
              }
            }

这篇关于如何使用isInEditMode(),看看在编辑器中使用自定义视图布局的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆