Working filter
This commit is contained in:
parent
4b4e2b6b3c
commit
91c4485265
10
.idea/runConfigurations.xml
Normal file
10
.idea/runConfigurations.xml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="RunConfigurationProducerService">
|
||||||
|
<option name="ignoredProducers">
|
||||||
|
<set>
|
||||||
|
<option value="com.android.tools.idea.compose.preview.runconfiguration.ComposePreviewRunConfigurationProducer" />
|
||||||
|
</set>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
@ -3,6 +3,7 @@ package it.danieleverducci.subitobeers
|
|||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import it.danieleverducci.subitobeers.entities.Beer
|
import it.danieleverducci.subitobeers.entities.Beer
|
||||||
|
import it.danieleverducci.subitobeers.networking.BeersFilter
|
||||||
import it.danieleverducci.subitobeers.networking.RetrofitProvider
|
import it.danieleverducci.subitobeers.networking.RetrofitProvider
|
||||||
import retrofit2.Call
|
import retrofit2.Call
|
||||||
import retrofit2.Callback
|
import retrofit2.Callback
|
||||||
@ -16,9 +17,9 @@ class BeersRepository {
|
|||||||
|
|
||||||
var listener: Listener? = null
|
var listener: Listener? = null
|
||||||
|
|
||||||
fun getBeers(page: Int) {
|
fun getBeers(page: Int, filter: BeersFilter) {
|
||||||
// Obtain beers
|
// Obtain beers
|
||||||
val call = RetrofitProvider.getClient.getBeers(page)
|
val call = RetrofitProvider.getClient.getBeers(page, filter.brewedBefore, filter.brewedAfter)
|
||||||
call.enqueue(object: Callback<List<Beer>> {
|
call.enqueue(object: Callback<List<Beer>> {
|
||||||
override fun onResponse(call: Call<List<Beer>>, response: Response<List<Beer>>) {
|
override fun onResponse(call: Call<List<Beer>>, response: Response<List<Beer>>) {
|
||||||
if (response.body() != null)
|
if (response.body() != null)
|
||||||
|
@ -15,7 +15,7 @@ class Beer// Parse date
|
|||||||
val description: String = ""
|
val description: String = ""
|
||||||
@SerializedName("image_url")
|
@SerializedName("image_url")
|
||||||
val imageUrl: String = ""
|
val imageUrl: String = ""
|
||||||
// @SerializedName("first_brewed")
|
@SerializedName("first_brewed")
|
||||||
// val firstBrewed: Date? = null
|
val firstBrewed: String = ""
|
||||||
|
|
||||||
}
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
package it.danieleverducci.subitobeers.networking
|
||||||
|
|
||||||
|
object BeersFilter {
|
||||||
|
var brewedBefore: String? = null
|
||||||
|
var brewedAfter: String? = null
|
||||||
|
}
|
@ -8,6 +8,8 @@ import retrofit2.http.Query
|
|||||||
interface PunkAPI {
|
interface PunkAPI {
|
||||||
@GET("/v2/beers?per_page=10")
|
@GET("/v2/beers?per_page=10")
|
||||||
fun getBeers(
|
fun getBeers(
|
||||||
@Query("page") page: Int
|
@Query("page") page: Int,
|
||||||
|
@Query("brewed_before") brewedBefore: String?,
|
||||||
|
@Query("brewed_after") brewedAfter: String?
|
||||||
): Call<List<Beer>>
|
): Call<List<Beer>>
|
||||||
}
|
}
|
@ -34,7 +34,7 @@ class BeerDetailFragment(val beer: Beer) : Fragment() {
|
|||||||
binding.beerDetailTitle.text = beer.name
|
binding.beerDetailTitle.text = beer.name
|
||||||
binding.beerDetailShortdesc.text = beer.tagline
|
binding.beerDetailShortdesc.text = beer.tagline
|
||||||
binding.beerDetailDesc.text = beer.description
|
binding.beerDetailDesc.text = beer.description
|
||||||
// binding.beerDetailFirstbrewed.text = beer.
|
binding.beerDetailFirstbrewed.text = beer.firstBrewed
|
||||||
|
|
||||||
return binding.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
@ -50,6 +50,7 @@ class BeerRecyclerAdapter : RecyclerView.Adapter<BeerRecyclerAdapter.ViewHolder>
|
|||||||
// Fill layout with data
|
// Fill layout with data
|
||||||
holder.name.text = item.name
|
holder.name.text = item.name
|
||||||
holder.descr.text = item.tagline
|
holder.descr.text = item.tagline
|
||||||
|
holder.firstbrewed.text = item.firstBrewed
|
||||||
Picasso.get()
|
Picasso.get()
|
||||||
.load(item.imageUrl)
|
.load(item.imageUrl)
|
||||||
.placeholder(R.drawable.ic_launcher_foreground)
|
.placeholder(R.drawable.ic_launcher_foreground)
|
||||||
@ -66,8 +67,13 @@ class BeerRecyclerAdapter : RecyclerView.Adapter<BeerRecyclerAdapter.ViewHolder>
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun addItems(ni: List<Beer>) {
|
fun addItems(ni: List<Beer>) {
|
||||||
items.addAll(ni);
|
items.addAll(ni)
|
||||||
notifyDataSetChanged();
|
notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun clear() {
|
||||||
|
items.clear()
|
||||||
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemCount(): Int = items.size
|
override fun getItemCount(): Int = items.size
|
||||||
@ -76,6 +82,7 @@ class BeerRecyclerAdapter : RecyclerView.Adapter<BeerRecyclerAdapter.ViewHolder>
|
|||||||
val root: View = binding.root
|
val root: View = binding.root
|
||||||
val name: TextView = binding.beerItemName
|
val name: TextView = binding.beerItemName
|
||||||
val descr: TextView = binding.beerItemDescr
|
val descr: TextView = binding.beerItemDescr
|
||||||
|
val firstbrewed: TextView = binding.beerItemFirstbrewed
|
||||||
val pic: ImageView = binding.beerItemPic
|
val pic: ImageView = binding.beerItemPic
|
||||||
val progress: ProgressBar = binding.beerItemProgress
|
val progress: ProgressBar = binding.beerItemProgress
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package it.danieleverducci.subitobeers.ui
|
package it.danieleverducci.subitobeers.ui
|
||||||
|
|
||||||
|
import android.app.DatePickerDialog
|
||||||
|
import android.content.res.Resources
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.*
|
import android.view.*
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
@ -11,16 +13,21 @@ import it.danieleverducci.subitobeers.BeersRepository
|
|||||||
import it.danieleverducci.subitobeers.R
|
import it.danieleverducci.subitobeers.R
|
||||||
import it.danieleverducci.subitobeers.databinding.FragmentBeersListBinding
|
import it.danieleverducci.subitobeers.databinding.FragmentBeersListBinding
|
||||||
import it.danieleverducci.subitobeers.entities.Beer
|
import it.danieleverducci.subitobeers.entities.Beer
|
||||||
|
import it.danieleverducci.subitobeers.networking.BeersFilter
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A fragment representing a list of Items.
|
* A fragment representing a list of Items.
|
||||||
*/
|
*/
|
||||||
class BeersFragment : Fragment(), BeersRepository.Listener, BeerRecyclerAdapter.Listener {
|
class BeersFragment : Fragment(), BeersRepository.Listener, BeerRecyclerAdapter.Listener {
|
||||||
|
|
||||||
|
enum class FILTERTYPE {SINCE, TO}
|
||||||
|
|
||||||
private val rvAdapter = BeerRecyclerAdapter()
|
private val rvAdapter = BeerRecyclerAdapter()
|
||||||
private val repo = BeersRepository()
|
private val repo = BeersRepository()
|
||||||
lateinit var binding: FragmentBeersListBinding
|
lateinit var binding: FragmentBeersListBinding
|
||||||
private var page = 1
|
private var page = 1
|
||||||
|
private var filter = BeersFilter
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater, container: ViewGroup?,
|
inflater: LayoutInflater, container: ViewGroup?,
|
||||||
@ -28,12 +35,17 @@ class BeersFragment : Fragment(), BeersRepository.Listener, BeerRecyclerAdapter.
|
|||||||
): View? {
|
): View? {
|
||||||
setHasOptionsMenu(true);
|
setHasOptionsMenu(true);
|
||||||
|
|
||||||
|
// Inflate layout
|
||||||
binding = FragmentBeersListBinding.inflate(
|
binding = FragmentBeersListBinding.inflate(
|
||||||
LayoutInflater.from(container!!.context),
|
LayoutInflater.from(container!!.context),
|
||||||
container,
|
container,
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Register filter buttons listeners
|
||||||
|
binding.listFilterSinceBt.setOnClickListener { onFilterButtonClicked(FILTERTYPE.SINCE) }
|
||||||
|
binding.listFilterToBt.setOnClickListener { onFilterButtonClicked(FILTERTYPE.TO) }
|
||||||
|
|
||||||
// Set the adapter
|
// Set the adapter
|
||||||
with(binding.list) {
|
with(binding.list) {
|
||||||
layoutManager = LinearLayoutManager(context)
|
layoutManager = LinearLayoutManager(context)
|
||||||
@ -43,18 +55,13 @@ class BeersFragment : Fragment(), BeersRepository.Listener, BeerRecyclerAdapter.
|
|||||||
// Register for recyclerview adapter events
|
// Register for recyclerview adapter events
|
||||||
rvAdapter.listener = this
|
rvAdapter.listener = this
|
||||||
|
|
||||||
return binding.root
|
// Register for network completed events
|
||||||
}
|
|
||||||
|
|
||||||
override fun onStart() {
|
|
||||||
super.onStart()
|
|
||||||
|
|
||||||
// Load beers from network
|
|
||||||
repo.listener = this
|
repo.listener = this
|
||||||
|
|
||||||
// TODO: evitare che ogni volta ricarichi gli stessi elementi
|
// Load first page
|
||||||
page = 1
|
loadBeers(true)
|
||||||
repo.getBeers(page)
|
|
||||||
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||||
@ -86,18 +93,58 @@ class BeersFragment : Fragment(), BeersRepository.Listener, BeerRecyclerAdapter.
|
|||||||
throw IllegalStateException("Activity must implement BeerNavigation")
|
throw IllegalStateException("Activity must implement BeerNavigation")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a filter button is clicked
|
||||||
|
* @param type whether is start or end date
|
||||||
|
*/
|
||||||
|
fun onFilterButtonClicked(type: FILTERTYPE) {
|
||||||
|
val dpd = DatePickerDialog(requireContext())
|
||||||
|
// Hide day selector
|
||||||
|
// dpd.datePicker.findViewById<View>(
|
||||||
|
// Resources.getSystem().getIdentifier("day", "id", "android")
|
||||||
|
// ).visibility = View.GONE
|
||||||
|
dpd.setOnDateSetListener(DatePickerDialog.OnDateSetListener { view, year, month, dayOfMonth ->
|
||||||
|
// On date chosen
|
||||||
|
val formattedDate = "${String.format("%02d", month)}-${String.format("%04d", year)}"
|
||||||
|
if (type == FILTERTYPE.SINCE)
|
||||||
|
filter.brewedAfter = formattedDate
|
||||||
|
else
|
||||||
|
filter.brewedBefore = formattedDate
|
||||||
|
// Update list
|
||||||
|
loadBeers(true)
|
||||||
|
})
|
||||||
|
dpd.show()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when last list item is displayed.
|
* Called when last list item is displayed.
|
||||||
* Used to fetch more elements
|
* Used to fetch more elements
|
||||||
*/
|
*/
|
||||||
override fun OnLastItemScrolled() {
|
override fun OnLastItemScrolled() {
|
||||||
page++;
|
page++
|
||||||
repo.getBeers(page)
|
loadBeers(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggles beer filter visibility
|
||||||
|
*/
|
||||||
private fun toggleFilter() {
|
private fun toggleFilter() {
|
||||||
binding.listFilterDropdown.visibility =
|
binding.listFilterDropdown.visibility =
|
||||||
if (binding.listFilterDropdown.visibility == View.VISIBLE) View.GONE else View.VISIBLE
|
if (binding.listFilterDropdown.visibility == View.VISIBLE) View.GONE else View.VISIBLE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads beers from network from first page
|
||||||
|
* @param clear: clears the list and fetch from first element
|
||||||
|
*/
|
||||||
|
private fun loadBeers(clear: Boolean) {
|
||||||
|
if (clear) {
|
||||||
|
rvAdapter.clear()
|
||||||
|
page = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load with filter
|
||||||
|
repo.getBeers(page, filter)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,11 +0,0 @@
|
|||||||
package it.danieleverducci.subitobeers.ui.views
|
|
||||||
|
|
||||||
import android.app.DatePickerDialog
|
|
||||||
import android.content.Context
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Here I extend DatePickerDialog to hide the Day picker
|
|
||||||
*/
|
|
||||||
class CustomMonthPickerDialog(context: Context) : DatePickerDialog(context) {
|
|
||||||
|
|
||||||
}
|
|
5
app/src/main/res/drawable/ic_firstbrewed_list.xml
Normal file
5
app/src/main/res/drawable/ic_firstbrewed_list.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<vector android:height="16dp" android:tint="?attr/colorControlNormal"
|
||||||
|
android:viewportHeight="24" android:viewportWidth="24"
|
||||||
|
android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M20,3h-1L19,1h-2v2L7,3L7,1L5,1v2L4,3c-1.1,0 -2,0.9 -2,2v16c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,5c0,-1.1 -0.9,-2 -2,-2zM20,21L4,21L4,8h16v13z"/>
|
||||||
|
</vector>
|
@ -19,17 +19,19 @@
|
|||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:layout_marginRight="10dp"
|
android:layout_marginEnd="10dp"
|
||||||
android:text="00/0000"
|
android:text="@string/list_filter_brewed_after"
|
||||||
android:drawableLeft="@drawable/ic_firstbrewed"/>
|
app:drawableLeftCompat="@drawable/ic_firstbrewed"
|
||||||
|
android:drawableTint="@color/white"/>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/list_filter_to_bt"
|
android:id="@+id/list_filter_to_bt"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:text="00/0000"
|
android:text="@string/list_filter_brewed_before"
|
||||||
android:drawableLeft="@drawable/ic_firstbrewed"/>
|
app:drawableLeftCompat="@drawable/ic_firstbrewed"
|
||||||
|
android:drawableTint="@color/white"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
@ -42,15 +42,30 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="20dp"
|
android:layout_marginStart="20dp"
|
||||||
android:layout_marginEnd="10dp"
|
android:layout_marginEnd="10dp"
|
||||||
android:layout_marginBottom="16dp"
|
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
android:maxLines="3"
|
android:maxLines="3"
|
||||||
android:text="@string/placeholder_tagline"
|
android:text="@string/placeholder_tagline"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/beer_item_pic"
|
app:layout_constraintBottom_toTopOf="@+id/beer_item_firstbrewed"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toEndOf="@+id/beer_item_pic"
|
app:layout_constraintStart_toEndOf="@+id/beer_item_pic"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/beer_item_name" />
|
app:layout_constraintTop_toBottomOf="@+id/beer_item_name" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/beer_item_firstbrewed"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="20dp"
|
||||||
|
android:layout_marginEnd="10dp"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
|
android:text="@string/placeholder_firstbrewed"
|
||||||
|
app:drawableLeftCompat="@drawable/ic_firstbrewed_list"
|
||||||
|
android:drawablePadding="5dp"
|
||||||
|
android:textStyle="italic"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/beer_item_pic"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/beer_item_pic"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/beer_item_descr" />
|
||||||
|
|
||||||
<ProgressBar
|
<ProgressBar
|
||||||
android:id="@+id/beer_item_progress"
|
android:id="@+id/beer_item_progress"
|
||||||
android:layout_width="50dp"
|
android:layout_width="50dp"
|
||||||
@ -62,5 +77,4 @@
|
|||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/beer_item_pic" />
|
app:layout_constraintTop_toBottomOf="@+id/beer_item_pic" />
|
||||||
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
<!-- Beers list -->
|
<!-- Beers list -->
|
||||||
<string name="network_error">Unable to retrieve beers from network</string>
|
<string name="network_error">Unable to retrieve beers from network</string>
|
||||||
|
<string name="list_filter_brewed_after">Brewed after</string>
|
||||||
|
<string name="list_filter_brewed_before">Brewed before</string>
|
||||||
|
|
||||||
<!-- Beers detail -->
|
<!-- Beers detail -->
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user