mirror of
https://github.com/dzeiocom/OpenHealth.git
synced 2025-04-23 11:22:10 +00:00
Updated
This commit is contained in:
parent
8c33478e17
commit
e5615c9463
8
.idea/misc.xml
generated
8
.idea/misc.xml
generated
@ -3,9 +3,15 @@
|
||||
<component name="DesignSurface">
|
||||
<option name="filePathToZoomLevelMap">
|
||||
<map>
|
||||
<entry key="..\:/Git/Dzeio/OpenHealth/app/src/main/res/layout/fragment_home.xml" value="0.33" />
|
||||
<entry key="..\:/Git/Dzeio/OpenHealth/app/src/main/res/drawable/ic_outline_hexagon_24.xml" value="0.3475" />
|
||||
<entry key="..\:/Git/Dzeio/OpenHealth/app/src/main/res/layout/dialog_edit_weight.xml" value="0.5510416666666667" />
|
||||
<entry key="..\:/Git/Dzeio/OpenHealth/app/src/main/res/layout/fragment_home.xml" value="0.67" />
|
||||
<entry key="..\:/Git/Dzeio/OpenHealth/app/src/main/res/layout/fragment_import.xml" value="0.1" />
|
||||
<entry key="..\:/Git/Dzeio/OpenHealth/app/src/main/res/layout/fragment_main_water_home.xml" value="0.5" />
|
||||
<entry key="..\:/Git/Dzeio/OpenHealth/app/src/main/res/layout/layout_item_list.xml" value="0.5" />
|
||||
<entry key="..\:/Git/Dzeio/OpenHealth/app/src/main/res/layout/layout_item_weight.xml" value="0.267983789260385" />
|
||||
<entry key="..\:/Git/Dzeio/OpenHealth/app/src/main/res/menu/activity_main_drawer.xml" value="0.10989583333333333" />
|
||||
<entry key="..\:/Git/Dzeio/OpenHealth/app/src/main/res/menu/fullscreen_dialog.xml" value="0.31197916666666664" />
|
||||
<entry key="..\:/Git/Dzeio/OpenHealth/app/src/main/res/menu/main.xml" value="0.1875" />
|
||||
<entry key="..\:/git/Dzeio/OpenHealth/app/src/main/res/drawable/half_circle.xml" value="0.421" />
|
||||
<entry key="..\:/git/Dzeio/OpenHealth/app/src/main/res/drawable/ic_ellipse_2.xml" value="0.4165" />
|
||||
|
@ -23,19 +23,6 @@
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.OpenHealth">
|
||||
|
||||
<receiver android:name=".services.BroadcastReceiver"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<!-- Water Intake -->
|
||||
<service android:name=".services.WaterReminderService"
|
||||
android:label="Water Intake service"
|
||||
android:permission="android.permission.BIND_JOB_SERVICE" />
|
||||
|
||||
<!-- Samsung Health-->
|
||||
<meta-data
|
||||
android:name="com.samsung.android.health.permission.read"
|
||||
|
@ -15,8 +15,10 @@ import androidx.navigation.ui.AppBarConfiguration
|
||||
import androidx.navigation.ui.navigateUp
|
||||
import androidx.navigation.ui.setupActionBarWithNavController
|
||||
import androidx.navigation.ui.setupWithNavController
|
||||
import androidx.work.WorkManager
|
||||
import com.dzeio.openhealth.core.BaseActivity
|
||||
import com.dzeio.openhealth.databinding.ActivityMainBinding
|
||||
import com.dzeio.openhealth.interfaces.NotificationChannels
|
||||
import com.dzeio.openhealth.services.WaterReminderService
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
|
||||
@ -27,14 +29,16 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
|
||||
private lateinit var navController: NavController
|
||||
|
||||
override val bindingInflater: (LayoutInflater) -> ActivityMainBinding = ActivityMainBinding::inflate
|
||||
override val bindingInflater: (LayoutInflater) -> ActivityMainBinding =
|
||||
ActivityMainBinding::inflate
|
||||
|
||||
override fun onCreated(savedInstanceState: Bundle?) {
|
||||
super.onCreated(savedInstanceState)
|
||||
|
||||
setSupportActionBar(binding.toolbar)
|
||||
|
||||
val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
|
||||
val navHostFragment =
|
||||
supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
|
||||
navController = navHostFragment.navController
|
||||
binding.navView.setupWithNavController(navController)
|
||||
|
||||
@ -46,9 +50,13 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
|
||||
setupActionBarWithNavController(navController, appBarConfiguration)
|
||||
|
||||
WaterReminderService.setup(this)
|
||||
createNotificationChannel()
|
||||
|
||||
// Services
|
||||
WorkManager.getInstance(this)
|
||||
.cancelAllWork()
|
||||
WaterReminderService.setup(this)
|
||||
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
@ -83,13 +91,21 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
private fun createNotificationChannel() {
|
||||
// Create the NotificationChannel, but only on API 26+ because
|
||||
// the NotificationChannel class is new and not in the support library
|
||||
|
||||
val notificationManager: NotificationManager =
|
||||
getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
val importance = NotificationManager.IMPORTANCE_DEFAULT
|
||||
val channel = NotificationChannel("openhealth", "Default Channel", importance)
|
||||
// Register the channel with the system
|
||||
val notificationManager: NotificationManager =
|
||||
getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
notificationManager.createNotificationChannel(channel)
|
||||
for (channel in NotificationChannels.values()) {
|
||||
notificationManager.createNotificationChannel(
|
||||
NotificationChannel(
|
||||
channel.id,
|
||||
channel.channelName,
|
||||
channel.importance
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,31 @@
|
||||
package com.dzeio.openhealth.adapters
|
||||
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import com.dzeio.openhealth.core.BaseAdapter
|
||||
import com.dzeio.openhealth.core.BaseViewHolder
|
||||
import com.dzeio.openhealth.data.water.Water
|
||||
import com.dzeio.openhealth.data.weight.Weight
|
||||
import com.dzeio.openhealth.databinding.LayoutItemListBinding
|
||||
import com.dzeio.openhealth.databinding.LayoutItemWeightBinding
|
||||
|
||||
class WaterAdapter() : BaseAdapter<Water, LayoutItemListBinding>() {
|
||||
|
||||
override val bindingInflater: (LayoutInflater, ViewGroup?, Boolean) -> LayoutItemListBinding
|
||||
get() = LayoutItemListBinding::inflate
|
||||
|
||||
var onItemClick: ((weight: Water) -> Unit)? = null
|
||||
|
||||
override fun onBindData(
|
||||
holder: BaseViewHolder<LayoutItemListBinding>,
|
||||
item: Water,
|
||||
position: Int
|
||||
) {
|
||||
holder.binding.value.text = "${item.value}ml"
|
||||
holder.binding.datetime.text = item.formatTimestamp()
|
||||
holder.binding.edit.setOnClickListener {
|
||||
onItemClick?.invoke(item)
|
||||
}
|
||||
}
|
||||
}
|
@ -4,8 +4,8 @@ import android.content.Context
|
||||
import androidx.room.Database
|
||||
import androidx.room.Room
|
||||
import androidx.room.RoomDatabase
|
||||
import com.dzeio.openhealth.data.weight.Water
|
||||
import com.dzeio.openhealth.data.weight.WaterDao
|
||||
import com.dzeio.openhealth.data.water.Water
|
||||
import com.dzeio.openhealth.data.water.WaterDao
|
||||
import com.dzeio.openhealth.data.weight.WeightDao
|
||||
import com.dzeio.openhealth.data.weight.Weight
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.dzeio.openhealth.data.weight
|
||||
package com.dzeio.openhealth.data.water
|
||||
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
@ -12,23 +12,25 @@ data class Water(
|
||||
@PrimaryKey(autoGenerate = true) var id: Long = 0,
|
||||
var value: Int = 0,
|
||||
@ColumnInfo(index = true)
|
||||
var timestamp: Long = System.currentTimeMillis(),
|
||||
var timestamp: Long = 0,
|
||||
var source: String = "OpenHealth"
|
||||
) {
|
||||
init {
|
||||
val cal = Calendar.getInstance()
|
||||
cal.set(Calendar.HOUR_OF_DAY, 0)
|
||||
cal.set(Calendar.MINUTE, 0)
|
||||
cal.set(Calendar.SECOND, 0)
|
||||
cal.set(Calendar.MILLISECOND, 0)
|
||||
if (timestamp == (0).toLong()) {
|
||||
val cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"))
|
||||
cal.set(Calendar.HOUR_OF_DAY, 0)
|
||||
cal.set(Calendar.MINUTE, 0)
|
||||
cal.set(Calendar.SECOND, 0)
|
||||
cal.set(Calendar.MILLISECOND, 0)
|
||||
|
||||
timestamp = cal.timeInMillis
|
||||
timestamp = cal.timeInMillis
|
||||
}
|
||||
}
|
||||
|
||||
fun formatTimestamp(): String = getDateInstance().format(Date(timestamp))
|
||||
|
||||
fun isToday(): Boolean {
|
||||
val cal = Calendar.getInstance()
|
||||
val cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"))
|
||||
cal.set(Calendar.HOUR_OF_DAY, 0)
|
||||
cal.set(Calendar.MINUTE, 0)
|
||||
cal.set(Calendar.SECOND, 0)
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.dzeio.openhealth.data.weight
|
||||
package com.dzeio.openhealth.data.water
|
||||
|
||||
import androidx.room.*
|
||||
import com.dzeio.openhealth.core.BaseDao
|
||||
@ -8,7 +8,7 @@ import kotlinx.coroutines.flow.Flow
|
||||
@Dao
|
||||
interface WaterDao : BaseDao<Water> {
|
||||
|
||||
@Query("SELECT * FROM Water")
|
||||
@Query("SELECT * FROM Water ORDER BY timestamp")
|
||||
fun getAll(): Flow<List<Water>>
|
||||
|
||||
@Query("SELECT * FROM Water where id = :weightId")
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.dzeio.openhealth.data.weight
|
||||
package com.dzeio.openhealth.data.water
|
||||
|
||||
import android.util.Log
|
||||
import kotlinx.coroutines.flow.*
|
||||
|
@ -2,7 +2,7 @@ package com.dzeio.openhealth.di
|
||||
|
||||
import android.content.Context
|
||||
import com.dzeio.openhealth.data.AppDatabase
|
||||
import com.dzeio.openhealth.data.weight.WaterDao
|
||||
import com.dzeio.openhealth.data.water.WaterDao
|
||||
import com.dzeio.openhealth.data.weight.WeightDao
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
|
@ -0,0 +1,12 @@
|
||||
package com.dzeio.openhealth.interfaces
|
||||
|
||||
import android.app.NotificationManager
|
||||
|
||||
enum class NotificationChannels(
|
||||
val id: String,
|
||||
val channelName: String,
|
||||
val importance: Int
|
||||
) {
|
||||
// 3 is IMPORTANCE_DEFAULT
|
||||
DEFAULT("default", "Default Channel", 3)
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package com.dzeio.openhealth.interfaces
|
||||
|
||||
enum class NotificationIds {
|
||||
WaterIntake
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
package com.dzeio.openhealth.services
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.util.Log
|
||||
|
||||
class BroadcastReceiver : BroadcastReceiver() {
|
||||
@SuppressLint("UnsafeProtectedBroadcastReceiver")
|
||||
override fun onReceive(context: Context?, intent: Intent?) {
|
||||
context?.let {
|
||||
WaterReminderService.setup(it)
|
||||
Log.d("OpenHealth/BR", "Scheduled Jobs!")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -14,6 +14,8 @@ import com.dzeio.openhealth.Application
|
||||
import com.dzeio.openhealth.MainActivity
|
||||
import com.dzeio.openhealth.R
|
||||
import com.dzeio.openhealth.core.BaseService
|
||||
import com.dzeio.openhealth.interfaces.NotificationChannels
|
||||
import com.dzeio.openhealth.interfaces.NotificationIds
|
||||
import java.util.*
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
@ -27,7 +29,7 @@ class WaterReminderService(
|
||||
fun setup(context: Context) {
|
||||
schedule(
|
||||
TAG,
|
||||
PeriodicWorkRequestBuilder<WaterReminderService>(15, TimeUnit.MINUTES)
|
||||
PeriodicWorkRequestBuilder<WaterReminderService>(1, TimeUnit.HOURS)
|
||||
.addTag(TAG)
|
||||
.build(),
|
||||
context
|
||||
@ -39,48 +41,29 @@ class WaterReminderService(
|
||||
override fun doWork(): Result {
|
||||
Log.d(TAG, "Ran! ${Date().toLocaleString()}")
|
||||
with(NotificationManagerCompat.from(context)) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
notify(
|
||||
(Math.random() * 100).toInt(), NotificationCompat.Builder(context, "openhealth")
|
||||
.setContentTitle("Did you drink?")
|
||||
.setContentText("Drink now!")
|
||||
.setSmallIcon(R.drawable.ic_logo_small)
|
||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||
.setContentIntent(
|
||||
PendingIntent.getActivity(
|
||||
context,
|
||||
0,
|
||||
Intent(context, MainActivity::class.java).apply {
|
||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
},
|
||||
PendingIntent.FLAG_IMMUTABLE
|
||||
)
|
||||
val flag =
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) PendingIntent.FLAG_IMMUTABLE else 0
|
||||
val builder =
|
||||
NotificationCompat.Builder(context, NotificationChannels.DEFAULT.channelName)
|
||||
.setContentTitle("Did you drink?")
|
||||
.setContentText("Drink now! ${Date().toLocaleString()}")
|
||||
.setSmallIcon(R.drawable.ic_logo_small)
|
||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||
.setContentIntent(
|
||||
PendingIntent.getActivity(
|
||||
context,
|
||||
0,
|
||||
Intent(context, MainActivity::class.java).apply {
|
||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
},
|
||||
flag
|
||||
)
|
||||
.build()
|
||||
)
|
||||
} else {
|
||||
notify(
|
||||
(Math.random() * 100).toInt(), NotificationCompat.Builder(context, "openhealth")
|
||||
.setContentTitle("Did you drink?")
|
||||
.setContentText("Drink now!")
|
||||
.setSmallIcon(R.drawable.ic_logo_small)
|
||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||
.setContentIntent(
|
||||
PendingIntent.getActivity(
|
||||
context,
|
||||
0,
|
||||
Intent(context, MainActivity::class.java).apply {
|
||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
},
|
||||
0
|
||||
)
|
||||
)
|
||||
.build()
|
||||
)
|
||||
}
|
||||
).build()
|
||||
notify(
|
||||
NotificationIds.WaterIntake.ordinal,
|
||||
builder
|
||||
)
|
||||
}
|
||||
return Result.success()
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -11,9 +11,10 @@ import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import com.dzeio.openhealth.Application
|
||||
import com.dzeio.openhealth.R
|
||||
import com.dzeio.openhealth.core.BaseFragment
|
||||
import com.dzeio.openhealth.data.weight.Water
|
||||
import com.dzeio.openhealth.data.water.Water
|
||||
import com.dzeio.openhealth.databinding.FragmentHomeBinding
|
||||
import com.dzeio.openhealth.data.weight.Weight
|
||||
import com.dzeio.openhealth.ui.weight.AddWeightDialog
|
||||
@ -39,14 +40,12 @@ import kotlin.math.min
|
||||
class HomeFragment : BaseFragment<HomeViewModel, FragmentHomeBinding>(HomeViewModel::class.java) {
|
||||
|
||||
companion object {
|
||||
const val TAG = "HomeFragment"
|
||||
const val TAG = "${Application.TAG}/HomeFragment"
|
||||
}
|
||||
|
||||
override val bindingInflater: (LayoutInflater, ViewGroup?, Boolean) -> FragmentHomeBinding
|
||||
get() = FragmentHomeBinding::inflate
|
||||
|
||||
// private lateinit var fit: GoogleFit
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
@ -107,99 +106,62 @@ class HomeFragment : BaseFragment<HomeViewModel, FragmentHomeBinding>(HomeViewMo
|
||||
Log.d("T", "Trying to move")
|
||||
|
||||
findNavController().navigate(HomeFragmentDirections.actionNavHomeToNavListWeight())
|
||||
|
||||
// requireActivity().supportFragmentManager.commit {
|
||||
// replace(R.id.nav_host_fragment_content_main, ListWeightFragment())
|
||||
// addToBackStack(null)
|
||||
// }
|
||||
}
|
||||
|
||||
// Setup Graph
|
||||
// binding.weightGraph.apply {
|
||||
// gridLabelRenderer.labelFormatter = DateAsXAxisLabelFormatter(
|
||||
// requireContext(),
|
||||
// DateFormat.getDateInstance(DateFormat.MEDIUM)
|
||||
// )
|
||||
// gridLabelRenderer.numHorizontalLabels = 3 // only 4 because of the space
|
||||
// gridLabelRenderer.numVerticalLabels = 3
|
||||
// gridLabelRenderer.gridStyle = GridLabelRenderer.GridStyle.HORIZONTAL
|
||||
// viewport.isXAxisBoundsManual = true
|
||||
// viewport.isScalable = true
|
||||
// viewport.setScalableY(true)
|
||||
// viewport.isScrollable = true
|
||||
// viewport.setScrollableY(true)
|
||||
// gridLabelRenderer.setHumanRounding(false);
|
||||
// addSeries(serie)
|
||||
// }
|
||||
|
||||
binding.gotoWaterHome.setOnClickListener {
|
||||
findNavController().navigate(HomeFragmentDirections.actionNavHomeToNavWaterHome())
|
||||
}
|
||||
}
|
||||
|
||||
// private val serie: LineGraphSeries<DataPoint> = LineGraphSeries()
|
||||
// private val entries = LineGraphSeries<DataPoint>()
|
||||
|
||||
private fun updateGraph(list: List<Weight>) {
|
||||
if (list.isNotEmpty()) {
|
||||
val first = list[0].timestamp
|
||||
val last = list[list.size - 1].timestamp
|
||||
val weekFirst = last - 604800000
|
||||
// binding.weightGraph.viewport.setMinX(if (first > weekFirst) first else weekFirst)
|
||||
// binding.weightGraph.viewport.setMaxX(last);
|
||||
|
||||
|
||||
val entries = ArrayList<Entry>()
|
||||
for (item in list) {
|
||||
entries.add(Entry(item.timestamp.toFloat(), item.weight))
|
||||
}
|
||||
|
||||
val dataSet = LineDataSet(entries, "Label")
|
||||
// binding.weightGraph.xAxis.axisMinimum = if (first > weekFirst) first.toFloat() else weekFirst.toFloat()
|
||||
// binding.weightGraph.setExtraOffsets(
|
||||
// if (first > weekFirst) first.toFloat() else weekFirst.toFloat(),
|
||||
// 100f,
|
||||
// last.toFloat(),
|
||||
// 0f
|
||||
// )
|
||||
binding.weightGraph.isAutoScaleMinMaxEnabled = true
|
||||
//binding.weightGraph.setvir
|
||||
binding.weightGraph.isDragEnabled = true
|
||||
binding.weightGraph.isScaleYEnabled = false
|
||||
binding.weightGraph.description = Description().apply { isEnabled = false }
|
||||
binding.weightGraph.isScaleXEnabled = true
|
||||
binding.weightGraph.setPinchZoom(false)
|
||||
binding.weightGraph.xAxis.setLabelCount(5, true)
|
||||
binding.weightGraph.xAxis.position = XAxis.XAxisPosition.BOTTOM
|
||||
binding.weightGraph.axisRight.isEnabled = false
|
||||
binding.weightGraph.axisRight.setDrawGridLines(false)
|
||||
binding.weightGraph.xAxis.valueFormatter = object : ValueFormatter() {
|
||||
override fun getAxisLabel(value: Float, axis: AxisBase?): String {
|
||||
return SimpleDateFormat(
|
||||
"yyyy-MM-dd",
|
||||
Locale.getDefault()
|
||||
).format(Date(value.toLong()))
|
||||
//return super.getAxisLabel(value, axis)
|
||||
binding.weightGraph.apply {
|
||||
|
||||
// Setup
|
||||
isAutoScaleMinMaxEnabled = true
|
||||
legend.isEnabled = false
|
||||
isDragEnabled = true
|
||||
isScaleYEnabled = false
|
||||
description = Description().apply { isEnabled = false }
|
||||
isScaleXEnabled = true
|
||||
setPinchZoom(false)
|
||||
axisLeft.setLabelCount(0, true)
|
||||
setDrawBorders(false)
|
||||
|
||||
xAxis.apply {
|
||||
valueFormatter = object : ValueFormatter() {
|
||||
override fun getAxisLabel(value: Float, axis: AxisBase?): String {
|
||||
return SimpleDateFormat(
|
||||
"yyyy-MM-dd",
|
||||
Locale.getDefault()
|
||||
).format(Date(value.toLong()))
|
||||
//return super.getAxisLabel(value, axis)
|
||||
}
|
||||
}
|
||||
position = XAxis.XAxisPosition.BOTTOM
|
||||
setDrawGridLines(false)
|
||||
setLabelCount(3, true)
|
||||
}
|
||||
|
||||
// Apply new dataset
|
||||
data = LineData(dataSet)
|
||||
|
||||
// idk what I did but it works lol
|
||||
setVisibleXRange(
|
||||
0f, entries[entries.size - 1].x / 1000f
|
||||
)
|
||||
|
||||
// BIS... :(
|
||||
// Also it invalidate the view so I don't have to call invalidate
|
||||
moveViewToX(entries[entries.size - 1].x - 1600000000f)
|
||||
}
|
||||
binding.weightGraph.data = LineData(dataSet)
|
||||
binding.weightGraph.invalidate()
|
||||
binding.weightGraph.setVisibleXRange(
|
||||
(list[list.size - 1].timestamp - 604800000).toFloat(),
|
||||
list[list.size - 1].timestamp.toFloat()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
// binding.weightGraph.gridLabelRenderer.numHorizontalLabels = 3 // only 4 because of the space
|
||||
// binding.weightGraph.gridLabelRenderer.numVerticalLabels = 3
|
||||
//
|
||||
// binding.weightGraph.viewport.maxXAxisSize = 604800000.0 * 2
|
||||
//// binding.weightGraph.viewport.setMinimalViewport(0.0, 604800000.0, minValue.toDouble(), maxValue.toDouble())
|
||||
//
|
||||
// serie.resetData(list
|
||||
// .map { DataPoint(Date(it.timestamp), it.weight.toDouble()) }
|
||||
// .toTypedArray())
|
||||
//
|
||||
// binding.weightGraph.viewport.scrollToEnd()
|
||||
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
@ -212,6 +174,7 @@ class HomeFragment : BaseFragment<HomeViewModel, FragmentHomeBinding>(HomeViewMo
|
||||
}
|
||||
|
||||
viewModel.water.observe(viewLifecycleOwner) {
|
||||
Log.d(TAG, "${it?.formatTimestamp()} $it")
|
||||
if (it != null) {
|
||||
updateWater(it.value)
|
||||
} else {
|
||||
|
@ -4,8 +4,8 @@ import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.dzeio.openhealth.core.BaseViewModel
|
||||
import com.dzeio.openhealth.data.weight.Water
|
||||
import com.dzeio.openhealth.data.weight.WaterRepository
|
||||
import com.dzeio.openhealth.data.water.Water
|
||||
import com.dzeio.openhealth.data.water.WaterRepository
|
||||
import com.dzeio.openhealth.data.weight.Weight
|
||||
import com.dzeio.openhealth.data.weight.WeightRepository
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
|
@ -1,2 +1,52 @@
|
||||
package com.dzeio.openhealth.ui.water
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.dzeio.openhealth.adapters.WaterAdapter
|
||||
import com.dzeio.openhealth.adapters.WeightAdapter
|
||||
import com.dzeio.openhealth.core.BaseFragment
|
||||
import com.dzeio.openhealth.databinding.FragmentListWeightBinding
|
||||
import com.dzeio.openhealth.databinding.FragmentMainWaterHomeBinding
|
||||
import com.dzeio.openhealth.ui.home.HomeViewModel
|
||||
import com.dzeio.openhealth.ui.weight.ListWeightFragmentDirections
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
|
||||
@AndroidEntryPoint
|
||||
class WaterHomeFragment :
|
||||
BaseFragment<WaterHomeViewModel, FragmentMainWaterHomeBinding>(WaterHomeViewModel::class.java) {
|
||||
|
||||
override val bindingInflater: (LayoutInflater, ViewGroup?, Boolean) -> FragmentMainWaterHomeBinding =
|
||||
FragmentMainWaterHomeBinding::inflate
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
viewModel.init()
|
||||
|
||||
val recycler = binding.list
|
||||
|
||||
val manager = LinearLayoutManager(requireContext())
|
||||
recycler.layoutManager = manager
|
||||
|
||||
val adapter = WaterAdapter()
|
||||
adapter.onItemClick = {
|
||||
findNavController().navigate(
|
||||
ListWeightFragmentDirections.actionNavListWeightToNavEditWeight(
|
||||
it.id
|
||||
)
|
||||
)
|
||||
//EditWeightDialog().show(requireActivity().supportFragmentManager, "dialog")
|
||||
}
|
||||
recycler.adapter = adapter
|
||||
|
||||
viewModel.items.observe(viewLifecycleOwner) {
|
||||
adapter.set(it)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package com.dzeio.openhealth.ui.water
|
||||
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.dzeio.openhealth.core.BaseViewModel
|
||||
import com.dzeio.openhealth.data.water.Water
|
||||
import com.dzeio.openhealth.data.water.WaterRepository
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class WaterHomeViewModel@Inject internal constructor(
|
||||
private val waterRepository: WaterRepository
|
||||
) : BaseViewModel() {
|
||||
val items: MutableLiveData<List<Water>> = MutableLiveData()
|
||||
|
||||
fun init() {
|
||||
viewModelScope.launch {
|
||||
waterRepository.getWaters().collectLatest {
|
||||
items.postValue(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -2,9 +2,9 @@
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M17.2,3H6.8l-5.2,9l5.2,9h10.4l5.2,-9L17.2,3zM16.05,19H7.95l-4.04,-7l4.04,-7h8.09l4.04,7L16.05,19z"/>
|
||||
android:pathData="M12.0001,1.7144L20.9078,6.8572V17.1429L12.0001,22.2858L3.0924,17.1429V6.8572L12.0001,1.7144Z"
|
||||
android:strokeWidth="2"
|
||||
android:strokeColor="@android:color/white"/>
|
||||
</vector>
|
||||
|
@ -55,6 +55,7 @@
|
||||
android:src="@drawable/ic_baseline_add_24" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/goto_water_home"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:src="@drawable/ic_outline_hexagon_24" />
|
||||
|
62
app/src/main/res/layout/fragment_main_water_home.xml
Normal file
62
app/src/main/res/layout/fragment_main_water_home.xml
Normal file
@ -0,0 +1,62 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
tools:context=".ui.water.WaterHomeFragment">
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
style="?attr/materialCardViewFilledStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginEnd="16dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
|
||||
|
||||
<com.github.mikephil.charting.charts.LineChart
|
||||
android:id="@+id/chart"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="200dp"
|
||||
android:minHeight="200dp" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
android:layout_marginVertical="16dp"
|
||||
android:gravity="end"
|
||||
android:orientation="horizontal"
|
||||
android:weightSum="2">
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/button_edit_default_intake"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
style="?attr/materialButtonOutlinedStyle"
|
||||
android:text="Modify Default Intake" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:clipToPadding="false"
|
||||
android:id="@+id/list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="16dp"
|
||||
|
||||
tools:listitem="@layout/layout_item_weight" />
|
||||
|
||||
</LinearLayout>
|
50
app/src/main/res/layout/layout_item_list.xml
Normal file
50
app/src/main/res/layout/layout_item_list.xml
Normal file
@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
style="?attr/materialCardViewFilledStyle"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:layout_width="match_parent"
|
||||
android:id="@+id/edit"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="16dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:weightSum="1">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/value"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="xkg" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/datetime"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:text="Taken: yyyy-mm-dd" />
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<ImageView
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:src="@drawable/ic_baseline_edit_24" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</com.google.android.material.card.MaterialCardView>
|
@ -24,6 +24,9 @@
|
||||
app:exitAnim="@android:anim/slide_out_right"
|
||||
app:popEnterAnim="@android:anim/slide_in_left"
|
||||
app:popExitAnim="@android:anim/slide_out_right" />
|
||||
<action
|
||||
android:id="@+id/action_nav_home_to_nav_water_home"
|
||||
app:destination="@id/nav_water_home" />
|
||||
</fragment>
|
||||
|
||||
<fragment
|
||||
@ -57,4 +60,12 @@
|
||||
app:argType="long" />
|
||||
|
||||
</fragment>
|
||||
|
||||
<fragment
|
||||
android:id="@+id/nav_water_home"
|
||||
android:name="com.dzeio.openhealth.ui.water.WaterHomeFragment"
|
||||
android:label="@string/nav_water_home"
|
||||
tools:layout="@layout/fragment_water_home">
|
||||
|
||||
</fragment>
|
||||
</navigation>
|
@ -13,4 +13,6 @@
|
||||
<string name="menu_import">Import</string>
|
||||
<string name="menu_list_weight">Weight List</string>
|
||||
<string name="menu_edit_weight">Edit Weight</string>
|
||||
<string name="nav_list_water">Water Intake</string>
|
||||
<string name="nav_water_home">Water Intake</string>
|
||||
</resources>
|
Loading…
x
Reference in New Issue
Block a user