的Andr​​oid / Java的创建一个辅助类来创建图形 [英] Android/Java creating a helper class to create graphs

查看:691
本文介绍了的Andr​​oid / Java的创建一个辅助类来创建图形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目标:

要为图形生成创建一个辅助类

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(...)

这篇关于的Andr​​oid / Java的创建一个辅助类来创建图形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