Skip to content

Commit

Permalink
Use Recycler View instead of List View
Browse files Browse the repository at this point in the history
  • Loading branch information
mikolasan committed Aug 10, 2024
1 parent 6aae8fe commit 0f8712d
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 84 deletions.
4 changes: 2 additions & 2 deletions .idea/deploymentTargetSelector.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class ImperialCategoryAdapter(private val categories: Array<ImperialUnitCategory
private val publishSubject: MainActivity)
: RecyclerView.Adapter<ImperialCategoryAdapter.ViewHolder>()
{
var selectedViewHolder: ViewHolder? = null
private var selectedViewHolder: ViewHolder? = null
// var selectedPosition: Int = 0

class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
Expand Down Expand Up @@ -44,9 +44,7 @@ class ImperialCategoryAdapter(private val categories: Array<ImperialUnitCategory
}
holder.space.setOnClickListener {
// unselect previous holder
selectedViewHolder?.let {
it.space.setBackgroundResource(0)
}
selectedViewHolder?.space?.setBackgroundResource(0)
selectedViewHolder = holder
publishSubject.onCategorySelected(holder.category!!)
holder.space.setBackgroundResource(R.drawable.bg_rect_selected)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import android.widget.Filterable
import android.widget.ImageView
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.willowtreeapps.fuzzywuzzy.diffutils.FuzzySearch
import io.github.mikolasan.ratiogenerator.ImperialUnit
import kotlinx.coroutines.CoroutineScope
Expand All @@ -21,8 +23,28 @@ import kotlinx.coroutines.withContext
import java.util.Locale


class ImperialListAdapter(private val workingUnits: WorkingUnits) : BaseAdapter(), Filterable {
val scope = CoroutineScope(Job() + Dispatchers.Main)
class ImperialListAdapter(private val workingUnits: WorkingUnits,
private val publishSubject: MainActivity)
: RecyclerView.Adapter<ImperialListAdapter.ViewHolder>(), Filterable
{

class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
lateinit var data: ImperialUnit
lateinit var publishSubject: MainActivity
val layout: ConstraintLayout = view as ConstraintLayout
val name: TextView = layout.findViewById(R.id.unit_name)
val value: TextView = layout.findViewById(R.id.unit_value)
val symbol: TextView = layout.findViewById(R.id.unit_symbol)
val arrowUp: ImageView = layout.findViewById(R.id.arrow_up)
val bookmark: ImageView = layout.findViewById(R.id.bookmark)
init {
layout.setOnClickListener {
publishSubject.onUnitSelected(data)
}
}
}

private val scope = CoroutineScope(Job() + Dispatchers.Main)

var allUnits: Array<ImperialUnit> = workingUnits.orderedUnits
var units: Array<ImperialUnit> = workingUnits.orderedUnits
Expand Down Expand Up @@ -50,53 +72,45 @@ class ImperialListAdapter(private val workingUnits: WorkingUnits) : BaseAdapter(
bookmarkClickListener = listener
}


fun updateAllValues(unit: ImperialUnit?, value: Double) {
val job = scope.launch {
withContext(Dispatchers.IO) {
allUnits.forEach { u ->
if (u != unit) {
names = allUnits.map { u -> u.unitName.name.lowercase(Locale.ROOT) }
allUnits.forEachIndexed { i, u ->
if (u != unit) {
scope.launch {
withContext(Dispatchers.IO) {
val v = convertValue(unit, u, value)
u.value = v
u.formattedString = makeSerializedString(valueForDisplay(v))
}
notifyItemChanged(i)
}
names = allUnits.map { u -> u.unitName.name.lowercase(Locale.ROOT) }
} else {
notifyItemChanged(i)
}
notifyDataSetChanged()
}
}

override fun getView(position: Int, contentView: View?, parent: ViewGroup?): View {
if (contentView != null) {
if (contentView is ConstraintLayout) {
updateViewData(contentView, position)
updateViewColors(contentView, position)
updateControlListeners(contentView, position)
return contentView
}
return contentView
} else {
val context = parent?.context
val inflater = context?.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
val view = inflater.inflate(R.layout.unit_space, parent, false) as ConstraintLayout
updateViewData(view, position)
updateViewColors(view, position)
updateControlListeners(view, position)
return view
}

private fun getItem(position: Int): ImperialUnit {
return units[position]
}

override fun getItem(position: Int): Any {
return units[position]
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): ViewHolder {
val context = parent.context
val inflater = context?.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
val view = inflater.inflate(R.layout.unit_space, parent, false)
return ViewHolder(view)
}

override fun getItemId(position: Int): Long {
return position.toLong()
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
updateViewData(holder, position)
updateViewColors(holder, position)
updateControlListeners(holder, position)
}

override fun getCount(): Int {
override fun getItemCount(): Int {
return units.size
}

Expand Down Expand Up @@ -127,23 +141,18 @@ class ImperialListAdapter(private val workingUnits: WorkingUnits) : BaseAdapter(
ViewState.NORMAL to R.color.inputNormal
)

private fun updateViewColors(layout: ConstraintLayout, dataPosition: Int) {
val name: TextView = layout.findViewById(R.id.unit_name)
val value: TextView = layout.findViewById(R.id.unit_value)
val symbol: TextView = layout.findViewById(R.id.unit_symbol)
val arrowUp: ImageView = layout.findViewById(R.id.arrow_up)
val bookmark: ImageView = layout.findViewById(R.id.bookmark)
private fun updateViewColors(holder: ViewHolder, dataPosition: Int) {
val bookmarkColor = if (units[dataPosition].bookmarked) R.color.bookmark else R.color.action
val color = bookmark.context.resources.getColor(bookmarkColor)
bookmark.drawable.mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN)
val color = holder.bookmark.context.resources.getColor(bookmarkColor)
holder.bookmark.drawable.mutate().setColorFilter(color, PorterDuff.Mode.SRC_IN)
when (getItem(dataPosition) as ImperialUnit) {
workingUnits.topUnit -> {
layout.setBackgroundResource(backgrounds.getValue(ViewState.SELECTED))
name.setTextColorId(nameColors.getValue(ViewState.SELECTED))
value.setTextColorId(valueColors.getValue(ViewState.SELECTED))
symbol.setTextColorId(valueColors.getValue(ViewState.SELECTED))
holder.layout.setBackgroundResource(backgrounds.getValue(ViewState.SELECTED))
holder.name.setTextColorId(nameColors.getValue(ViewState.SELECTED))
holder.value.setTextColorId(valueColors.getValue(ViewState.SELECTED))
holder.symbol.setTextColorId(valueColors.getValue(ViewState.SELECTED))

arrowUp.visibility = if (dataPosition == 0) View.INVISIBLE else View.VISIBLE
holder.arrowUp.visibility = if (dataPosition == 0) View.INVISIBLE else View.VISIBLE
}
// workingUnits.bottomUnit -> {
// layout.setBackgroundResource(backgrounds.getValue(ViewState.SECOND))
Expand All @@ -153,55 +162,51 @@ class ImperialListAdapter(private val workingUnits: WorkingUnits) : BaseAdapter(
// arrowUp.visibility = View.INVISIBLE
// }
else -> {
layout.setBackgroundResource(backgrounds.getValue(ViewState.NORMAL))
name.setTextColorId(nameColors.getValue(ViewState.NORMAL))
value.setTextColorId(valueColors.getValue(ViewState.NORMAL))
symbol.setTextColorId(valueColors.getValue(ViewState.NORMAL))
holder.layout.setBackgroundResource(backgrounds.getValue(ViewState.NORMAL))
holder.name.setTextColorId(nameColors.getValue(ViewState.NORMAL))
holder.value.setTextColorId(valueColors.getValue(ViewState.NORMAL))
holder.symbol.setTextColorId(valueColors.getValue(ViewState.NORMAL))
// bookmark.setColorFilter(if (units[dataPosition].bookmarked) R.color.colorPrimaryDark else R.color.action, PorterDuff.Mode.SRC_IN)
arrowUp.visibility = View.INVISIBLE
holder.arrowUp.visibility = View.INVISIBLE
}
}
}

private fun updateViewData(layout: ConstraintLayout, dataPosition: Int) {
val data: ImperialUnit = getItem(dataPosition) as ImperialUnit
val name: TextView = layout.findViewById(R.id.unit_name)
name.text = data.unitName.name.lowercase(Locale.getDefault()).replace('_', ' ')
private fun updateViewData(holder: ViewHolder, dataPosition: Int) {
val data: ImperialUnit = getItem(dataPosition)
holder.publishSubject = publishSubject
holder.data = data
holder.name.text = data.unitName.name.lowercase(Locale.getDefault()).replace('_', ' ')
.replaceFirstChar {
if (it.isLowerCase()) it.titlecase(
Locale.getDefault()
) else it.toString()
}
val value: TextView = layout.findViewById(R.id.unit_value)
value.text = data.formattedString //valueForDisplay(data.value)
val symbol: TextView = layout.findViewById(R.id.unit_symbol)
symbol.text = ImperialSymbol.symbols[data.unitName] ?: ""
holder.value.text = data.formattedString //valueForDisplay(data.value)
holder.symbol.text = ImperialSymbol.symbols[data.unitName] ?: ""
}

private fun updateControlListeners(layout: ConstraintLayout, dataPosition: Int) {
val arrowUp: ImageView = layout.findViewById(R.id.arrow_up)
val unit = units[dataPosition]
arrowUp.setOnClickListener {
private fun updateControlListeners(holder: ViewHolder, dataPosition: Int) {
val unit = getItem(dataPosition)
holder.arrowUp.setOnClickListener {
if (dataPosition != 0) {
units.moveToFrontFrom(dataPosition)
arrowClickListener(dataPosition, it, unit)
notifyDataSetChanged()
notifyItemMoved(dataPosition, 0)
}
}
arrowUp.setOnLongClickListener {
holder.arrowUp.setOnLongClickListener {
if (dataPosition != 0) {
units.moveToFrontFrom(dataPosition)
notifyDataSetChanged()
notifyItemMoved(dataPosition, 0)
arrowLongClickListener(dataPosition, it, unit)
}
dataPosition != 0
}

val bookmark: ImageView = layout.findViewById(R.id.bookmark)
bookmark.setOnClickListener {
holder.bookmark.setOnClickListener {
unit.bookmarked = !unit.bookmarked
bookmarkClickListener(dataPosition, it, unit)
notifyDataSetChanged()
notifyItemChanged(dataPosition)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ class ImperialSettings(application: Application) : AndroidViewModel(application)
topUnit = topPanelUnit
bottomUnit = bottomPanelUnit
selectedCategory = category
listAdapter = ImperialListAdapter(this)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ class MainActivity : AppCompatActivity() {

private fun restoreMainUnits() {
workingUnits = settings.restoreWorkingUnits()
workingUnits.listAdapter = ImperialListAdapter(workingUnits, this)

val topString = settings.restoreTopString()
workingUnits.topUnit.restoreValue(topString, BasicCalculator(topString).eval())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,16 @@ import androidx.core.os.bundleOf
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentContainerView
import androidx.navigation.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import io.github.mikolasan.ratiogenerator.ImperialUnit


class UnitListFragment : Fragment() {

var keyboardFragment: KeyboardFragment? = null
var keyboardButtonFragment: KeyboardButtonFragment? = null
private lateinit var unitsList: ListView
private lateinit var unitsList: RecyclerView
lateinit var listAdapter: ImperialListAdapter
private var switchFragment: SwitchFragment? = null
private lateinit var title: TextView
Expand All @@ -41,7 +43,7 @@ class UnitListFragment : Fragment() {
listAdapter.setOnArrowLongClickListener { _: Int, arrow: View, unit: ImperialUnit ->
arrow.visibility = View.INVISIBLE // hide the arrow
(activity as MainActivity).onArrowLongClicked(unit)
unitsList.setSelectionAfterHeaderView()
//unitsList.setSelectionAfterHeaderView()
}
listAdapter.setOnBookmarkClickListener { _: Int, arrow: View, unit: ImperialUnit ->
(activity as MainActivity).let {
Expand Down Expand Up @@ -74,6 +76,7 @@ class UnitListFragment : Fragment() {
val view = inflater.inflate(R.layout.fragment_list, container, false)
unitsList = view.findViewById(R.id.units_list)
unitsList.adapter = listAdapter
unitsList.layoutManager = LinearLayoutManager(activity)
// This is moved to another fragment (main activity for tablets ??)
// val searchInput = view.findViewById<EditText>(R.id.search_input)
// searchInput.addTextChangedListener {
Expand Down Expand Up @@ -161,10 +164,6 @@ class UnitListFragment : Fragment() {
}

private fun setListeners(view: View) {
unitsList.setOnItemClickListener { _, _, position, _ ->
val unit = listAdapter.getItem(position) as ImperialUnit
(activity as MainActivity).onUnitSelected(unit)
}

// This is replaced by the toolbar
// view.run {
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/layout/fragment_list.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent" >

<ListView
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/units_list"
android:layout_width="400dp"
android:layout_height="0dp"
Expand Down

0 comments on commit 0f8712d

Please sign in to comment.