1
0
mirror of https://github.com/dzeiocom/OpenHealth.git synced 2025-04-23 11:22:10 +00:00
This commit is contained in:
Florian Bouillon 2021-12-23 16:47:30 +01:00
parent 8c33478e17
commit e5615c9463
23 changed files with 374 additions and 185 deletions

8
.idea/misc.xml generated
View File

@ -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" />

View File

@ -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"

View File

@ -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
)
)
}
}
}

View File

@ -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)
}
}
}

View File

@ -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

View File

@ -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)

View File

@ -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")

View File

@ -1,4 +1,4 @@
package com.dzeio.openhealth.data.weight
package com.dzeio.openhealth.data.water
import android.util.Log
import kotlinx.coroutines.flow.*

View File

@ -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

View File

@ -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)
}

View File

@ -0,0 +1,5 @@
package com.dzeio.openhealth.interfaces
enum class NotificationIds {
WaterIntake
}

View File

@ -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!")
}
}
}

View File

@ -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()
}
}

View File

@ -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 {

View File

@ -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

View File

@ -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)
}
}
}

View File

@ -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)
}
}
}
}

View File

@ -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>

View File

@ -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" />

View 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>

View 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>

View File

@ -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>

View File

@ -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>