Я использую библиотеку MPAndroidChart, чтобы создавать гистограммы для некоторых данных, которые мне нужно отображать. В моем случае, когда пользователь нажимает на столбец на гистограмме, подробная информация об этом конкретном столбце должна отображаться в программе recyclerview, как показано ниже:
Скриншот приложения
Теперь мои события щелчка работают отлично, они отображают только соответствующие данные при срабатывании.
Проблема в том, что событие щелчка запускается для всего столбца панели, а не только для нее. По сути, если я щелкну пустое пространство над полосой, соответствующее событие щелчка для этой панели все равно будет запущено. Однако я хочу, чтобы он запускался только тогда, когда я нажимаю на панель.
Мой соответствующий код приведен ниже (он в Kotlin, но любая помощь на Java также будет оценена):
mBarChart=findViewById(R.id.bargraph)
mBarChart.setNoDataText("No data has been logged to the cloud yet")
rootRef7.addValueEventListener(object : ValueEventListener, com.github.mikephil.charting.listener.OnChartValueSelectedListener {
override fun onNothingSelected() {
}
override fun onValueSelected(e: Entry?, dataSetIndex: Int, h: Highlight?) {
barSelected= e!!.xIndex
if (barSelected!=-1)
{
mBGListShow.clear()
mBGListShow.add(mBGList[barSelected])
RV2.setLayoutManager(LinearLayoutManager(applicationContext))
RV2.setAdapter(adapter1(mBGListShow))
//Toast.makeText(applicationContext,"Data loaded, contains " + mBGList.size.toString() + " items", Toast.LENGTH_SHORT).show()
}
}
override fun onDataChange(dataSnapshot: DataSnapshot) {
// This method is called once with the initial value and again
// whenever data at this location is updated.
var i:Int=0
for (data: DataSnapshot in dataSnapshot.getChildren()) {
var emailIDDB = data.child("emailID").getValue().toString().trim()
if (emailIDDB.equals(currentUserEmailID)) {
dateDB=data.child("calendarTime").getValue().toString().trim() + " (" + data.child("beforeEvent").getValue().toString().trim() + ")"
BGDB=data.child("currentBGLevel").getValue().toString().trim()
BGDBNumber=BGDB.toFloat()
dateList.add(dateDB)
BGList.add(BarEntry(BGDBNumber,i))
i++
eventDB=data.child("beforeEvent").getValue().toString().trim()
currentBGDB=data.child("currentBGLevel").getValue().toString().trim()
targetBGDB=data.child("targetBGLevel").getValue().toString().trim()
amountOfCHODB=data.child("totalCHO").getValue().toString().trim()
disposedCHODB=data.child("amountDisposedByInsulin").getValue().toString().trim()
correctionFactorDB=data.child("correctionFactor").getValue().toString().trim()
insulinRecommendationDB=data.child("insulinRecommendation").getValue().toString().trim()
typeOfInsulinDB=data.child("typeOfBG").getValue().toString().trim()
var mBGRecyclerView: BGRecyclerView= BGRecyclerView(eventDB,currentBGDB,targetBGDB,amountOfCHODB,disposedCHODB,correctionFactorDB,insulinRecommendationDB,typeOfInsulinDB)
mBGList.add(mBGRecyclerView)
}
}
mBarChart.xAxis.setLabelsToSkip(0)
mBarChart.setOnChartValueSelectedListener(this)
var mBarBGDataSet: BarDataSet= BarDataSet(BGList,"BG Level")
var mBarData:BarData=BarData(dateList,mBarBGDataSet)
mBarChart.setData(mBarData)
mBarChart.setTouchEnabled(true)
mBarChart.setDragEnabled(true)
mBarChart.setScaleEnabled(true)
mBarChart.setDescription("")
mBarChart.setMaxVisibleValueCount(1000)
mBarChart.invalidate()
}
override fun onCancelled(p0: DatabaseError?) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
})




Я опаздываю на вечеринку.
Это все еще ошибка в MPAndroidChart. Он не делает различий между заполненной областью и незаполненной областью столбца. Если мы коснемся незаполненной области (сверху, снизу, слева, справа), запускается событие OnValueSelected. Я перепробовал все, но не смог решить.
Наконец, я нашел обходной путь. Я использовал событие OnChartSingleTap для OnChartGestureListener, чтобы зафиксировать текущую позицию y (getY). Затем в OnValueselected сравниваю h.getYPx<=y. То же самое можно сделать и для оси x.
Это решило проблему для меня.
Вот решение проблемы: onValueSelected вызывается даже в незаполненной (пустой) области бара (верх заполненной области полосы):
/**
* Selected Y Index on user tap
*/
private var selectedYIndex: Float? = null
override fun onChartSingleTapped(motionEvent: MotionEvent) {
// Touched chart entry
val entry: Entry? =
chartView.getEntryByTouchPoint(motionEvent.x, motionEvent.y)
selectedYIndex = if (entry != null) {
//Entry is non-null which means user clicked on bar area (filled or non-filled)
motionEvent.y
} else {
//Entry is null which means user clicked outside of bar area
null
}
}
А затем в onValueSelected:
override fun onValueSelected(e: Entry?, h: Highlight?) {
//We check for Selected Y Index is non-null (user tapped on non-filled or filled area of bar)
//Also, we check for selected highlight is non-null and whether user tapped filled area of bar
if (selectedYIndex != null && h != null && h.yPx <= selectedYIndex!!) {
//TODO: User tapped on filled bar area
}
}
Вы можете поблагодарить пользователя, проголосовав за его вопрос / ответ, а не в сообщении.