Android / Java创建帮助类来创建图形

时间:2016-02-29 17:52:23

标签: java android class android-fragments android-graphview

目标:

为图生成创建辅助类

背景

我有3个片段,每个片段收集一些传感器数据(加速度计,陀螺仪,旋转)并使用GraphView绘制图形。以下是其中一个片段的代码(此代码当前正常工作):

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重复了很多图形生成代码,所以我想创建一个GraphHelper类,我可以实例化它来创建图形,只有如果我想改变图形的外观,可以在一个地方更改代码。但是,我是Java的新手,因此无法创建这个新类。

尝试解决方案:

我设法提出以下课程以试图解决问题:

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更改为这样(其他一切都相同):

@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:

每当我尝试查看图片片段时,我都会收到以下错误:

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

这是指{I}尝试将数据附加到系列中的onSensorChanged方法。它似乎不知道gyroXSeries是什么,因为我将它添加到帮助程序中的图形中。

问题#2:

目前,我在主要的片段类中声明gyroXSeries,以及帮助程序类的顶部,并在帮助程序构造函数中创建新的LineGraphSeries对象。有没有办法减少这段代码的重复?

修改

在回应下面的评论时,我做了以下更改,新的GraphHelper类看起来像这样:

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:尝试调用虚方法&#39; void com.jjoe64.graphview.series.LineGraphSeries.setTitle(java.lang.String)&#39;在null对象引用上                                                                               在net.binarysea.sensorload.GraphHelper。(GraphHelper.java:30)                                                                               at 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)                                                                               at java.lang.reflect.Method.invoke(Native Method)                                                                               在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:726)                                                                               在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

1 个答案:

答案 0 :(得分:2)

将图形帮助程序类更改为此。

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中执行帮助的更合适的方法:

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

这样你就没有一个等待垃圾收集的随机对象。 要调用它:

GraphHelper.initializeGraph(...)