的Android / Java的创建一个辅助类来创建图形 [英] Android/Java creating a helper class to create graphs
问题描述
目标:
要为图形生成创建一个辅助类
To create a helper class for graph generation
背景:
我有3个片段,每个收集一些传感器数据(加速度计,陀螺仪,旋转),并绘制使用GraphView图。这里是code是什么样子的那些片段(在此code当前工作正常):
I have 3 fragments that each collect some sensor data (accelerometer, gyroscope, rotation) and plots a graph using GraphView. Here is what the code looks like for one of those fragments (this code currently works correctly):
public class GyroscopeFragment extends Fragment implements SensorEventListener {
private final short TYPE_GYROSCOPE = Sensor.TYPE_GYROSCOPE;
private final short POLL_FREQUENCY = 100; //in milliseconds
private final short MAX_POINTS_DISPLAYED = 50;
private SensorManager sensorManager;
private Sensor sensor;
private Sensor gyroscope;
private long lastUpdate = -1;
float curGyroX;
float curGyroY;
float curGyroZ;
private LineGraphSeries<DataPoint> gyroXSeries;
private LineGraphSeries<DataPoint> gyroYSeries;
private LineGraphSeries<DataPoint> gyroZSeries;
private double graphXTime = 1d;
public GyroscopeFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_gyroscope, container, false);
//Set the nav drawer item highlight
MainActivity mainActivity = (MainActivity) getActivity();
mainActivity.navigationView.setCheckedItem(R.id.nav_gyroscope);
//Set actionbar title
mainActivity.setTitle("Gyroscope");
//Sensor manager
sensorManager = (SensorManager) getContext().getSystemService(Context.SENSOR_SERVICE);
gyroscope = (Sensor) sensorManager.getDefaultSensor(TYPE_GYROSCOPE);
return view;
}
@Override
public void onResume() {
super.onResume();
sensorManager.registerListener(this, gyroscope, SensorManager.SENSOR_DELAY_FASTEST);
//Create graph
GraphView gyroGraph = (GraphView) getView().findViewById(R.id.gyroGraph);
gyroGraph.getLegendRenderer().setVisible(true);
gyroGraph.getLegendRenderer().setFixedPosition(0,0);
gyroGraph.getGridLabelRenderer().setHighlightZeroLines(false);
gyroXSeries = new LineGraphSeries<DataPoint>();
gyroYSeries = new LineGraphSeries<DataPoint>();
gyroZSeries = new LineGraphSeries<DataPoint>();
gyroXSeries.setTitle("X");
gyroYSeries.setTitle("Y");
gyroZSeries.setTitle("Z");
gyroXSeries.setColor(Color.RED);
gyroYSeries.setColor(Color.GREEN);
gyroZSeries.setColor(Color.BLUE);
gyroGraph.addSeries(gyroXSeries);
gyroGraph.addSeries(gyroYSeries);
gyroGraph.addSeries(gyroZSeries);
gyroGraph.getViewport().setYAxisBoundsManual(true);
gyroGraph.getViewport().setMinY(-10);
gyroGraph.getViewport().setMaxY(10);
gyroGraph.getViewport().setXAxisBoundsManual(true);
gyroGraph.getViewport().setMinX(0);
gyroGraph.getViewport().setMaxX(MAX_POINTS_DISPLAYED);
}
@Override
public void onPause() {
super.onPause();
sensorManager.unregisterListener(this);
}
@Override
public void onDestroy() {
super.onDestroy();
sensorManager.unregisterListener(this);
}
@Override
public void onLowMemory() {
super.onLowMemory();
sensorManager.unregisterListener(this);
}
@Override
public void onSensorChanged(SensorEvent event) {
sensor = event.sensor;
curGyroX = event.values[0];
curGyroY = event.values[1];
curGyroZ = event.values[2];
long curTime = System.currentTimeMillis();
long diffTime = (curTime - lastUpdate);
// only allow one update every POLL_FREQUENCY.
if (diffTime > POLL_FREQUENCY) {
lastUpdate = curTime;
graphXTime += 1d;
gyroXSeries.appendData(new DataPoint(graphXTime, curGyroX), true, MAX_POINTS_DISPLAYED);
gyroYSeries.appendData(new DataPoint(graphXTime, curGyroY), true, MAX_POINTS_DISPLAYED);
gyroZSeries.appendData(new DataPoint(graphXTime, curGyroZ), true, MAX_POINTS_DISPLAYED);
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
//Safe not to implement
}
}
我发现,在整个3个片段,我在 onResume
重复了很多图形生成code,所以我想创建一个GraphHelper类,我可以实例做图形创作,仅为不必更改code在一个地方,如果我想改变一个图形外观的利益。不过,我是新来的Java所以遇到问题缠绕我的头围绕创建这个新类。
I find that across the 3 fragments I am repeating a lot of the graph generation code in onResume
so I wanted to create a GraphHelper class that I can instantiate to do the graph creation, with the benefit of only having to change code in one place if I wanted to alter the look of a graph. However, I am new to Java so having trouble wrapping my head around creating this new class.
尝试性解决方案:
我已成功地想出以下类以试图解决的问题:
I have managed to come up with the following class in an attempt to solve the problem:
public class GraphHelper {
private final GraphView graph;
private final LineGraphSeries<DataPoint> xSeries;
private final LineGraphSeries<DataPoint> ySeries;
private final LineGraphSeries<DataPoint> zSeries;
public GraphHelper(GraphView graph, LineGraphSeries<DataPoint> xSeries,
LineGraphSeries<DataPoint> ySeries, LineGraphSeries<DataPoint> zSeries, short maxDisplayed){
this.graph = graph;
this.xSeries = xSeries;
this.ySeries = ySeries;
this.zSeries = zSeries;
graph.getLegendRenderer().setVisible(true);
graph.getLegendRenderer().setFixedPosition(0, 0);
graph.getGridLabelRenderer().setHighlightZeroLines(false);
xSeries = new LineGraphSeries<DataPoint>();
ySeries = new LineGraphSeries<DataPoint>();
zSeries = new LineGraphSeries<DataPoint>();
xSeries.setTitle("X");
ySeries.setTitle("Y");
zSeries.setTitle("Z");
xSeries.setColor(Color.RED);
ySeries.setColor(Color.GREEN);
zSeries.setColor(Color.BLUE);
graph.addSeries(xSeries);
graph.addSeries(ySeries);
graph.addSeries(zSeries);
graph.getViewport().setYAxisBoundsManual(true);
graph.getViewport().setMinY(-10);
graph.getViewport().setMaxY(10);
graph.getViewport().setXAxisBoundsManual(true);
graph.getViewport().setMinX(0);
graph.getViewport().setMaxX(maxDisplayed);
}
}
和改变了我的片段 onResume
看起来像这样(其他一切都是一样的):
And have changed my fragment onResume
to look like this (everything else is the same):
@Override
public void onResume() {
super.onResume();
sensorManager.registerListener(this, gyroscope, SensorManager.SENSOR_DELAY_FASTEST);
//Create graph
GraphView gyroGraph = (GraphView) getView().findViewById(R.id.gyroGraph);
new GraphHelper(gyroGraph, gyroXSeries, gyroYSeries, gyroZSeries, MAX_POINTS_DISPLAYED);
}
问题1:
我收到以下错误,每当我尝试查看图片断:
I am getting the following error whenever I try to view the graph fragment:
java.lang.NullPointerException: Attempt to invoke virtual method 'void com.jjoe64.graphview.series.LineGraphSeries.appendData(com.jjoe64.graphview.series.DataPointInterface, boolean, int)' on a null object reference
这是指 onSensorChanged
方法,其中我试图将数据追加到系列。它似乎不知道什么 gyroXSeries
是因为我将它添加到助手里的图形。
This is referring to the onSensorChanged
method where I'm trying to append data to the series. It doesn't seem to know what gyroXSeries
is because I'm adding it to the graph within the helper.
问题2:
目前我声明了 gyroXSeries
主片段类,以及辅助类的顶部,同时也创造了新的 LineGraphSeries
对象在助手的构造函数。有没有办法减少这种code的重复的方式?
Currently I'm declaring gyroXSeries
in the main fragment class, as well as the top of the helper class, and also creating a new LineGraphSeries
object in the helpers constructor. Is there a way to reduce the repetition of this code?
修改
在回应下面的评论,我做了如下的变化和新的GraphHelper类看起来是这样的:
In response to the comments below, I made the following changes and the new GraphHelper class looks like this:
public class GraphHelper {
private final GraphView graph;
private final LineGraphSeries<DataPoint> xSeries;
private final LineGraphSeries<DataPoint> ySeries;
private final LineGraphSeries<DataPoint> zSeries;
public GraphHelper(GraphView graph, LineGraphSeries<DataPoint> xSeries,
LineGraphSeries<DataPoint> ySeries, LineGraphSeries<DataPoint> zSeries, short maxDisplayed){
this.graph = graph;
this.xSeries = xSeries;
this.ySeries = ySeries;
this.zSeries = zSeries;
graph.getLegendRenderer().setVisible(true);
graph.getLegendRenderer().setFixedPosition(0, 0);
graph.getGridLabelRenderer().setHighlightZeroLines(false);
xSeries.setTitle("X");
ySeries.setTitle("Y");
zSeries.setTitle("Z");
xSeries.setColor(Color.RED);
ySeries.setColor(Color.GREEN);
zSeries.setColor(Color.BLUE);
graph.addSeries(xSeries);
graph.addSeries(ySeries);
graph.addSeries(zSeries);
graph.getViewport().setYAxisBoundsManual(true);
graph.getViewport().setMinY(-10);
graph.getViewport().setMaxY(10);
graph.getViewport().setXAxisBoundsManual(true);
graph.getViewport().setMinX(0);
graph.getViewport().setMaxX(maxDisplayed);
}
}
陀螺仪片段是和原来一样,用改变 onResume
我上面
这将导致以下错误:
致命异常:主要
工艺:net.binarysea.sensorload,PID:25997
显示java.lang.NullPointerException:尝试在空对象引用调用虚拟方法无效com.jjoe64.graphview.series.LineGraphSeries.setTitle(java.lang.String中)'
在net.binarysea.sensorload.GraphHelper(GraphHelper.java:30)
在net.binarysea.sensorload.GyroscopeFragment.onResume(GyroscopeFragment.java:73)
在android.support.v4.app.Fragment.performResume(Fragment.java:2005)
在android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1108)
在android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1248)
在android.support.v4.app.BackStackRecord.run(BackStackRecord.java:738)
在android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1613)
在android.support.v4.app.FragmentManagerImpl $ 1.run(FragmentManager.java:517)
在android.os.Handler.handleCallback(Handler.java:739)
在android.os.Handler.dispatchMessage(Handler.java:95)
在android.os.Looper.loop(Looper.java:148)
在android.app.ActivityThread.main(ActivityThread.java:5417)
在java.lang.reflect.Method.invoke(本机方法)
在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:726)
在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
FATAL EXCEPTION: main Process: net.binarysea.sensorload, PID: 25997 java.lang.NullPointerException: Attempt to invoke virtual method 'void com.jjoe64.graphview.series.LineGraphSeries.setTitle(java.lang.String)' on a null object reference at net.binarysea.sensorload.GraphHelper.(GraphHelper.java:30) at net.binarysea.sensorload.GyroscopeFragment.onResume(GyroscopeFragment.java:73) at android.support.v4.app.Fragment.performResume(Fragment.java:2005) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1108) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1248) at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:738) at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1613) at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:517) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5417) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
推荐答案
您的图形辅助类改成这样。
Change your graph helper class to this.
public class GraphHelper {
public GraphHelper(GraphView graph, LineGraphSeries<DataPoint> xSeries,
LineGraphSeries<DataPoint> ySeries, LineGraphSeries<DataPoint> zSeries, short maxDisplayed){
graph.getLegendRenderer().setVisible(true);
graph.getLegendRenderer().setFixedPosition(0, 0);
graph.getGridLabelRenderer().setHighlightZeroLines(false);
xSeries.setTitle("X");
ySeries.setTitle("Y");
zSeries.setTitle("Z");
xSeries.setColor(Color.RED);
ySeries.setColor(Color.GREEN);
zSeries.setColor(Color.BLUE);
graph.addSeries(xSeries);
graph.addSeries(ySeries);
graph.addSeries(zSeries);
graph.getViewport().setYAxisBoundsManual(true);
graph.getViewport().setMinY(-10);
graph.getViewport().setMaxY(10);
graph.getViewport().setXAxisBoundsManual(true);
graph.getViewport().setMinX(0);
graph.getViewport().setMaxX(maxDisplayed);
}
}
这样称呼它:
@Override
public void onResume() {
super.onResume();
sensorManager.registerListener(this, gyroscope, SensorManager.SENSOR_DELAY_FASTEST);
//Create graph
GraphView gyroGraph = (GraphView) getView().findViewById(R.id.gyroGraph);
gyroXSeries = new LineGraphSeries<DataPoint>();
gyroYSeries = new LineGraphSeries<DataPoint>();
gyroZSeries = new LineGraphSeries<DataPoint>();
new GraphHelper(gyroGraph, gyroXSeries, gyroYSeries, gyroZSeries, MAX_POINTS_DISPLAYED);
}
另外这是做Java中的帮手更合适的方式:
Also this is a more proper way to do a helper in java:
public class GraphHelper {
public GraphHelper() { }
public static void initializeGraph(GraphView graph, LineGraphSeries<DataPoint> xSeries,
LineGraphSeries<DataPoint> ySeries, LineGraphSeries<DataPoint> zSeries, short maxDisplayed){
graph.getLegendRenderer().setVisible(true);
graph.getLegendRenderer().setFixedPosition(0, 0);
graph.getGridLabelRenderer().setHighlightZeroLines(false);
xSeries.setTitle("X");
ySeries.setTitle("Y");
zSeries.setTitle("Z");
xSeries.setColor(Color.RED);
ySeries.setColor(Color.GREEN);
zSeries.setColor(Color.BLUE);
graph.addSeries(xSeries);
graph.addSeries(ySeries);
graph.addSeries(zSeries);
graph.getViewport().setYAxisBoundsManual(true);
graph.getViewport().setMinY(-10);
graph.getViewport().setMaxY(10);
graph.getViewport().setXAxisBoundsManual(true);
graph.getViewport().setMinX(0);
graph.getViewport().setMaxX(maxDisplayed);
}
}
这样,你没有那个的等待垃圾回收随机对象。
要叫它是:
This way you don't have a random object that's waiting to be garbage collected. To call it use:
GraphHelper.initializeGraph(...)
这篇关于的Android / Java的创建一个辅助类来创建图形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!