java - Android Studio - MPAndroidChart 将用户输入添加到折线图

标签 java android android-studio user-input mpandroidchart

大家好,这是我第一次使用 MPandroidChart,目前我正在试验它以充分了解如何使用它及其功能。目前,我正在尝试使用用户输入的数据(通过 fragment )更新我的折线图。我已经看到一些关于堆栈溢出的类似问题,但是它们似乎都不适合我。

任何帮助将不胜感激。提前致谢。

注意:有一些重复的代码,因为我正在试验并试图找出不同的方法来寻找解决方案。

获取用户输入的MainFragment

public class Fragment1 extends Fragment {

EditText Input;
Button EnterVal;
public float userInput;

//Fragment1Listener activityCommander;

public interface Fragment1Listener{
    void sendInput(float value);
}

/*@Override
public void onAttach(Context context) {
    super.onAttach(context);
    try{
        activityCommander = (Fragment1Listener) getTargetFragment();
    }catch (ClassCastException e){
        throw new ClassCastException(context.toString() + "Must Implement FragmentListener");
    }
}*/

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment1, container, false);

    //@SuppressWarnings("all")

    Input = view.findViewById(R.id.Input);
    EnterVal = view.findViewById(R.id.button);


    EnterVal.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            String val = Input.getText().toString();

            if(val != null && val.length() > 0) {
                userInput = Float.valueOf(val);
                Input.setText("");
                /*if(activityCommander != null) {
                    activityCommander.sendInput(userInput);
                }*/
                Fragment1Listener listener = getListener();
                if(listener != null){
                    listener.sendInput(userInput);
                    Log.d("User Val", "Listener was successfull!");
                }
            }
        }
    });

    return view;
}

@Nullable
private Fragment1Listener getListener(){
    Fragment1Listener activityCommander;
    try{
        Fragment onInputSelected_Frag = getTargetFragment();
        if(onInputSelected_Frag != null){
            activityCommander = (Fragment1Listener) onInputSelected_Frag;
        }
        else{
            Activity onInputSelected_Act = getActivity();
            activityCommander = (Fragment1Listener) onInputSelected_Act;
        }
        return activityCommander;
    }catch(ClassCastException e){
        Log.e("Fragment Listener", "getListener: ClassCastException + " + e.getMessage());
    }
    return null;
}
}

MPandroidchart fragment (折线图)

