Replace RoundList with compose.
Some checks are pending
continuous-integration/drone/push Build is running

This commit is contained in:
2023-01-07 22:42:21 +01:00
parent 5f6da1d7d4
commit 2ed221a99f
8 changed files with 107 additions and 345 deletions

View File

@@ -11,7 +11,7 @@ data class GameAndScore(
override val created: Date, override val created: Date,
override var modified: Date, override var modified: Date,
override var gameId: Long, override var gameId: Long,
override var scoreA: Int?, override var scoreA: Int,
override var scoreB: Int?, override var scoreB: Int,
) : IGame, IRound { ) : IGame, IRound {
} }

View File

@@ -2,6 +2,6 @@ package me.zobrist.tichucounter.data
interface IRound { interface IRound {
var gameId: Long var gameId: Long
var scoreA: Int? var scoreA: Int
var scoreB: Int? var scoreB: Int
} }

View File

@@ -6,7 +6,7 @@ import androidx.room.PrimaryKey
@Entity @Entity
data class Round( data class Round(
override var gameId: Long, override var gameId: Long,
override var scoreA: Int?, override var scoreA: Int,
override var scoreB: Int?, override var scoreB: Int,
@PrimaryKey(autoGenerate = true) override val uid: Long? = null @PrimaryKey(autoGenerate = true) override val uid: Long? = null
) : IRound, IEntity ) : IRound, IEntity

View File

@@ -5,13 +5,11 @@ import android.view.*
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.core.view.MenuHost import androidx.core.view.MenuHost
import androidx.core.view.MenuProvider import androidx.core.view.MenuProvider
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.Lifecycle import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import me.zobrist.tichucounter.R import me.zobrist.tichucounter.R
import me.zobrist.tichucounter.data.Round
import me.zobrist.tichucounter.databinding.FragmentCounterBinding import me.zobrist.tichucounter.databinding.FragmentCounterBinding
import me.zobrist.tichucounter.repository.GameRepository import me.zobrist.tichucounter.repository.GameRepository
import me.zobrist.tichucounter.ui.FragmentBase import me.zobrist.tichucounter.ui.FragmentBase
@@ -26,12 +24,6 @@ class CounterFragment : FragmentBase<FragmentCounterBinding>(), MenuProvider {
override val bindingInflater: (LayoutInflater, ViewGroup?, Boolean) -> FragmentCounterBinding override val bindingInflater: (LayoutInflater, ViewGroup?, Boolean) -> FragmentCounterBinding
get() = FragmentCounterBinding::inflate get() = FragmentCounterBinding::inflate
private var currentRound: Round = Round(0, 0, null, null)
private var ignoreNextUpdate: Boolean = false
private val keyboardViewModel: KeyboardViewModel by activityViewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)

View File

@@ -4,32 +4,103 @@ import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.ViewCompositionStrategy
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import me.zobrist.tichucounter.databinding.FragmentRoundListBinding import kotlinx.coroutines.launch
import me.zobrist.tichucounter.ui.FragmentBase import me.zobrist.tichucounter.data.Round
@AndroidEntryPoint @AndroidEntryPoint
class RoundList : FragmentBase<FragmentRoundListBinding>() { class RoundList : Fragment() {
override val bindingInflater: (LayoutInflater, ViewGroup?, Boolean) -> FragmentRoundListBinding
get() = FragmentRoundListBinding::inflate
private val viewModel: RoundListViewModel by activityViewModels() private val viewModel: RoundListViewModel by activityViewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
viewModel.historyA.observe(viewLifecycleOwner) { text -> return ComposeView(requireContext()).apply {
binding.historyA.text = text // Dispose of the Composition when the view's LifecycleOwner
} // is destroyed
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
viewModel.historyB.observe(viewLifecycleOwner) { text -> setContent {
binding.historyB.text = text MaterialTheme {
} RoundListView(viewModel)
}
viewModel.scrollDown.observe(viewLifecycleOwner) { }
binding.scrollViewHistory.smoothScrollTo(0, binding.scrollViewHistory.height)
} }
} }
@Preview
@Composable
fun RoundListView(viewModel: IRoundListViewModel = DefaultViewModel()) {
val lazyListState = rememberLazyListState()
val scope = rememberCoroutineScope()
LazyColumn(state = lazyListState) {
itemsIndexed(viewModel.scores) { index, item ->
RoundListItem(item, index, lazyListState)
}
scope.launch {
lazyListState.animateScrollToItem(viewModel.scores.size)
}
}
}
@Composable
fun RoundListItem(round: Round, index: Int, lazyListState: LazyListState) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(all = 4.dp)
) {
Text(
text = round.scoreA.toString(),
style = MaterialTheme.typography.bodyMedium,
modifier = Modifier.weight(5f),
textAlign = TextAlign.Center
)
Text(
text = index.toString(),
style = MaterialTheme.typography.bodyMedium,
modifier = Modifier.weight(1f),
textAlign = TextAlign.Center
)
Text(
text = round.scoreB.toString(),
style = MaterialTheme.typography.bodyMedium,
modifier = Modifier.weight(5f),
textAlign = TextAlign.Center
)
}
}
internal class DefaultViewModel() : IRoundListViewModel {
override var scores: List<Round>
get() = TODO("Not yet implemented")
set(value) {}
}
} }

View File

