如何缩放android xy绘图?
我是Android的初学者,我尝试在我的应用程序中缩放图表,但由于错误,我在下面编写的代码无法工作:如何缩放android xy绘图?,android,Android,我是Android的初学者,我尝试在我的应用程序中缩放图表,但由于错误,我在下面编写的代码无法工作: java.lang.NullPointerException: Attempt to invoke virtual method (android.view.View$OnTouchListener)' on a null object reference. 我不知道如何在代码中更正它 提前感谢你的帮助 public class EcgChartActivity extends Act
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);
}
碰撞发生在这条线路上:
ecgPlot.setOnTouchListener(this);
这是因为“ecgPlot”变量为空
它被设置在线路上
this.ecgPlot = (XYPlot) findViewById(R.id.ecg_plot);
检查您的“R.layout.activity\u ecg\u图表”文件。
看起来它没有id为“R.id.ecg\u plot”的视图谢谢您的回答。我检查了布局,实际上有一个你写的错误。我更正并重新开始,但出现了新的错误。我不知道,我怎样才能修复它们。感谢您的帮助。这是我的新错误:
java.lang.IllegalArgumentException:pointerIndex超出范围,位于android.view.MotionEvent.nativeGetAxisValue(本机方法)android.view.MotionEvent.getX(MotionEvent.java:1983)
您在处理多点触摸时遇到问题。我没有足够的经验来帮助你。另外,这个错误应该在另一个问题中提出,但我建议首先阅读更多关于如何使用多点触控的示例。
this.ecgPlot = (XYPlot) findViewById(R.id.ecg_plot);