按下图形会导致应用程序崩溃

pressing the graph causes the application to crash

我有一个问题,如何在 phone 上打开应用程序并尝试按 MPAndroidChart 中的图表,它让我退出应用程序,我写道应用程序正在崩溃。

link 到我从中获取文档的页面 [此处][1]

我对图表有疑问。我的图表从 csv 文件中获取数据,并以小时、分钟和秒为单位给出时间。如何校准图形以使时间每 60 分钟而不是每 100 分钟显示一次 我的

主要活动

package com.example.aplikacjadlataty

import android.content.Intent
import android.graphics.Color
import android.net.Uri
import android.os.Bundle
import android.util.Log
import android.widget.Button
import android.widget.Switch
import android.widget.TextView
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import com.github.mikephil.charting.animation.Easing
import com.github.mikephil.charting.charts.LineChart
import com.github.mikephil.charting.data.Entry
import com.github.mikephil.charting.data.LineData
import com.github.mikephil.charting.data.LineDataSet
import com.google.android.gms.ads.MobileAds
import kotlinx.android.synthetic.main.activity_main.*
import java.io.BufferedReader
import java.io.IOException
import java.io.InputStreamReader
import java.util.*

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val getContent = registerForActivityResult(ActivityResultContracts.GetContent()) { uri: Uri? ->
            val lines = readCSV(uri)
            val newEntries = lines.map { line -> toEntry(line) }.groupingBy { entry -> entry.x }
                .reduce { _, accumulator, element -> if (accumulator.y > element.y) accumulator else element }.values
            val lineChart = findViewById<LineChart>(R.id.lineChart)
            val vl = LineDataSet(newEntries.toList().take(4000), "cost")
            vl.setDrawValues(false)
            vl.setDrawFilled(true)
            vl.lineWidth = 1.5f
            vl.fillColor = R.color.gray
            vl.fillAlpha = R.color.red
            vl.setDrawCircles(false)
            lineChart.data = LineData(vl)
            lineChart.notifyDataSetChanged()
            lineChart.animateX(1800, Easing.EaseInExpo)
            lineChart.description.isEnabled = false
            lineChart.isHighlightPerDragEnabled = false
            lineChart.isScaleYEnabled = false
            lineChart.axisRight.isEnabled = false
//            lineChart.xAxis.valueFormatter = MyAxisFormatter()
//              lineChart.xAxis.granularity = 60f
        }

        findViewById<Button>(R.id.button_loadCsv)?.setOnClickListener {
            val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
            intent.addCategory(Intent.CATEGORY_OPENABLE)
            intent.type = "text/*"
            getContent.launch("text/*")
        }

        val button = findViewById<Button>(R.id.button_loadCsv)
        val text = findViewById<TextView>(R.id.text)

        val sw1 = findViewById<Switch>(R.id.switch1)
        sw1?.setOnCheckedChangeListener { _, isChecked ->
            if (isChecked) screen.setBackgroundColor(Color.DKGRAY)
            else screen.setBackgroundColor(Color.WHITE)

            if (isChecked) layout.setBackgroundColor(Color.DKGRAY)
            else layout.setBackgroundColor(Color.WHITE)

            if (isChecked) AdsLayout.setBackgroundColor(Color.DKGRAY)
            else AdsLayout.setBackgroundColor(Color.WHITE)

            if (isChecked) text.text = "Set light mode"
            else text.text = "Set dark mode"
            if (isChecked) text.setTextColor(Color.WHITE)
            else text.setTextColor(Color.BLACK)

            if (isChecked) button.setTextColor(Color.WHITE)
            else button.setTextColor(Color.BLACK)
            if (isChecked) button.setBackgroundColor(Color.parseColor("#707070"))
            else button.setBackgroundColor(Color.parseColor("#efefef"))
        }

        Log.d(
            "MainActivity", "onCreate Called \n" +
                    "                                                                                                                    \n" +
                    "                                                                                                                    \n" +
                    "                                                                                                                    \n" +
                    "    __  ___    ___     __ __   _____          ______    __  __   ____        __    _   __    ____    ___     __ __  \n" +
                    "   /  |/  /   /   |   / //_/  / ___/         / ____/   / / / /  / __ \      / /   / | / /   /  _/   /   |   / //_/ \n" +
                    "  / /|_/ /   / /| |  / ,<     \__ \         / /       / /_/ /  / / / / __  / /   /  |/ /    / /    / /| |  / ,<   \n" +
                    " / /  / /   / ___ | / /| |   ___/ /        / /___    / __  /  / /_/ / / /_/ /   / /|  /   _/ /    / ___ | / /| |    \n" +
                    "/_/  /_/   /_/  |_|/_/ |_|  /____/         \____/   /_/ /_/   \____/  \____/   /_/ |_/   /___/   /_/  |_|/_/ |_| \n" +
                    "                                                                                                                    \n" +
                    "                                                                                                                    \n" +
                    "                                                                                                                      "
        )

        MobileAds.initialize(this) {}

        val markerView = CustomMarker(this@MainActivity, R.layout.marker_view)
        lineChart.marker = markerView
    }

    @Throws(IOException::class)
    fun readCSV(uri: Uri?): List<String> {
        if (uri != null) {
            val csvFile = contentResolver.openInputStream(uri)
            val isr = InputStreamReader(csvFile)
            return BufferedReader(isr).readLines()
        }
        return Collections.emptyList()
    }

    private fun toEntry(line: String): Entry {
        val split = line.split(";")
        return Entry(split[1].toFloat(), split[2].toFloat())
    }
}