public class Fragment2 extends Fragment implements Fragment1.Fragment1Listener{

private LineChart lineChart;
//public Fragment1 fragment1;

private ArrayList<ILineDataSet> DataSets = new ArrayList<>();
private LineDataSet lineDataSet5;
private ArrayList<Entry> userData = new ArrayList<>();
private LineData data = new LineData(DataSets);

@Override
public void sendInput(float value) {

    data = lineChart.getData();
    ILineDataSet xSet = data.getDataSetByIndex(0);

    data.addEntry(new Entry(xSet.getEntryCount(), value),0);

    //lineDataSet5.notifyDataSetChanged();
    //lineDataSets.add(lineDataSet5);
    data.notifyDataChanged();
    lineChart.notifyDataSetChanged();
    lineChart.invalidate();
    lineChart.moveViewToX(data.getEntryCount());
}

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment2, container, false);

    lineChart = view.findViewById(R.id.LineChart);

    //Enable Touch Gestures
    lineChart.setTouchEnabled(true);

    //We want also enable scaling and dragging
    lineChart.setDragEnabled(true);
    lineChart.setScaleEnabled(true);

    //Enable pinch zoom to avoid scaling x and y axis separately
    lineChart.setPinchZoom(true);

    //Double tap zoom to chart
    lineChart.setDoubleTapToZoomEnabled(true);

    //Alternate Background Color
    lineChart.setBackgroundColor(Color.parseColor("#2b2b2b"));

    ArrayList<String> xAXES = new ArrayList<>();
    ArrayList<Entry> yAXESsin = new ArrayList<>();
    ArrayList<Entry> yAXEScos = new ArrayList<>();
    ArrayList<Entry> yAXEStan = new ArrayList<>();
    ArrayList<Entry> random = new ArrayList<>();

    double x = 0;
    int numDataPoints = 1000;
    for(int i =0; i<numDataPoints; i++){
        float sinFunction = Float.parseFloat(String.valueOf(Math.sin(x)));
        float cosFunction = Float.parseFloat(String.valueOf(Math.cos(x)));
        float tanFunction = Float.parseFloat(String.valueOf(Math.tan(x)));
        x += 0.1;
        yAXESsin.add(new Entry(i, sinFunction));
        yAXEScos.add(new Entry(i, cosFunction));
        yAXEStan.add(new Entry(i, tanFunction));
        xAXES.add(i, String.valueOf(x));

        final int randomVal = getRandomNumber(-10, 10);
        float randomData = (float) randomVal;
        random.add(new Entry(i, randomData));
    }

    String[] xaxes = new String[xAXES.size()];
    for(int i =0; i<xAXES.size(); i++){
        xaxes[i] = xAXES.get(i).toString();
    }

    //Add user Input
    //@SuppressWarnings("all")
    //userInput = fragment1.getUserInput();
    //userData.add(new Entry(userData.size()+1, userInput));

    ArrayList<ILineDataSet> lineDataSets = new ArrayList<>();
    ArrayList<ILineDataSet> dataSets = new ArrayList<>();

    //Data Set 1

    LineDataSet lineDataSet1 = new LineDataSet(yAXEScos, "Cos");
    lineDataSet1.setAxisDependency(YAxis.AxisDependency.LEFT);
    lineDataSet1.setDrawCircles(false);
    lineDataSet1.setColor(Color.parseColor("#B71C1C"));
    lineDataSet1.setLineWidth(3f);
    lineDataSet1.setHighlightEnabled(true);
    lineDataSet1.setDrawHighlightIndicators(true);
    lineDataSet1.setHighLightColor(Color.parseColor("#FF4081"));
    lineDataSet1.setValueTextSize(10f);
    lineDataSet1.setValueTextColor(Color.WHITE);
    lineDataSet1.setFillAlpha(110);

    //Data Set 2

    LineDataSet lineDataSet2 = new LineDataSet(yAXESsin, "Sin");
    lineDataSet2.setAxisDependency(YAxis.AxisDependency.LEFT);
    lineDataSet2.setDrawCircles(false);
    lineDataSet2.setColor(Color.parseColor("#33bbff"));
    lineDataSet2.setLineWidth(3f);
    lineDataSet2.setHighlightEnabled(true);
    lineDataSet2.setDrawHighlightIndicators(true);
    lineDataSet2.setHighLightColor(Color.parseColor("#FFD600"));
    lineDataSet2.setValueTextSize(10f);
    lineDataSet2.setValueTextColor(Color.WHITE);
    lineDataSet2.setFillAlpha(110);

    //Data Set 3

    LineDataSet lineDataSet3 = new LineDataSet(yAXEStan, "Tan");
    lineDataSet3.setAxisDependency(YAxis.AxisDependency.LEFT);
    lineDataSet3.setDrawCircles(false);
    lineDataSet3.setColor(Color.parseColor("#FFD600"));
    lineDataSet3.setLineWidth(3f);
    lineDataSet3.setHighlightEnabled(true);
    lineDataSet3.setDrawHighlightIndicators(true);
    lineDataSet2.setHighLightColor(Color.parseColor("#FFD600"));
    lineDataSet2.setValueTextSize(10f);
    lineDataSet2.setValueTextColor(Color.WHITE);
    lineDataSet2.setFillAlpha(110);

    //Data Set 4

    /*LineDataSet lineDataSet4 = new LineDataSet(random, "Random Numbers");
    lineDataSet4.setAxisDependency(YAxis.AxisDependency.LEFT);
    lineDataSet4.setDrawCircles(false);
    lineDataSet4.setColor(Color.parseColor("#00897B"));
    lineDataSet4.setLineWidth(3f);
    lineDataSet4.setHighlightEnabled(true);
    lineDataSet4.setDrawHighlightIndicators(true);
    lineDataSet4.setHighLightColor(Color.parseColor("#64FFDA"));
    lineDataSet4.setValueTextSize(10f);
    lineDataSet4.setValueTextColor(Color.WHITE);
    lineDataSet4.setFillAlpha(110);*/

    //Data set 5 - User Input
    lineDataSet5 = new LineDataSet(userData, "User Data");
    lineDataSet5.setAxisDependency(YAxis.AxisDependency.LEFT);
    lineDataSet5.setDrawCircles(false);
    lineDataSet5.setColor(Color.parseColor("#9C27B0"));
    lineDataSet5.setLineWidth(3f);
    lineDataSet5.setHighlightEnabled(true);
    lineDataSet5.setDrawHighlightIndicators(true);
    lineDataSet5.setHighLightColor(Color.parseColor("#E040FB"));
    lineDataSet5.setValueTextSize(10f);
    lineDataSet5.setValueTextColor(Color.WHITE);
    lineDataSet5.setFillAlpha(110);

    //Add Data sets
    lineDataSets.add(lineDataSet1);
    lineDataSets.add(lineDataSet2);
    lineDataSets.add(lineDataSet3);
    //lineDataSets.add(lineDataSet4);
    //lineDataSets.add(lineDataSet5);

    lineChart.setData(new LineData(lineDataSets));
    lineChart.setData(new LineData());
    lineChart.setVisibleXRangeMaximum(65f);
    lineChart.setHighlightPerTapEnabled(true);

    //Get legend object
    Legend legend = lineChart.getLegend();

    //Customize Legend
    legend.setForm(Legend.LegendForm.LINE);
    legend.setTextColor(Color.WHITE);

    //Set x axis
    XAxis xAxis = lineChart.getXAxis();
    xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
    xAxis.setTextColor(Color.WHITE);
    xAxis.setTextSize(10f);
    xAxis.setDrawGridLines(true);
    xAxis.setAvoidFirstLastClipping(true);

    //Set y axis
    YAxis yAxis = lineChart.getAxisLeft();
    yAxis.setTextColor(Color.WHITE);
    yAxis.setTextSize(10f);
    yAxis.setDrawGridLines(true);
    yAxis.setAxisMaximum(10f);
    yAxis.setAxisMinimum(-10f);

    //Disable Right y-axis values
    lineChart.getAxisRight().setEnabled(false);

    //Set Description
    lineChart.getDescription().setText("Sin and Cos Functions");
    lineChart.getDescription().setTextColor(Color.WHITE);

    //Update and refresh for User Input
    lineChart.notifyDataSetChanged(); //let the chart know it's data changed
    lineChart.invalidate(); //Refresh

    return view;
}

