FoodFragment -> jetpack

This commit is contained in:
Milos Kozak 2021-01-25 11:35:36 +01:00
parent c3878de916
commit aeec33eb9e
4 changed files with 135 additions and 125 deletions

View file

@ -1,5 +1,6 @@
package info.nightscout.androidaps.plugins.general.food package info.nightscout.androidaps.plugins.general.food
import android.annotation.SuppressLint
import android.content.DialogInterface import android.content.DialogInterface
import android.graphics.Paint import android.graphics.Paint
import android.os.Bundle import android.os.Bundle
@ -10,11 +11,12 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.AdapterView import android.widget.AdapterView
import android.widget.ArrayAdapter import android.widget.ArrayAdapter
import android.widget.TextView
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import dagger.android.support.DaggerFragment import dagger.android.support.DaggerFragment
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.databinding.FoodFragmentBinding
import info.nightscout.androidaps.databinding.FoodItemBinding
import info.nightscout.androidaps.events.EventFoodDatabaseChanged import info.nightscout.androidaps.events.EventFoodDatabaseChanged
import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.general.food.FoodFragment.RecyclerViewAdapter.FoodsViewHolder import info.nightscout.androidaps.plugins.general.food.FoodFragment.RecyclerViewAdapter.FoodsViewHolder
@ -24,7 +26,6 @@ import info.nightscout.androidaps.utils.alertDialogs.OKDialog.showConfirmation
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
import kotlinx.android.synthetic.main.food_fragment.*
import java.util.* import java.util.*
import javax.inject.Inject import javax.inject.Inject
import kotlin.collections.ArrayList import kotlin.collections.ArrayList
@ -41,24 +42,32 @@ class FoodFragment : DaggerFragment() {
private lateinit var unfiltered: List<Food> private lateinit var unfiltered: List<Food>
private lateinit var filtered: MutableList<Food> private lateinit var filtered: MutableList<Food>
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { private var _binding: FoodFragmentBinding? = null
return inflater.inflate(R.layout.food_fragment, container, false)
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
_binding = FoodFragmentBinding.inflate(inflater, container, false)
return binding.root
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
food_recyclerview.setHasFixedSize(true) binding.recyclerview.setHasFixedSize(true)
food_recyclerview.layoutManager = LinearLayoutManager(view.context) binding.recyclerview.layoutManager = LinearLayoutManager(view.context)
food_recyclerview.adapter = RecyclerViewAdapter(foodPlugin.service?.foodData ?: ArrayList()) binding.recyclerview.adapter = RecyclerViewAdapter(foodPlugin.service?.foodData
?: ArrayList())
food_clearfilter.setOnClickListener { binding.clearfilter.setOnClickListener {
food_filter.setText("") binding.filter.setText("")
food_category.setSelection(0) binding.category.setSelection(0)
food_subcategory.setSelection(0) binding.subcategory.setSelection(0)
filterData() filterData()
} }
food_category.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { binding.category.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
fillSubcategories() fillSubcategories()
filterData() filterData()
@ -69,7 +78,7 @@ class FoodFragment : DaggerFragment() {
filterData() filterData()
} }
} }
food_subcategory.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { binding.subcategory.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
filterData() filterData()
} }
@ -78,7 +87,7 @@ class FoodFragment : DaggerFragment() {
filterData() filterData()
} }
} }
food_filter.addTextChangedListener(object : TextWatcher { binding.filter.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {} override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) { override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
filterData() filterData()
@ -92,7 +101,8 @@ class FoodFragment : DaggerFragment() {
filterData() filterData()
} }
@Synchronized override fun onResume() { @Synchronized
override fun onResume() {
super.onResume() super.onResume()
disposable.add(rxBus disposable.add(rxBus
.toObservable(EventFoodDatabaseChanged::class.java) .toObservable(EventFoodDatabaseChanged::class.java)
@ -102,11 +112,18 @@ class FoodFragment : DaggerFragment() {
updateGui() updateGui()
} }
@Synchronized override fun onPause() { @Synchronized
override fun onPause() {
super.onPause() super.onPause()
disposable.clear() disposable.clear()
} }
@Synchronized
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
private fun loadData() { private fun loadData() {
unfiltered = foodPlugin.service?.foodData ?: ArrayList() unfiltered = foodPlugin.service?.foodData ?: ArrayList()
} }
@ -121,12 +138,12 @@ class FoodFragment : DaggerFragment() {
categories.add(0, resourceHelper.gs(R.string.none)) categories.add(0, resourceHelper.gs(R.string.none))
context?.let { context -> context?.let { context ->
val adapterCategories = ArrayAdapter(context, R.layout.spinner_centered, categories) val adapterCategories = ArrayAdapter(context, R.layout.spinner_centered, categories)
food_category.adapter = adapterCategories binding.category.adapter = adapterCategories
} }
} }
private fun fillSubcategories() { private fun fillSubcategories() {
val categoryFilter = food_category.selectedItem.toString() val categoryFilter = binding.category.selectedItem.toString()
val subCatSet: MutableSet<CharSequence> = HashSet() val subCatSet: MutableSet<CharSequence> = HashSet()
if (categoryFilter != resourceHelper.gs(R.string.none)) { if (categoryFilter != resourceHelper.gs(R.string.none)) {
for (f in unfiltered) { for (f in unfiltered) {
@ -138,65 +155,61 @@ class FoodFragment : DaggerFragment() {
subcategories.add(0, resourceHelper.gs(R.string.none)) subcategories.add(0, resourceHelper.gs(R.string.none))
context?.let { context -> context?.let { context ->
val adapterSubcategories = ArrayAdapter(context, R.layout.spinner_centered, subcategories) val adapterSubcategories = ArrayAdapter(context, R.layout.spinner_centered, subcategories)
food_subcategory.adapter = adapterSubcategories binding.subcategory.adapter = adapterSubcategories
} }
} }
private fun filterData() { private fun filterData() {
val textFilter = food_filter.text.toString() val textFilter = binding.filter.text.toString()
val categoryFilter = food_category.selectedItem.toString() val categoryFilter = binding.category.selectedItem.toString()
val subcategoryFilter = food_subcategory.selectedItem.toString() val subcategoryFilter = binding.subcategory.selectedItem.toString()
val newfiltered = ArrayList<Food>() val newFiltered = ArrayList<Food>()
for (f in unfiltered) { for (f in unfiltered) {
if (f.name == null || f.category == null || f.subcategory == null) continue if (f.name == null || f.category == null || f.subcategory == null) continue
if (subcategoryFilter != resourceHelper.gs(R.string.none) && f.subcategory != subcategoryFilter) continue if (subcategoryFilter != resourceHelper.gs(R.string.none) && f.subcategory != subcategoryFilter) continue
if (categoryFilter != resourceHelper.gs(R.string.none) && f.category != categoryFilter) continue if (categoryFilter != resourceHelper.gs(R.string.none) && f.category != categoryFilter) continue
if (textFilter != "" && !f.name.toLowerCase(Locale.getDefault()).contains(textFilter.toLowerCase(Locale.getDefault()))) continue if (textFilter != "" && !f.name.toLowerCase(Locale.getDefault()).contains(textFilter.toLowerCase(Locale.getDefault()))) continue
newfiltered.add(f) newFiltered.add(f)
} }
filtered = newfiltered filtered = newFiltered
updateGui() updateGui()
} }
protected fun updateGui() { private fun updateGui() {
food_recyclerview?.swapAdapter(RecyclerViewAdapter(filtered), true) binding.recyclerview.swapAdapter(RecyclerViewAdapter(filtered), true)
} }
inner class RecyclerViewAdapter internal constructor(var foodList: List<Food>) : RecyclerView.Adapter<FoodsViewHolder>() { inner class RecyclerViewAdapter internal constructor(var foodList: List<Food>) : RecyclerView.Adapter<FoodsViewHolder>() {
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): FoodsViewHolder { override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): FoodsViewHolder {
val v = LayoutInflater.from(viewGroup.context).inflate(R.layout.food_item, viewGroup, false) val v = LayoutInflater.from(viewGroup.context).inflate(R.layout.food_item, viewGroup, false)
return FoodsViewHolder(v) return FoodsViewHolder(v)
} }
@SuppressLint("SetTextI18n")
override fun onBindViewHolder(holder: FoodsViewHolder, position: Int) { override fun onBindViewHolder(holder: FoodsViewHolder, position: Int) {
val food = foodList[position] val food = foodList[position]
holder.ns.visibility = if (food._id != null) View.VISIBLE else View.GONE holder.binding.nsSign.visibility = if (food._id != null) View.VISIBLE else View.GONE
holder.name.text = food.name holder.binding.name.text = food.name
holder.portion.text = food.portion.toString() + food.units holder.binding.portion.text = food.portion.toString() + food.units
holder.carbs.text = food.carbs.toString() + resourceHelper.gs(R.string.shortgramm) holder.binding.carbs.text = food.carbs.toString() + resourceHelper.gs(R.string.shortgramm)
holder.fat.text = resourceHelper.gs(R.string.shortfat) + ": " + food.fat + resourceHelper.gs(R.string.shortgramm) holder.binding.fat.text = resourceHelper.gs(R.string.shortfat) + ": " + food.fat + resourceHelper.gs(R.string.shortgramm)
if (food.fat == 0) holder.fat.visibility = View.INVISIBLE if (food.fat == 0) holder.binding.fat.visibility = View.INVISIBLE
holder.protein.text = resourceHelper.gs(R.string.shortprotein) + ": " + food.protein + resourceHelper.gs(R.string.shortgramm) holder.binding.protein.text = resourceHelper.gs(R.string.shortprotein) + ": " + food.protein + resourceHelper.gs(R.string.shortgramm)
if (food.protein == 0) holder.protein.visibility = View.INVISIBLE if (food.protein == 0) holder.binding.protein.visibility = View.INVISIBLE
holder.energy.text = resourceHelper.gs(R.string.shortenergy) + ": " + food.energy + resourceHelper.gs(R.string.shortkilojoul) holder.binding.energy.text = resourceHelper.gs(R.string.shortenergy) + ": " + food.energy + resourceHelper.gs(R.string.shortkilojoul)
if (food.energy == 0) holder.energy.visibility = View.INVISIBLE if (food.energy == 0) holder.binding.energy.visibility = View.INVISIBLE
holder.remove.tag = food holder.binding.remove.tag = food
} }
override fun getItemCount(): Int = foodList.size override fun getItemCount(): Int = foodList.size
inner class FoodsViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { inner class FoodsViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var name: TextView = itemView.findViewById(R.id.food_name)
var portion: TextView = itemView.findViewById(R.id.food_portion) val binding = FoodItemBinding.bind(itemView)
var carbs: TextView = itemView.findViewById(R.id.food_carbs)
var fat: TextView = itemView.findViewById(R.id.food_fat)
var protein: TextView = itemView.findViewById(R.id.food_protein)
var energy: TextView = itemView.findViewById(R.id.food_energy)
var ns: TextView = itemView.findViewById(R.id.ns_sign)
var remove: TextView = itemView.findViewById(R.id.food_remove)
init { init {
remove.setOnClickListener { v: View -> binding.remove.setOnClickListener { v: View ->
val food = v.tag as Food val food = v.tag as Food
activity?.let { activity -> activity?.let { activity ->
showConfirmation(activity, resourceHelper.gs(R.string.confirmation), resourceHelper.gs(R.string.removerecord) + "\n" + food.name, DialogInterface.OnClickListener { _: DialogInterface?, _: Int -> showConfirmation(activity, resourceHelper.gs(R.string.confirmation), resourceHelper.gs(R.string.removerecord) + "\n" + food.name, DialogInterface.OnClickListener { _: DialogInterface?, _: Int ->
@ -207,7 +220,7 @@ class FoodFragment : DaggerFragment() {
}, null) }, null)
} }
} }
remove.paintFlags = remove.paintFlags or Paint.UNDERLINE_TEXT_FLAG binding.remove.paintFlags = binding.remove.paintFlags or Paint.UNDERLINE_TEXT_FLAG
} }
} }
} }

View file

@ -1,89 +1,86 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical"
tools:context="info.nightscout.androidaps.plugins.treatments.fragments.TreatmentsExtendedBolusesFragment"> tools:context="info.nightscout.androidaps.plugins.treatments.fragments.TreatmentsExtendedBolusesFragment">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:orientation="vertical"> android:orientation="horizontal">
<LinearLayout <ImageView
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal"> android:contentDescription="@string/filter"
android:paddingLeft="5dp"
android:paddingRight="5dp"
app:srcCompat="@android:drawable/ic_menu_search" />
<ImageView <EditText
android:layout_width="wrap_content" android:id="@+id/filter"
android:paddingLeft="5dp" android:layout_width="0dp"
android:paddingRight="5dp"
app:srcCompat="@android:drawable/ic_menu_search"
android:layout_height="wrap_content" />
<EditText
android:id="@+id/food_filter"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:inputType="text"
android:text="" />
<ImageView
android:id="@+id/food_clearfilter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="5dp"
android:paddingRight="5dp"
app:srcCompat="@android:drawable/ic_menu_close_clear_cancel" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="5dp" android:layout_weight="1"
android:orientation="horizontal"> android:autofillHints="@string/filter"
android:ems="10"
android:inputType="text"
android:text="" />
<TextView <ImageView
android:layout_width="wrap_content" android:id="@+id/clearfilter"
android:layout_height="wrap_content" android:layout_width="wrap_content"
android:text="@string/category" /> android:layout_height="wrap_content"
android:contentDescription="@string/clear_filter"
android:paddingLeft="5dp"
android:paddingRight="5dp"
app:srcCompat="@android:drawable/ic_menu_close_clear_cancel" />
</LinearLayout>
<Spinner <LinearLayout
android:id="@+id/food_category" android:layout_width="match_parent"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:layout_marginBottom="5dp"
android:gravity="right" android:orientation="horizontal">
android:minWidth="100dp" />
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" /> android:text="@string/category" />
<TextView <Spinner
android:layout_width="wrap_content" android:id="@+id/category"
android:layout_height="wrap_content" android:layout_width="wrap_content"
android:text="@string/subcategory" /> android:layout_height="wrap_content"
android:gravity="end"
android:minWidth="100dp" />
<Spinner <TextView
android:id="@+id/food_subcategory" android:layout_width="0dp"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:layout_weight="1" />
android:gravity="right"
android:minWidth="100dp" />
</LinearLayout> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/subcategory" />
<androidx.recyclerview.widget.RecyclerView <Spinner
android:id="@+id/food_recyclerview" android:id="@+id/subcategory"
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="match_parent"> android:layout_height="wrap_content"
android:gravity="end"
</androidx.recyclerview.widget.RecyclerView> android:minWidth="100dp" />
</LinearLayout> </LinearLayout>
</FrameLayout> <androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent">
</androidx.recyclerview.widget.RecyclerView>
</LinearLayout>

View file

@ -21,23 +21,22 @@
android:orientation="horizontal"> android:orientation="horizontal">
<TextView <TextView
android:id="@+id/food_name" android:id="@+id/name"
android:layout_width="wrap_content" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_weight="1"
android:inputType="textMultiLine|textNoSuggestions"
android:text="Name" android:text="Name"
android:textStyle="bold" /> android:textStyle="bold" />
<TextView <TextView
android:id="@+id/food_portion" android:id="@+id/portion"
android:layout_width="60dp" android:layout_width="60dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="end" android:gravity="end"
android:text="Portion" /> android:text="Portion" />
<TextView <TextView
android:id="@+id/food_carbs" android:id="@+id/carbs"
android:layout_width="50dp" android:layout_width="50dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="end" android:gravity="end"
@ -47,27 +46,27 @@
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="0dp"
android:layout_weight="1" android:layout_weight="1"
android:gravity="end" android:gravity="end"
android:orientation="horizontal"> android:orientation="horizontal">
<TextView <TextView
android:id="@+id/food_fat" android:id="@+id/fat"
android:layout_width="70dp" android:layout_width="70dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="end" android:gravity="end"
android:text="Fat" /> android:text="Fat" />
<TextView <TextView
android:id="@+id/food_protein" android:id="@+id/protein"
android:layout_width="70dp" android:layout_width="70dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="end" android:gravity="end"
android:text="Protein" /> android:text="Protein" />
<TextView <TextView
android:id="@+id/food_energy" android:id="@+id/energy"
android:layout_width="70dp" android:layout_width="70dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="end" android:gravity="end"
@ -83,7 +82,7 @@
android:textColor="@color/colorSetTempButton" /> android:textColor="@color/colorSetTempButton" />
<TextView <TextView
android:id="@+id/food_remove" android:id="@+id/remove"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingEnd="5dp" android:paddingEnd="5dp"

View file

@ -1381,5 +1381,6 @@
<string name="fabric_upload_disabled">Crash logs upload disabled!</string> <string name="fabric_upload_disabled">Crash logs upload disabled!</string>
<string name="graph_menu_divider_header">Graph</string> <string name="graph_menu_divider_header">Graph</string>
<string name="chart_menu">Chart menu</string> <string name="chart_menu">Chart menu</string>
<string name="clear_filter">Clear filter</string>
</resources> </resources>