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
import android.annotation.SuppressLint
import android.content.DialogInterface
import android.graphics.Paint
import android.os.Bundle
@ -10,11 +11,12 @@ import android.view.View
import android.view.ViewGroup
import android.widget.AdapterView
import android.widget.ArrayAdapter
import android.widget.TextView
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import dagger.android.support.DaggerFragment
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.plugins.bus.RxBusWrapper
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 io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import kotlinx.android.synthetic.main.food_fragment.*
import java.util.*
import javax.inject.Inject
import kotlin.collections.ArrayList
@ -41,24 +42,32 @@ class FoodFragment : DaggerFragment() {
private lateinit var unfiltered: List<Food>
private lateinit var filtered: MutableList<Food>
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.food_fragment, container, false)
private var _binding: FoodFragmentBinding? = null
// 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?) {
super.onViewCreated(view, savedInstanceState)
food_recyclerview.setHasFixedSize(true)
food_recyclerview.layoutManager = LinearLayoutManager(view.context)
food_recyclerview.adapter = RecyclerViewAdapter(foodPlugin.service?.foodData ?: ArrayList())
binding.recyclerview.setHasFixedSize(true)
binding.recyclerview.layoutManager = LinearLayoutManager(view.context)
binding.recyclerview.adapter = RecyclerViewAdapter(foodPlugin.service?.foodData
?: ArrayList())
food_clearfilter.setOnClickListener {
food_filter.setText("")
food_category.setSelection(0)
food_subcategory.setSelection(0)
binding.clearfilter.setOnClickListener {
binding.filter.setText("")
binding.category.setSelection(0)
binding.subcategory.setSelection(0)
filterData()
}
food_category.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
binding.category.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
fillSubcategories()
filterData()
@ -69,7 +78,7 @@ class FoodFragment : DaggerFragment() {
filterData()
}
}
food_subcategory.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
binding.subcategory.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
filterData()
}
@ -78,7 +87,7 @@ class FoodFragment : DaggerFragment() {
filterData()
}
}
food_filter.addTextChangedListener(object : TextWatcher {
binding.filter.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
filterData()
@ -92,7 +101,8 @@ class FoodFragment : DaggerFragment() {
filterData()
}
@Synchronized override fun onResume() {
@Synchronized
override fun onResume() {
super.onResume()
disposable.add(rxBus
.toObservable(EventFoodDatabaseChanged::class.java)
@ -102,11 +112,18 @@ class FoodFragment : DaggerFragment() {
updateGui()
}
@Synchronized override fun onPause() {
@Synchronized
override fun onPause() {
super.onPause()
disposable.clear()
}
@Synchronized
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
private fun loadData() {
unfiltered = foodPlugin.service?.foodData ?: ArrayList()
}
@ -121,12 +138,12 @@ class FoodFragment : DaggerFragment() {
categories.add(0, resourceHelper.gs(R.string.none))
context?.let { context ->
val adapterCategories = ArrayAdapter(context, R.layout.spinner_centered, categories)
food_category.adapter = adapterCategories
binding.category.adapter = adapterCategories
}
}
private fun fillSubcategories() {
val categoryFilter = food_category.selectedItem.toString()
val categoryFilter = binding.category.selectedItem.toString()
val subCatSet: MutableSet<CharSequence> = HashSet()
if (categoryFilter != resourceHelper.gs(R.string.none)) {
for (f in unfiltered) {
@ -138,65 +155,61 @@ class FoodFragment : DaggerFragment() {
subcategories.add(0, resourceHelper.gs(R.string.none))
context?.let { context ->
val adapterSubcategories = ArrayAdapter(context, R.layout.spinner_centered, subcategories)
food_subcategory.adapter = adapterSubcategories
binding.subcategory.adapter = adapterSubcategories
}
}
private fun filterData() {
val textFilter = food_filter.text.toString()
val categoryFilter = food_category.selectedItem.toString()
val subcategoryFilter = food_subcategory.selectedItem.toString()
val newfiltered = ArrayList<Food>()
val textFilter = binding.filter.text.toString()
val categoryFilter = binding.category.selectedItem.toString()
val subcategoryFilter = binding.subcategory.selectedItem.toString()
val newFiltered = ArrayList<Food>()
for (f in unfiltered) {
if (f.name == null || f.category == null || f.subcategory == null) continue
if (subcategoryFilter != resourceHelper.gs(R.string.none) && f.subcategory != subcategoryFilter) 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
newfiltered.add(f)
newFiltered.add(f)
}
filtered = newfiltered
filtered = newFiltered
updateGui()
}
protected fun updateGui() {
food_recyclerview?.swapAdapter(RecyclerViewAdapter(filtered), true)
private fun updateGui() {
binding.recyclerview.swapAdapter(RecyclerViewAdapter(filtered), true)
}
inner class RecyclerViewAdapter internal constructor(var foodList: List<Food>) : RecyclerView.Adapter<FoodsViewHolder>() {
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): FoodsViewHolder {
val v = LayoutInflater.from(viewGroup.context).inflate(R.layout.food_item, viewGroup, false)
return FoodsViewHolder(v)
}
@SuppressLint("SetTextI18n")
override fun onBindViewHolder(holder: FoodsViewHolder, position: Int) {
val food = foodList[position]
holder.ns.visibility = if (food._id != null) View.VISIBLE else View.GONE
holder.name.text = food.name
holder.portion.text = food.portion.toString() + food.units
holder.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)
if (food.fat == 0) holder.fat.visibility = View.INVISIBLE
holder.protein.text = resourceHelper.gs(R.string.shortprotein) + ": " + food.protein + resourceHelper.gs(R.string.shortgramm)
if (food.protein == 0) holder.protein.visibility = View.INVISIBLE
holder.energy.text = resourceHelper.gs(R.string.shortenergy) + ": " + food.energy + resourceHelper.gs(R.string.shortkilojoul)
if (food.energy == 0) holder.energy.visibility = View.INVISIBLE
holder.remove.tag = food
holder.binding.nsSign.visibility = if (food._id != null) View.VISIBLE else View.GONE
holder.binding.name.text = food.name
holder.binding.portion.text = food.portion.toString() + food.units
holder.binding.carbs.text = food.carbs.toString() + 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.binding.fat.visibility = View.INVISIBLE
holder.binding.protein.text = resourceHelper.gs(R.string.shortprotein) + ": " + food.protein + resourceHelper.gs(R.string.shortgramm)
if (food.protein == 0) holder.binding.protein.visibility = View.INVISIBLE
holder.binding.energy.text = resourceHelper.gs(R.string.shortenergy) + ": " + food.energy + resourceHelper.gs(R.string.shortkilojoul)
if (food.energy == 0) holder.binding.energy.visibility = View.INVISIBLE
holder.binding.remove.tag = food
}
override fun getItemCount(): Int = foodList.size
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)
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)
val binding = FoodItemBinding.bind(itemView)
init {
remove.setOnClickListener { v: View ->
binding.remove.setOnClickListener { v: View ->
val food = v.tag as Food
activity?.let { activity ->
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)
}
}
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:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="info.nightscout.androidaps.plugins.treatments.fragments.TreatmentsExtendedBolusesFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout
android:layout_width="match_parent"
<ImageView
android:layout_width="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
android:layout_width="wrap_content"
android:paddingLeft="5dp"
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"
<EditText
android:id="@+id/filter"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:orientation="horizontal">
android:layout_weight="1"
android:autofillHints="@string/filter"
android:ems="10"
android:inputType="text"
android:text="" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/category" />
<ImageView
android:id="@+id/clearfilter"
android:layout_width="wrap_content"
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
android:id="@+id/food_category"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="right"
android:minWidth="100dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/category" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/subcategory" />
<Spinner
android:id="@+id/category"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="end"
android:minWidth="100dp" />
<Spinner
android:id="@+id/food_subcategory"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="right"
android:minWidth="100dp" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/subcategory" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/food_recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent">
</androidx.recyclerview.widget.RecyclerView>
<Spinner
android:id="@+id/subcategory"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="end"
android:minWidth="100dp" />
</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">
<TextView
android:id="@+id/food_name"
android:layout_width="wrap_content"
android:id="@+id/name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:inputType="textMultiLine|textNoSuggestions"
android:text="Name"
android:textStyle="bold" />
<TextView
android:id="@+id/food_portion"
android:id="@+id/portion"
android:layout_width="60dp"
android:layout_height="wrap_content"
android:gravity="end"
android:text="Portion" />
<TextView
android:id="@+id/food_carbs"
android:id="@+id/carbs"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:gravity="end"
@ -47,27 +46,27 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="end"
android:orientation="horizontal">
<TextView
android:id="@+id/food_fat"
android:id="@+id/fat"
android:layout_width="70dp"
android:layout_height="wrap_content"
android:gravity="end"
android:text="Fat" />
<TextView
android:id="@+id/food_protein"
android:id="@+id/protein"
android:layout_width="70dp"
android:layout_height="wrap_content"
android:gravity="end"
android:text="Protein" />
<TextView
android:id="@+id/food_energy"
android:id="@+id/energy"
android:layout_width="70dp"
android:layout_height="wrap_content"
android:gravity="end"
@ -83,7 +82,7 @@
android:textColor="@color/colorSetTempButton" />
<TextView
android:id="@+id/food_remove"
android:id="@+id/remove"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingEnd="5dp"

View file

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