private int getRandomNumber(int min,int max) {
    return (new Random()).nextInt((max - min) + 1) + min;
}
}

主要 Activity :

它管理 2 个选项卡,一个选项卡包含供用户输入值的 EditText,另一个选项卡包含我要更新的折线图。

public class MainActivity extends AppCompatActivity {

private SectionsPagerAdapter mSectionsPagerAdapter;

private ViewPager mViewPager;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Toolbar toolbar = findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());

    // Set up the ViewPager with the sections adapter.
    mViewPager = findViewById(R.id.container);
    //mViewPager.setAdapter(mSectionsPagerAdapter);
    setupViewPager(mViewPager);

    TabLayout tabLayout = findViewById(R.id.tabs);
    tabLayout.setupWithViewPager(mViewPager);

    mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
    tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));

    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                    .setAction("Action", null).show();
        }
    });

}

private void setupViewPager(ViewPager viewPager){
    SectionsPagerAdapter adapter = new SectionsPagerAdapter(getSupportFragmentManager());
    adapter.addFragment(new Fragment1(), "Fragment 1");
    adapter.addFragment(new Fragment2(), "Fragment 2");
    viewPager.setAdapter(adapter);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}
}

最佳答案

您可以更直接地设置监听器。尝试将此方法添加到 Fragment1(并删除 getListener)

void setListener(Fragment1Listener listener) {
    activityCommander = listener;
}

然后像这样在您的 Activity 中设置监听器

private void setupViewPager(ViewPager viewPager){
    SectionsPagerAdapter adapter = new SectionsPagerAdapter(getSupportFragmentManager());
    Fragment1 f1 = new Fragment1();
    Fragment2 f2 = new Fragment2();
    f1.setListener(f2);
    adapter.addFragment(f1, "Fragment 1");
    adapter.addFragment(f2, "Fragment 2");
    viewPager.setAdapter(adapter);
}

当屏幕旋转时,这种方法可能会出现问题,但这至少可以帮助您克服这个障碍。如果您想继续使用 getTargetFragment 方法,您还需要在某处调用 setTargetFragment(参见 question)。类似于 f1.setTargetFragment(f2); 而不是上面代码中的 f1.setListener(f2)

我认为一旦监听器开始工作,您就需要对图形部分进行一些更改以使其继续工作。例如替换

lineChart.setData(new LineData(lineDataSets));
lineChart.setData(new LineData()); // this overrides the previous line with an empty data set

data.addDataSet([... the sets you want to add ...]);
lineChart.setData(data);

但这至少应该让您走上正确的道路。

关于java - Android Studio - MPAndroidChart 将用户输入添加到折线图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51468742/

相关文章:

java - Android应用程序: Error: Android.数据库。CursorIndexOutOfBoundsException : Index 0 requested,,大小为0

java - 使用 Gradle 在 Android 项目中使用 JaCoCo

android - 在 Android Studio 4.0(Canary) 中找不到预览窗口的位置

java - 为什么使用 Jsoup 连接到特定网页时会收到 404 错误?

java - 我们应该为java中的每个try catch block 编写catch(Exception e)吗

java - JGraphT 简单图和无向图

Java 安全管理器完全禁用反射

android studio 4 sdk manager 窗口没有打开并且文件-> 设置窗口也没有打开

android - 如何更改 Android Studio 默认的欢迎屏幕/启动屏幕?

android - 在Android Studio中,我收到一条错误消息,指出 “Packages unavailable”,并且我需要的软件包不可用