私は Android プログラミングの初心者と見なされています。したがって、明らかな見落としがある場合は、ご容赦ください。
大規模なアプリケーションの一部として、AndroidPlot を使用してグラフ ページを実装しようとしています。今のところ、テストのみを行っているため、グラフに手動で入力した値を使用しています。グラフ ページにズームとパンを実装するために、AndroidPlot Web サイトのチュートリアルを使用しました。ただし、エミュレーターと実際の電話で、タッチ イベントが発生するたびに。
グラフ ページのコードは次のとおりです。
public class Graph extends Activity implements OnTouchListener{
Campaign_Db myCamp = new Campaign_Db(this);
private XYPlot myXY;
private PointF minXY;
private PointF maxXY;
ArrayList<String> array_date;
ArrayList<Integer> array_cap;
Array arr_date;
Integer[] arr_cap;
float x,y;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.graph);
myXY = (XYPlot) findViewById(R.id.myXYplot);
myXY.setOnTouchListener(this);
getdata();
// Create a couple arrays of y-values to plot:
Number[] series1Numbers = {978307200, // 2001
1009843200, // 2002
1041379200, // 2003
1072915200, // 2004
1104537600 // 2005
};
Number[] series2 = {1,2,3,4,5};
// Turn the above arrays into XYSeries':
XYSeries series1 = new SimpleXYSeries(
Arrays.asList(series1Numbers),
Arrays.asList(series2),
"cups of water");
// Create a formatter to use for drawing a series using LineAndPointRenderer:
@SuppressWarnings("deprecation")
LineAndPointFormatter series1Format = new LineAndPointFormatter(
Color.rgb(0, 200, 0), // line color
Color.rgb(0, 100, 0), // point color
null); // fill color (none)
// add a new series' to the xyplot:
myXY.addSeries(series1, series1Format);
// reduce the number of range labels
myXY.setTicksPerRangeLabel(1);
myXY.setTicksPerDomainLabel(2);
// get rid of decimal points in our range labels:
myXY.setRangeValueFormat(new DecimalFormat("0"));
// customize our domain/range labels
myXY.setDomainLabel("Date");
myXY.setRangeLabel("# of cups");
myXY.setDomainValueFormat(new Format() {
/**
*
*/
private static final long serialVersionUID = 1L;
// create a simple date format that draws on the year portion of our timestamp.
// see http://download.oracle.com/javase/1.4.2/docs/api/java/text/SimpleDateFormat.html
// for a full description of SimpleDateFormat.
private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy");
@Override
public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) {
// because our timestamps are in seconds and SimpleDateFormat expects milliseconds
// we multiply our timestamp by 1000:
long timestamp = ((Number) obj).longValue() * 1000;
Date date = new Date(timestamp);
return dateFormat.format(date, toAppendTo, pos);
}
@Override
public Object parseObject(String string, ParsePosition position) {
// TODO Auto-generated method stub
return null;
}
});
// by default, AndroidPlot displays developer guides to aid in laying out your plot.
// To get rid of them call disableAllMarkup():
myXY.disableAllMarkup();
myXY.redraw();
//Set of internal variables for keeping track of the boundaries
myXY.calculateMinMaxVals();
minXY=new PointF(myXY.getCalculatedMinX().floatValue(),myXY.getCalculatedMinY().floatValue());
maxXY=new PointF(myXY.getCalculatedMaxX().floatValue(),myXY.getCalculatedMaxY().floatValue());
}
// 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;
public boolean onTouch(View view, MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: // Start gesture
firstFinger = new PointF(event.getX(), event.getY());
mode = ONE_FINGER_DRAG;
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
//When the gesture ends, a thread is created to give inertia to the scrolling and zoom
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);
myXY.setDomainBoundaries(minXY.x, maxXY.x, BoundaryMode.AUTO);
myXY.redraw();
}
}
}, 0);
case MotionEvent.ACTION_POINTER_DOWN: // second finger
distBetweenFingers = spacing(event);
// the distance check is done to avoid false alarms
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)/myXY.getHeight();
if (lastZooming<0)
lastZooming=1/(1-lastZooming);
else
lastZooming+=1;
zoom(lastZooming);
myXY.setDomainBoundaries(minXY.x, maxXY.x, BoundaryMode.AUTO);
myXY.redraw();
} else if (mode == TWO_FINGERS_DRAG) {
float oldDist =distBetweenFingers;
distBetweenFingers=spacing(event);
lastZooming=oldDist/distBetweenFingers;
zoom(lastZooming);
myXY.setDomainBoundaries(minXY.x, maxXY.x, BoundaryMode.AUTO);
myXY.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 / myXY.getWidth();
float offset = pan * step;
minXY.x+= offset;
maxXY.x+= offset;
}
private float spacing(MotionEvent event) {
x = event.getX(0) - event.getX(1);
y = event.getY(0) - event.getY(1);
return FloatMath.sqrt(x * x + y * y);
}
public boolean onInterceptTouchEvent(MotionEvent ev) {
try {
return super.onTouchEvent(ev);
} catch (IllegalArgumentException e) {
e.printStackTrace();
return false;
} catch (ArrayIndexOutOfBoundsException e) {
e.printStackTrace();
return false;
}
}
}
そして、ここにエラーのlogcatがあります
06-11 14:59:31.764: E/AndroidRuntime(2203): FATAL EXCEPTION: main
06-11 14:59:31.764: E/AndroidRuntime(2203): java.lang.IllegalArgumentException: pointerIndex out of range
06-11 14:59:31.764: E/AndroidRuntime(2203): at android.view.MotionEvent.nativeGetAxisValue(Native Method)
06-11 14:59:31.764: E/AndroidRuntime(2203): at android.view.MotionEvent.getX(MotionEvent.java:1974)
06-11 14:59:31.764: E/AndroidRuntime(2203): at com.example.damavand.Graph.spacing(Graph.java:231)
06-11 14:59:31.764: E/AndroidRuntime(2203): at com.example.damavand.Graph.onTouch(Graph.java:176)
06-11 14:59:31.764: E/AndroidRuntime(2203): at android.view.View.dispatchTouchEvent(View.java:5559)
06-11 14:59:31.764: E/AndroidRuntime(2203): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2058)
06-11 14:59:31.764: E/AndroidRuntime(2203): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1827)
06-11 14:59:31.764: E/AndroidRuntime(2203): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2058)
06-11 14:59:31.764: E/AndroidRuntime(2203): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1827)
06-11 14:59:31.764: E/AndroidRuntime(2203): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2058)
06-11 14:59:31.764: E/AndroidRuntime(2203): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1827)
06-11 14:59:31.764: E/AndroidRuntime(2203): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2058)
06-11 14:59:31.764: E/AndroidRuntime(2203): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1827)
06-11 14:59:31.764: E/AndroidRuntime(2203): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2058)
06-11 14:59:31.764: E/AndroidRuntime(2203): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1827)
06-11 14:59:31.764: E/AndroidRuntime(2203): at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1931)
06-11 14:59:31.764: E/AndroidRuntime(2203): at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1390)
06-11 14:59:31.764: E/AndroidRuntime(2203): at android.app.Activity.dispatchTouchEvent(Activity.java:2364)
06-11 14:59:31.764: E/AndroidRuntime(2203): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1879)
06-11 14:59:31.764: E/AndroidRuntime(2203): at android.view.View.dispatchPointerEvent(View.java:5766)
06-11 14:59:31.764: E/AndroidRuntime(2203): at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:2890)
06-11 14:59:31.764: E/AndroidRuntime(2203): at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2466)
06-11 14:59:31.764: E/AndroidRuntime(2203): at android.view.ViewRootImpl.processInputEvents(ViewRootImpl.java:845)
06-11 14:59:31.764: E/AndroidRuntime(2203): at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2475)
06-11 14:59:31.764: E/AndroidRuntime(2203): at android.os.Handler.dispatchMessage(Handler.java:99)
06-11 14:59:31.764: E/AndroidRuntime(2203): at android.os.Looper.loop(Looper.java:137)
06-11 14:59:31.764: E/AndroidRuntime(2203): at android.app.ActivityThread.main(ActivityThread.java:4441)
06-11 14:59:31.764: E/AndroidRuntime(2203): at java.lang.reflect.Method.invokeNative(Native Method)
06-11 14:59:31.764: E/AndroidRuntime(2203): at java.lang.reflect.Method.invoke(Method.java:511)
06-11 14:59:31.764: E/AndroidRuntime(2203): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
06-11 14:59:31.764: E/AndroidRuntime(2203): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
06-11 14:59:31.764: E/AndroidRuntime(2203): at dalvik.system.NativeStart.main(Native Method)
私は周りを読んでいて、何も役に立ちませんでした。これは、モーション イベントに関して私がひどいので、考えられる解決策を見逃した可能性があるためです。ヘルプやガイダンスをお寄せいただきありがとうございます。