故障很明显。此处指定:

NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference at com.example.aplikacjadlataty.CustomMarker.refreshContent(CustomMarker.kt:22)

因此转到 CustomMarker.kt 中的第 22 行并修复它。可能您没有对 tvPrice 的引用。你知道那个 ID 在哪里吗?

编辑

不看全文是做不到的。你有没有在你的项目中添加这个.XML

marker_view.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="2dp"
    android:background="@drawable/oval_marker"
    android:orientation="vertical">

    <TextView
        android:id="@+id/tvPrice"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:gravity="center"
        android:layout_marginLeft="5dp"
        android:layout_marginRight="5dp"
        android:text=""
        android:textSize="10dp"
        android:textColor="@android:color/white"
        android:ellipsize="end"
        android:textAppearance="?android:attr/textAppearanceSmall" />

</LinearLayout>

在您的link、here

中有解释 编辑 2 按照我的代码。对我来说,我工作得很好:

低于MainActivity.kt

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.github.mikephil.charting.animation.Easing
import com.github.mikephil.charting.data.Entry
import com.github.mikephil.charting.charts.LineChart
import com.github.mikephil.charting.data.LineData
import com.github.mikephil.charting.data.LineDataSet
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val lineChart = findViewById<LineChart>(R.id.lineChart)

        //Part1
        val entries = ArrayList<Entry>()

//Part2
        entries.add(Entry(1f, 10f))
        entries.add(Entry(2f, 2f))
        entries.add(Entry(3f, 7f))
        entries.add(Entry(4f, 20f))
        entries.add(Entry(5f, 16f))

//Part3
        val vl = LineDataSet(entries, "My Type")

//Part4
        vl.setDrawValues(false)
        vl.setDrawFilled(true)
        vl.lineWidth = 3f
        vl.fillColor = R.color.gray
        vl.fillAlpha = R.color.red

//Part5
        lineChart.xAxis.labelRotationAngle = 0f

//Part6
        lineChart.data = LineData(vl)

//Part7
        lineChart.axisRight.isEnabled = false
        lineChart.xAxis.axisMaximum = 1 + 0.1f

//Part8
        lineChart.setTouchEnabled(true)
        lineChart.setPinchZoom(true)

//Part9
        lineChart.description.text = "Days"
        lineChart.setNoDataText("No forex yet!")

//Part10
        lineChart.animateX(1800, Easing.EaseInExpo)

//Part11
        val markerView = CustomMarker(this, R.layout.marker_view)
        lineChart.marker = markerView
    }
}

低于CustomMarker.kt

import android.content.Context
import android.widget.TextView
import com.github.mikephil.charting.components.MarkerView
import com.github.mikephil.charting.data.Entry
import com.github.mikephil.charting.highlight.Highlight
import com.github.mikephil.charting.utils.MPPointF

class CustomMarker(context: Context, layoutResource: Int):  MarkerView(context, layoutResource) {
    override fun refreshContent(entry: Entry?, highlight: Highlight?) {
        val value = entry?.y?.toDouble() ?: 0.0

        val tvPrice = findViewById<TextView>(R.id.tvPrice)

        val resText: String = if(value.toString().length > 8){
            "Val: " + value.toString().substring(0,7)
        } else{
            "Val: $value"
        }
        tvPrice.text = resText
        super.refreshContent(entry, highlight)
    }

    override fun getOffsetForDrawingAtPoint(xpos: Float, ypos: Float): MPPointF {
        return MPPointF(-width / 2f, -height - 10f)
    }
}

这里 activity_main.xml 里面 res/layout 文件夹

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.github.mikephil.charting.charts.LineChart
        android:id="@+id/lineChart"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginStart="5dp"
        android:layout_marginTop="10dp"
        android:layout_marginEnd="5dp"
        android:layout_marginBottom="10dp"
        android:padding="9dp" />

</androidx.constraintlayout.widget.ConstraintLayout>

这里 oval_marker.xml 里面 res/drawable 文件夹

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@color/gray" />

    <stroke
        android:width="1dp"
        android:color="@color/colorWhite" />

    <padding
        android:bottom="1dp"
        android:left="1dp"
        android:right="1dp"
        android:top="1dp" />

    <corners
        android:bottomLeftRadius="7dp"
        android:bottomRightRadius="7dp"
        android:topLeftRadius="7dp"
        android:topRightRadius="7dp" />
</shape>

这里 gradient_bg.xml 里面 drawable 文件夹

<?xml version="1.0" encoding="UTF-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape>
            <gradient
                android:startColor="@color/colorLight"
                android:endColor="@color/colorDark"
                android:angle="180"/>
        </shape>
    </item>
</selector>

这里 colors.xml 里面 res/values:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="purple_200">#FFBB86FC</color>
    <color name="purple_500">#FF6200EE</color>
    <color name="purple_700">#FF3700B3</color>
    <color name="teal_200">#FF03DAC5</color>
    <color name="teal_700">#FF018786</color>
    <color name="black">#FF000000</color>
    <color name="white">#FFFFFFFF</color>

    <color name="green">#4CAF50</color>
    <color name="red">#F44336</color>
    <color name="colorDark">#666262</color>
    <color name="colorLight">#F3D3D0</color>
    <color name="gray">#4E4948</color>
    <color name="colorWhite">#FFFFFF</color>
</resources>