2015-12-09 2 views
0

Я новичок в Android, и я стараюсь, чтобы масштабировать диаграмму в моем приложении, но код, который я написал ниже, не работает из-за ошибки:Как я могу масштабировать график xroid?

java.lang.NullPointerException: Attempt to invoke virtual method (android.view.View$OnTouchListener)' on a null object reference. 

Я понятия не имею, как я мог исправить это в моем коде.

Заранее благодарим за помощь.

public class EcgChartActivity extends Activity implements OnTouchListener 
    { 


private PointF minXY; 
private PointF maxXY; 

//Class updating the data on the chart 
private class EcgUpdater implements Observer { 
    private final Plot plot; 

    public EcgUpdater(Plot plot) { 
     this.plot = plot; 
    } 

    @Override 
    public void update(Observable arg0, Object arg1) { 
     plot.redraw(); 
    } 
} 

private XYPlot ecgPlot; 
private EcgUpdater ecgUpdater; 
private Thread ecgPlotThread; 
private LinkedHashMap<Integer, ChannelData> allChannelsData; 
private EcgDataSource ecgDataSource; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_ecg_chart); 


    this.ecgPlot = (XYPlot) findViewById(R.id.ecg_plot); 

    this.ecgUpdater = new EcgUpdater(this.ecgPlot); 

    this.ecgDataSource = BaseApp.getApp().getEcgDataSource(); 

    this.ecgPlotThread = new Thread(this.ecgDataSource); 

    ecgPlot.setOnTouchListener(this); 



    ecgPlot.getGraphWidget().setTicksPerRangeLabel(1); 
    ecgPlot.getGraphWidget().setTicksPerDomainLabel(1); 
    ecgPlot.getGraphWidget().setRangeValueFormat(
      new DecimalFormat("#######")); 
    ecgPlot.getGraphWidget().setDomainValueFormat(
      new DecimalFormat("#######")); 
    ecgPlot.getGraphWidget().setRangeLabelWidth(25); 
    ecgPlot.setRangeLabel(""); 
    ecgPlot.setDomainLabel(""); 

    //Adding series to chart 

    EcgPlotSeries channel1 = new EcgPlotSeries(this.ecgDataSource, 0, "Channel 1", Color.RED); 
    this.ecgPlot.addSeries(channel1, channel1.getFormatter()); 

    EcgPlotSeries channel2 = new EcgPlotSeries(this.ecgDataSource, 1, "Channel 2", Color.BLUE); 
    this.ecgPlot.addSeries(channel2, channel2.getFormatter()); 

    ecgPlot.redraw(); 
    ecgPlot.calculateMinMaxVals(); 
    minXY=new PointF(ecgPlot.getCalculatedMinX().floatValue(),ecgPlot.getCalculatedMinY().floatValue()); 
    maxXY=new PointF(ecgPlot.getCalculatedMaxX().floatValue(),ecgPlot.getCalculatedMaxY().floatValue()); 


    BaseApp.getApp().getEcgDataSource().addObserver(this.ecgUpdater);  

} 


// Definition of the touch states 
static final int NONE = 0; 
static final int ONE_FINGER_DRAG = 1; 
static final int TWO_FINGERS_DRAG = 2; 
int mode = NONE; 

PointF firstFinger; 
float lastScrolling; 
float distBetweenFingers; 
float lastZooming; 


@Override 
public void onResume() { 
    // Uruchomienie wątku rysującego wykres 
    this.ecgPlotThread.start(); 
    super.onResume(); 
} 


@Override 
public void onPause() { 
    BaseApp.getApp().getEcgDataSource().stopThread(); 
    super.onPause(); 
} 