@@ -1,61 +1,33 @@
package me.zobrist.tichucounter.ui.counter package me.zobrist.tichucounter.ui.counter
import androidx.lifecycle.LiveData import androidx.compose.runtime.getValue
import androidx.lifecycle.MutableLiveData import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import me.zobrist.tichucounter.data.Round import me.zobrist.tichucounter.data.Round
import me.zobrist.tichucounter.data.RoundDao import me.zobrist.tichucounter.data.RoundDao
import me.zobrist.tichucounter.framework.SingleLiveEvent
import javax.inject.Inject import javax.inject.Inject
@HiltViewModel interface IRoundListViewModel {
class RoundListViewModel @Inject constructor(private val roundDao: RoundDao) : ViewModel() { var scores: List<Round>
}
private val _historyA: MutableLiveData<String> = MutableLiveData<String>() @HiltViewModel
private val _historyB: MutableLiveData<String> = MutableLiveData<String>() class RoundListViewModel @Inject constructor(private val roundDao: RoundDao) : ViewModel(),
private val _scrollDown: SingleLiveEvent<Boolean> = SingleLiveEvent() IRoundListViewModel {
override var scores by mutableStateOf(emptyList<Round>())
init { init {
viewModelScope.launch { viewModelScope.launch {
roundDao.getForActiveGame().collect { scores -> roundDao.getForActiveGame().collect {
update(scores) scores = it
} }
} }
} }
val historyA: LiveData<String>
get() {
return _historyA
}
val historyB: LiveData<String>
get() {
return _historyB
}
val scrollDown: LiveData<Boolean>
get() {
return _scrollDown
}
private fun update(scores: List<Round>) {
var historyA = String()
var historyB = String()
scores.forEach {
historyA += it.scoreA.toString() + "\n"
historyB += it.scoreB.toString() + "\n"
}
_historyA.value = historyA
_historyB.value = historyB
scrollDown()
}
private fun scrollDown() {
_scrollDown.value = true
}
} }

View File

@@ -1,228 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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="wrap_content"
tools:context=".ui.counter.Keyboard">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:id="@+id/viewInput"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
app:layout_constraintBottom_toTopOf="@+id/keyboard"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<EditText
android:id="@+id/inputTeamA"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:gravity="center"
android:hint="0"
android:importantForAutofill="no"
android:inputType="numberSigned"
tools:ignore="HardcodedText" />
<EditText
android:id="@+id/inputTeamB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:gravity="center"
android:hint="0"
android:importantForAutofill="no"
android:inputType="numberSigned"
tools:ignore="HardcodedText" />
</LinearLayout>
<LinearLayout
android:id="@+id/ButtonRow1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<Button
android:id="@+id/button1"
style='?android:attr/buttonStyle'
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="1"
tools:ignore="HardcodedText" />
<Button
android:id="@+id/button2"
style='?android:attr/buttonStyle'
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="2"
tools:ignore="HardcodedText" />
<Button
android:id="@+id/button3"
style='?android:attr/buttonStyle'
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="3"
tools:ignore="HardcodedText" />
<Button
android:id="@+id/buttonAdd100"
style='?android:attr/buttonStyle'
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="+100"
tools:ignore="HardcodedText" />
</LinearLayout>
<LinearLayout
android:id="@+id/ButtonRow2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/button4"
style='?android:attr/buttonStyle'
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="4"
tools:ignore="HardcodedText" />
<Button
android:id="@+id/button5"
style='?android:attr/buttonStyle'
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="5"
tools:ignore="HardcodedText" />
<Button
android:id="@+id/button6"
style='?android:attr/buttonStyle'
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="6"
tools:ignore="HardcodedText" />
<Button
android:id="@+id/buttonSub100"
style='?android:attr/buttonStyle'
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="-100"
tools:ignore="HardcodedText" />
</LinearLayout>
<LinearLayout
android:id="@+id/ButtonRow3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/button7"
style='?android:attr/buttonStyle'
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="7"
tools:ignore="HardcodedText" />
<Button
android:id="@+id/button8"
style='?android:attr/buttonStyle'
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="8"
tools:ignore="HardcodedText" />
<Button
android:id="@+id/button9"
style='?android:attr/buttonStyle'
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="9"
tools:ignore="HardcodedText" />
<ImageButton
android:id="@+id/buttonBack"
style='?android:attr/buttonStyle'
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:contentDescription="@string/back"
android:cropToPadding="false"
android:paddingTop="15dp"
android:paddingBottom="15dp"
android:scaleType="fitCenter"
app:srcCompat="@drawable/back" />
</LinearLayout>
<LinearLayout
android:id="@+id/ButtonRow4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
tools:layout_editor_absoluteX="1dp">
<Button
android:id="@+id/buttonInv"
style='?android:attr/buttonStyle'
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.0"
android:text="+/-" />
<Button
android:id="@+id/button0"
style='?android:attr/buttonStyle'
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.0"
android:text="0" />
<Space
style='?android:attr/buttonBarButtonStyle'
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.0" />
<ImageButton
android:id="@+id/submit"
style='?android:attr/buttonStyle'
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:contentDescription="@string/submit"
android:cropToPadding="false"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:scaleType="fitCenter"
app:srcCompat="@drawable/checkmark" />
</LinearLayout>
</LinearLayout>
</FrameLayout>

View File

@@ -1,45 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.counter.RoundList">
<ScrollView
android:id="@+id/scrollViewHistory"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/historyA"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.2"
android:gravity="center"
tools:text="@tools:sample/cities" />
<TextView
android:id="@+id/historyB"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.2"
android:gravity="center"
tools:text="@tools:sample/date/hhmmss" />
</LinearLayout>
</LinearLayout>
</ScrollView>
</FrameLayout>