diff --git a/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsBolusCarbsFragment.kt b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsBolusCarbsFragment.kt index a11badfb22..e70e7a9cbe 100644 --- a/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsBolusCarbsFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsBolusCarbsFragment.kt @@ -14,6 +14,7 @@ import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.entities.Bolus import info.nightscout.androidaps.database.entities.BolusCalculatorResult import info.nightscout.androidaps.database.entities.Carbs +import info.nightscout.androidaps.database.entities.UserEntry import info.nightscout.androidaps.database.entities.UserEntry.Action import info.nightscout.androidaps.database.entities.UserEntry.Sources import info.nightscout.androidaps.database.entities.ValueWithUnit @@ -82,8 +83,6 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() { private val disposable = CompositeDisposable() private lateinit var actionHelper: ActionModeHelper private val millsToThePast = T.days(30).msecs() - - // private var selectedItems: SparseArray = SparseArray() private var showInvalidated = false override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View = @@ -98,6 +97,8 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() { setHasOptionsMenu(true) binding.recyclerview.setHasFixedSize(true) binding.recyclerview.layoutManager = LinearLayoutManager(view.context) + binding.recyclerview.emptyView = binding.noRecordsText + binding.recyclerview.loadingView = binding.progressBar } private fun bolusMealLinksWithInvalid(now: Long) = repository @@ -126,7 +127,7 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() { fun swapAdapter() { val now = System.currentTimeMillis() - + binding.recyclerview.isLoading = true disposable += if (showInvalidated) carbsMealLinksWithInvalid(now) diff --git a/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsCareportalFragment.kt b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsCareportalFragment.kt index 8c7423b80e..37713a7e30 100644 --- a/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsCareportalFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsCareportalFragment.kt @@ -73,6 +73,8 @@ class TreatmentsCareportalFragment : DaggerFragment() { setHasOptionsMenu(true) binding.recyclerview.setHasFixedSize(true) binding.recyclerview.layoutManager = LinearLayoutManager(view.context) + binding.recyclerview.emptyView = binding.noRecordsText + binding.recyclerview.loadingView = binding.progressBar } private fun refreshFromNightscout() { @@ -105,6 +107,7 @@ class TreatmentsCareportalFragment : DaggerFragment() { fun swapAdapter() { val now = System.currentTimeMillis() + binding.recyclerview.isLoading = true disposable += if (showInvalidated) repository diff --git a/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsExtendedBolusesFragment.kt b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsExtendedBolusesFragment.kt index da972809ab..b7ffd407c8 100644 --- a/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsExtendedBolusesFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsExtendedBolusesFragment.kt @@ -79,10 +79,13 @@ class TreatmentsExtendedBolusesFragment : DaggerFragment() { setHasOptionsMenu(true) binding.recyclerview.setHasFixedSize(true) binding.recyclerview.layoutManager = LinearLayoutManager(view.context) + binding.recyclerview.emptyView = binding.noRecordsText + binding.recyclerview.loadingView = binding.progressBar } fun swapAdapter() { val now = System.currentTimeMillis() + binding.recyclerview.isLoading = true disposable += if (showInvalidated) repository .getExtendedBolusDataIncludingInvalidFromTime(now - millsToThePast, false) diff --git a/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsProfileSwitchFragment.kt b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsProfileSwitchFragment.kt index 02b160776a..92f9d5f38b 100644 --- a/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsProfileSwitchFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsProfileSwitchFragment.kt @@ -84,6 +84,8 @@ class TreatmentsProfileSwitchFragment : DaggerFragment() { setHasOptionsMenu(true) binding.recyclerview.setHasFixedSize(true) binding.recyclerview.layoutManager = LinearLayoutManager(view.context) + binding.recyclerview.emptyView = binding.noRecordsText + binding.recyclerview.loadingView = binding.progressBar } private fun refreshFromNightscout() { @@ -128,7 +130,7 @@ class TreatmentsProfileSwitchFragment : DaggerFragment() { fun swapAdapter() { val now = System.currentTimeMillis() - + binding.recyclerview.isLoading = true disposable += if (showInvalidated) profileSwitchWithInvalid(now) diff --git a/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsTempTargetFragment.kt b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsTempTargetFragment.kt index b6cb2b2600..028ae4f99a 100644 --- a/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsTempTargetFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsTempTargetFragment.kt @@ -83,6 +83,8 @@ class TreatmentsTempTargetFragment : DaggerFragment() { actionHelper.setOnRemoveHandler { removeSelected(it) } setHasOptionsMenu(true) binding.recyclerview.layoutManager = LinearLayoutManager(view.context) + binding.recyclerview.emptyView = binding.noRecordsText + binding.recyclerview.loadingView = binding.progressBar } private fun refreshFromNightscout() { @@ -111,6 +113,7 @@ class TreatmentsTempTargetFragment : DaggerFragment() { fun swapAdapter() { val now = System.currentTimeMillis() + binding.recyclerview.isLoading = true disposable += if (showInvalidated) repository diff --git a/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsTemporaryBasalsFragment.kt b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsTemporaryBasalsFragment.kt index 7736d02895..da76998092 100644 --- a/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsTemporaryBasalsFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsTemporaryBasalsFragment.kt @@ -84,6 +84,8 @@ class TreatmentsTemporaryBasalsFragment : DaggerFragment() { setHasOptionsMenu(true) binding.recyclerview.setHasFixedSize(true) binding.recyclerview.layoutManager = LinearLayoutManager(view.context) + binding.recyclerview.emptyView = binding.noRecordsText + binding.recyclerview.loadingView = binding.progressBar } private fun tempBasalsWithInvalid(now: Long) = repository @@ -102,6 +104,7 @@ class TreatmentsTemporaryBasalsFragment : DaggerFragment() { fun swapAdapter() { val now = System.currentTimeMillis() + binding.recyclerview.isLoading = true disposable += if (activePlugin.activePump.isFakingTempsByExtendedBoluses) { if (showInvalidated) diff --git a/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsUserEntryFragment.kt b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsUserEntryFragment.kt index e59fa71805..0303f5bf7c 100644 --- a/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsUserEntryFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsUserEntryFragment.kt @@ -63,6 +63,8 @@ class TreatmentsUserEntryFragment : DaggerFragment() { setHasOptionsMenu(true) binding.recyclerview.setHasFixedSize(true) binding.recyclerview.layoutManager = LinearLayoutManager(view.context) + binding.recyclerview.emptyView = binding.noRecordsText + binding.recyclerview.loadingView = binding.progressBar } private fun exportUserEntries() { @@ -76,6 +78,7 @@ class TreatmentsUserEntryFragment : DaggerFragment() { fun swapAdapter() { val now = System.currentTimeMillis() + binding.recyclerview.isLoading = true disposable += if (showLoop) repository diff --git a/app/src/main/res/layout/treatments_bolus_carbs_fragment.xml b/app/src/main/res/layout/treatments_bolus_carbs_fragment.xml index 388a6a9976..665a0db410 100644 --- a/app/src/main/res/layout/treatments_bolus_carbs_fragment.xml +++ b/app/src/main/res/layout/treatments_bolus_carbs_fragment.xml @@ -1,13 +1,32 @@ - - + + + + + android:layout_height="match_parent" + android:layout_alignParentTop="true" /> - + diff --git a/app/src/main/res/layout/treatments_bolus_carbs_item.xml b/app/src/main/res/layout/treatments_bolus_carbs_item.xml index 850bc3dc48..5c3c7502b6 100644 --- a/app/src/main/res/layout/treatments_bolus_carbs_item.xml +++ b/app/src/main/res/layout/treatments_bolus_carbs_item.xml @@ -1,12 +1,11 @@ + app:cardBackgroundColor="?attr/colorSurface"> + tools:text="1.1.2000" /> + tools:ignore="RtlSymmetry" + tools:text="{fa-clock-o}" /> + tools:ignore="RtlSymmetry" + tools:text="11:45" /> + tools:ignore="RtlSymmetry" + tools:text="{fa-clock-o}" /> + tools:ignore="RtlSymmetry" + tools:text="11:45" /> + tools:text="1.00 U" /> + tools:text="0.45U" /> + tools:text="Meal" /> + tools:text="NS" /> + tools:text="PH" /> + tools:ignore="RtlSymmetry" + tools:text="{fa-clock-o}" /> + tools:ignore="RtlSymmetry" + tools:text="11:45" /> + tools:text="NS" /> + tools:text="PH" /> - + + + + + android:layout_height="match_parent" + android:layout_alignParentTop="true" /> - + diff --git a/app/src/main/res/layout/treatments_careportal_item.xml b/app/src/main/res/layout/treatments_careportal_item.xml index 474c05f8c3..bb4fff2681 100644 --- a/app/src/main/res/layout/treatments_careportal_item.xml +++ b/app/src/main/res/layout/treatments_careportal_item.xml @@ -1,11 +1,11 @@ + app:cardBackgroundColor="?attr/colorSurface"> + tools:text="1.1.2000" /> + tools:text="{fa-clock-o}" /> + tools:ignore="RtlSymmetry" + tools:text="18:00" /> + tools:text="NS" /> + tools:ignore="RtlSymmetry" + tools:text="Activity" /> - + + + + + android:layout_height="match_parent" + android:layout_alignParentTop="true" /> - + diff --git a/app/src/main/res/layout/treatments_extendedbolus_item.xml b/app/src/main/res/layout/treatments_extendedbolus_item.xml index ffc0d10fd5..587a3e6410 100644 --- a/app/src/main/res/layout/treatments_extendedbolus_item.xml +++ b/app/src/main/res/layout/treatments_extendedbolus_item.xml @@ -1,11 +1,11 @@ + app:cardBackgroundColor="?attr/colorSurface"> + tools:text="1.1.2000" /> + tools:text="{fa-clock-o}" /> + tools:text="18:00" /> + tools:ignore="RtlSymmetry" + tools:text="150%" /> + tools:ignore="RtlSymmetry" + tools:text="30 min" /> + tools:text="PH" /> + tools:text="NS" /> @@ -104,7 +99,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="top" - android:paddingLeft="10dp" + android:paddingStart="10dp" android:paddingEnd="5dp" android:text="@string/tempbasals_netratio_label_string" android:textAppearance="?android:attr/textAppearanceSmall" @@ -116,17 +111,18 @@ android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:paddingEnd="10dp" - android:text="0.05 U/h" android:textStyle="bold" - tools:ignore="HardcodedText,RtlSymmetry" /> + tools:ignore="RtlSymmetry" + tools:text="0.05 U/h" /> + android:textAppearance="?android:attr/textAppearanceSmall" + tools:ignore="RtlSymmetry" /> + tools:text="0.12 U" /> diff --git a/app/src/main/res/layout/treatments_profileswitch_fragment.xml b/app/src/main/res/layout/treatments_profileswitch_fragment.xml index bc459add30..ea767a0ae8 100644 --- a/app/src/main/res/layout/treatments_profileswitch_fragment.xml +++ b/app/src/main/res/layout/treatments_profileswitch_fragment.xml @@ -1,13 +1,32 @@ - - + + + + + android:layout_height="match_parent" + android:layout_alignParentTop="true" /> - + diff --git a/app/src/main/res/layout/treatments_profileswitch_item.xml b/app/src/main/res/layout/treatments_profileswitch_item.xml index fcac08f883..ee4331c46a 100644 --- a/app/src/main/res/layout/treatments_profileswitch_item.xml +++ b/app/src/main/res/layout/treatments_profileswitch_item.xml @@ -1,11 +1,11 @@ + app:cardBackgroundColor="?attr/colorSurface"> + tools:text="1.1.2000" /> + tools:text="{fa-clock-o}" /> + tools:ignore="RtlSymmetry" + tools:text="18:00" /> + tools:ignore="RtlSymmetry" + tools:text="Name" /> + tools:ignore="RtlSymmetry" + tools:text="PH" /> + tools:ignore="RtlSymmetry" + tools:text="NS" /> @@ -93,9 +91,9 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingStart="10dp" - android:text="60 min" android:textAppearance="?android:attr/textAppearanceSmall" - tools:ignore="HardcodedText,RtlSymmetry" /> + tools:ignore="RtlSymmetry" + tools:text="60 min" /> - + + + + + android:layout_height="match_parent" + android:layout_alignParentTop="true" /> - + diff --git a/app/src/main/res/layout/treatments_tempbasals_item.xml b/app/src/main/res/layout/treatments_tempbasals_item.xml index 9788110bb7..94840ce53a 100644 --- a/app/src/main/res/layout/treatments_tempbasals_item.xml +++ b/app/src/main/res/layout/treatments_tempbasals_item.xml @@ -1,11 +1,11 @@ + app:cardBackgroundColor="?attr/colorSurface"> + tools:text="1.1.2000" /> + tools:text="{fa-clock-o}" /> + tools:text="18:00" /> + tools:ignore="RtlSymmetry" + tools:text="150%" /> + tools:ignore="RtlSymmetry" + tools:text="30 min" /> + tools:ignore="RtlSymmetry" + tools:text="E" /> + tools:ignore="RtlSymmetry" + tools:text="S" /> + tools:ignore="RtlSymmetry" + tools:text="ES" /> + tools:ignore="RtlSymmetry" + tools:text="SB" /> + tools:text="PH" /> + tools:text="NS" /> + tools:text="0.12 U" /> - + + + + + android:layout_height="match_parent" + android:layout_alignParentTop="true" /> - + diff --git a/app/src/main/res/layout/treatments_temptarget_item.xml b/app/src/main/res/layout/treatments_temptarget_item.xml index 4b3ba949ed..b6a5ce8e0c 100644 --- a/app/src/main/res/layout/treatments_temptarget_item.xml +++ b/app/src/main/res/layout/treatments_temptarget_item.xml @@ -1,11 +1,11 @@ + app:cardBackgroundColor="?attr/colorSurface"> + tools:text="1.1.2000" /> + tools:text="{fa-clock-o}" /> + tools:ignore="RtlSymmetry" + tools:text="1.1.2000 18:00" /> + tools:ignore="RtlSymmetry" + tools:text="80" /> + tools:ignore="RtlSymmetry" + tools:text="-" /> + tools:ignore="RtlSymmetry" + tools:text="100" /> + tools:ignore="RtlSymmetry" + tools:text="30 min" /> + tools:text="NS" /> @@ -134,9 +131,9 @@ android:layout_gravity="center_vertical" android:layout_weight="1" android:paddingEnd="10dp" - android:text="Activity" android:textStyle="bold" - tools:ignore="HardcodedText,RtlSymmetry" /> + tools:ignore="RtlSymmetry" + tools:text="Activity" /> - + + + + + android:layout_height="match_parent" + android:layout_alignParentTop="true" /> - + diff --git a/app/src/main/res/layout/treatments_user_entry_item.xml b/app/src/main/res/layout/treatments_user_entry_item.xml index d16db3746d..04110b1e3d 100644 --- a/app/src/main/res/layout/treatments_user_entry_item.xml +++ b/app/src/main/res/layout/treatments_user_entry_item.xml @@ -17,11 +17,11 @@ android:layout_marginBottom="5dp" android:background="?android:attr/dividerHorizontal" android:gravity="center" - android:text="1.1.2000" android:textAppearance="?android:attr/textAppearanceMedium" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" - tools:ignore="HardcodedText,RtlSymmetry" /> + tools:ignore="RtlSymmetry" + tools:text="1.1.2000" /> + tools:ignore="RtlSymmetry" + tools:text="09:00" /> + app:layout_constraintTop_toBottomOf="@id/date" + tools:ignore="RtlSymmetry" + tools:text="USER ENTRY" /> + app:srcCompat="@drawable/ic_cp_bolus_carbs" + tools:ignore="contentDescription" /> + app:layout_constraintTop_toBottomOf="@id/action" + tools:text="Values with units" /> + tools:ignore="RtlSymmetry" + tools:text="Notes" /> Temp Targets Carbs and bolus Are you sure you want to remove %1$d items + No records available Hide loop Show loop %1$d selected diff --git a/core/src/main/java/info/nightscout/androidaps/extensions/EmptyRecyclerView.kt b/core/src/main/java/info/nightscout/androidaps/extensions/EmptyRecyclerView.kt new file mode 100644 index 0000000000..b9a8aba3c5 --- /dev/null +++ b/core/src/main/java/info/nightscout/androidaps/extensions/EmptyRecyclerView.kt @@ -0,0 +1,89 @@ +package info.nightscout.androidaps.extensions + +import android.content.Context +import android.util.AttributeSet +import android.view.View +import androidx.recyclerview.widget.RecyclerView + +class EmptyRecyclerView : RecyclerView { + + private var mEmptyView: View? = null + private var mLoadingView: View? = null + private var mIsLoading = true + + constructor(context: Context) : super(context) + constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) + constructor(context: Context, attrs: AttributeSet?, defStyle: Int) : super(context, attrs, defStyle) + + private fun updateEmptyView() { + runOnUiThread { + val isEmpty = !mIsLoading && (adapter == null || adapter?.itemCount == 0) + visibility = isEmpty.not().toVisibility() + mEmptyView?.visibility = isEmpty.toVisibility() + } + } + + private fun updateLoadingView() { + runOnUiThread { + mLoadingView?.visibility = mIsLoading.toVisibility() + } + } + + private val observer: AdapterDataObserver = object : AdapterDataObserver() { + override fun onChanged() { + super.onChanged() + updateEmptyView() + } + + override fun onItemRangeInserted(positionStart: Int, itemCount: Int) { + super.onItemRangeInserted(positionStart, itemCount) + updateEmptyView() + } + + override fun onItemRangeRemoved(positionStart: Int, itemCount: Int) { + super.onItemRangeRemoved(positionStart, itemCount) + updateEmptyView() + } + } + + override fun setAdapter(adapter: Adapter<*>?) { + val oldAdapter = getAdapter() + super.setAdapter(adapter) + update(oldAdapter, adapter) + } + + override fun swapAdapter(adapter: Adapter<*>?, removeAndRecycleExistingViews: Boolean) { + val oldAdapter = getAdapter() + super.swapAdapter(adapter, removeAndRecycleExistingViews) + update(oldAdapter, adapter) + } + + var emptyView: View? + get() = mEmptyView + set(view) { + mEmptyView = view + updateEmptyView() + } + + var loadingView: View? + get() = mLoadingView + set(view) { + mLoadingView = view + updateLoadingView() + } + + var isLoading: Boolean + get() = mIsLoading + set(loading) { + mIsLoading = loading + updateLoadingView() + } + + private fun update(oldAdapter: Adapter<*>?, newAdapter: Adapter<*>?) { + oldAdapter?.unregisterAdapterDataObserver(observer) + newAdapter?.registerAdapterDataObserver(observer) + updateEmptyView() + isLoading = false + updateLoadingView() + } +}