@Override 
    public boolean onTouch(View v, MotionEvent event) { 
     // TODO Auto-generated method stub 

     switch (event.getAction() & MotionEvent.ACTION_MASK) { 
     case MotionEvent.ACTION_DOWN: 
      firstFinger = new PointF(event.getX(), event.getY()); 
      mode = ONE_FINGER_DRAG; 
      break; 
     case MotionEvent.ACTION_UP: 
      break; 
     case MotionEvent.ACTION_POINTER_UP: 
      Timer t = new Timer(); 
       t.schedule(new TimerTask() { 

       @Override 
        public void run() { 
         while(Math.abs(lastScrolling)>1f || Math.abs(lastZooming-1)<1.01){ 
         lastScrolling*=.8; 
         scroll(lastScrolling); 
         lastZooming+=(1-lastZooming)*.2; 
         zoom(lastZooming); 
         ecgPlot.setDomainBoundaries(minXY.x, maxXY.x, BoundaryMode.AUTO); 
         ecgPlot.redraw(); 
        } 
        } 


      }, 0); 

      break; 

     case MotionEvent.ACTION_POINTER_DOWN: 
      distBetweenFingers = spacing(event); 
      if (distBetweenFingers > 5f) { 
       mode = TWO_FINGERS_DRAG; 
      } 
      break; 
     case MotionEvent.ACTION_MOVE: 
      if (mode == ONE_FINGER_DRAG) { 
       PointF oldFirstFinger=firstFinger; 
       firstFinger=new PointF(event.getX(), event.getY()); 
       lastScrolling=oldFirstFinger.x-firstFinger.x; 
       scroll(lastScrolling); 
       lastZooming=(firstFinger.y-oldFirstFinger.y)/ecgPlot.getHeight(); 
       if (lastZooming<0) 
        lastZooming=1/(1-lastZooming); 
       else 
        lastZooming+=1; 
       zoom(lastZooming); 
       ecgPlot.setDomainBoundaries(minXY.x, maxXY.x, BoundaryMode.AUTO); 
       ecgPlot.redraw(); 

      } else if (mode == TWO_FINGERS_DRAG) { 
       float oldDist =distBetweenFingers; 
       distBetweenFingers=spacing(event); 
       lastZooming=oldDist/distBetweenFingers; 
       zoom(lastZooming); 
       ecgPlot.setDomainBoundaries(minXY.x, maxXY.x, BoundaryMode.AUTO); 
       ecgPlot.redraw(); 
      } 
      break; 
     } 
     return true; 

    } 

    private void zoom(float scale) { 
     float domainSpan = maxXY.x - minXY.x; 
     float domainMidPoint = maxXY.x - domainSpan/2.0f; 
     float offset = domainSpan * scale/2.0f; 
     minXY.x=domainMidPoint- offset; 
     maxXY.x=domainMidPoint+offset; 
    } 

    private void scroll(float pan) { 
     float domainSpan = maxXY.x - minXY.x; 
     float step = domainSpan/ecgPlot.getWidth(); 
     float offset = pan * step; 
     minXY.x+= offset; 
     maxXY.x+= offset; 
    } 

    @SuppressLint("FloatMath") 
    private float spacing(MotionEvent event) { 
     float x = event.getX(0) - event.getX(1); 
     float y = event.getY(0) - event.getY(1); 
     return FloatMath.sqrt(x * x + y * y); 
    } 

}

Вход:

12-09 21:39:40.893: E/AndroidRuntime(3137): java.lang.RuntimeException:  Unable to start activity  ComponentInfo{com.example.ecganalyzer/com.example.ecganalyzer.activities.EcgChartActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.androidplot.xy.XYPlot.setOnTouchListener(android.view.View$OnTouchListener)' on a null object reference 
12-09 21:39:40.893: E/AndroidRuntime(3137):at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2331) 
12-09 21:39:40.893: E/AndroidRuntime(3137): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2391) 
12-09 21:39:40.893: E/AndroidRuntime(3137): at android.app.ActivityThread.access$800(ActivityThread.java:151) 
12-09 21:39:40.893: E/AndroidRuntime(3137):at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1309) 
12-09 21:39:40.893: E/AndroidRuntime(3137): at android.os.Handler.dispatchMessage(Handler.java:102) 
12-09 21:39:40.893: E/AndroidRuntime(3137): at android.os.Looper.loop(Looper.java:135) 
12-09 21:39:40.893: E/AndroidRuntime(3137): at android.app.ActivityThread.main(ActivityThread.java:5349) 
12-09 21:39:40.893: E/AndroidRuntime(3137): at java.lang.reflect.Method.invoke(Native Method) 
12-09 21:39:40.893: E/AndroidRuntime(3137): at java.lang.reflect.Method.invoke(Method.java:372) 
12-09 21:39:40.893: E/AndroidRuntime(3137): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:908) 
12-09 21:39:40.893: E/AndroidRuntime(3137): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:703) 
12-09 21:39:40.893: E/AndroidRuntime(3137): Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.androidplot.xy.XYPlot.setOnTouchListener(android.view.View$OnTouchListener)' on a null object reference 
12-09 21:39:40.893: E/AndroidRuntime(3137): at com.example.ecganalyzer.activities.EcgChartActivity.onCreate(EcgChartActivity.java:112)12-09 21:39:40.893: E/AndroidRuntime(3137): at android.app.Activity.performCreate(Activity.java:6020) 12-09 21:39:40.893: E/AndroidRuntime(3137): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)12-09 21:39:40.893: E/AndroidRuntime(3137):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2284)12-09 21:39:40.893: E/AndroidRuntime(3137): ... 10 more 

ответ

0

Катастрофа происходит на этой линии:

ecgPlot.setOnTouchListener(this); 

Это происходит потому, что переменная 'ecgPlot' равно нулю.

Он установлен на линии

this.ecgPlot = (XYPlot) findViewById(R.id.ecg_plot); 

Проверьте файл 'R.layout.activity_ecg_chart'. Похоже, у него нет мнения с id 'R.id.ecg_plot'

+0

Благодарим за ответ. Я проверил макет и на самом деле ошибся, что вы написали. Я исправил и начал снова, но произошли новые ошибки. Я не знаю, как я мог их исправить. Буду признателен за вашу помощь. – PurpleFrog

+0

Это мои новые ошибки: 'java.lang.IllegalArgumentException: pointerIndex вне диапазона и в android.view.MotionEvent.nativeGetAxisValue (собственный метод) android.view.MotionEvent.getX (MotionEvent.java:1983)' – PurpleFrog

+0

У вас есть проблемы с обработкой мультитач. У меня недостаточно опыта, чтобы помочь вам. Кроме того, эту ошибку следует задать в другом вопросе, но я предлагаю сначала прочитать больше примеров того, как работать с мультитач. – geNia

Смежные вопросы