Full write logic of entries fragment
This commit is contained in:
parent
438aca7b75
commit
dbcb29ce79
@ -6,7 +6,9 @@ import dagger.hilt.InstallIn
|
|||||||
import dagger.hilt.android.components.ViewModelComponent
|
import dagger.hilt.android.components.ViewModelComponent
|
||||||
import ru.myitschool.work.data.repo.AccountRepositoryImpl
|
import ru.myitschool.work.data.repo.AccountRepositoryImpl
|
||||||
import ru.myitschool.work.data.repo.AuthorizationRepositoryImpl
|
import ru.myitschool.work.data.repo.AuthorizationRepositoryImpl
|
||||||
|
import ru.myitschool.work.data.repo.EntryRepositoryImpl
|
||||||
import ru.myitschool.work.domain.auth.repo.AuthorizationRepository
|
import ru.myitschool.work.domain.auth.repo.AuthorizationRepository
|
||||||
|
import ru.myitschool.work.domain.entry.repo.EntryRepository
|
||||||
import ru.myitschool.work.domain.profile.repo.UserInfoRepository
|
import ru.myitschool.work.domain.profile.repo.UserInfoRepository
|
||||||
|
|
||||||
@Module
|
@Module
|
||||||
@ -22,4 +24,9 @@ abstract class RepoModule {
|
|||||||
abstract fun bindAccountRepo(
|
abstract fun bindAccountRepo(
|
||||||
impl: AccountRepositoryImpl
|
impl: AccountRepositoryImpl
|
||||||
): UserInfoRepository
|
): UserInfoRepository
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
abstract fun bindEntryRepository(
|
||||||
|
impl: EntryRepositoryImpl
|
||||||
|
): EntryRepository
|
||||||
}
|
}
|
17
app/src/main/java/ru/myitschool/work/data/dto/EntriesDto.kt
Normal file
17
app/src/main/java/ru/myitschool/work/data/dto/EntriesDto.kt
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package ru.myitschool.work.data.dto
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
|
||||||
|
class EntriesDto(
|
||||||
|
@SerializedName("id")
|
||||||
|
val id: Long,
|
||||||
|
@SerializedName("username")
|
||||||
|
val username: String,
|
||||||
|
@SerializedName("time")
|
||||||
|
val time: String,
|
||||||
|
@SerializedName("type")
|
||||||
|
val type: VisitType,
|
||||||
|
@SerializedName("readerId")
|
||||||
|
val readerId: String,
|
||||||
|
)
|
@ -0,0 +1,5 @@
|
|||||||
|
package ru.myitschool.work.data.dto
|
||||||
|
|
||||||
|
enum class VisitType {
|
||||||
|
SCANNER, NFC
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
package ru.myitschool.work.data.mapper
|
||||||
|
|
||||||
|
import android.os.Build
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
|
import ru.myitschool.work.data.dto.EntriesDto
|
||||||
|
import ru.myitschool.work.data.dto.UserInfoDto
|
||||||
|
import ru.myitschool.work.domain.profile.entities.UserInfoEntity
|
||||||
|
import ru.myitschool.work.ui.entrylist.adapter.EntryHistoryEntity
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.Locale
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class EntryInfoMapper @Inject constructor() {
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.O)
|
||||||
|
operator fun invoke(model: List<EntriesDto>): Result<List<EntryHistoryEntity>> {
|
||||||
|
return kotlin.runCatching {
|
||||||
|
model.map {
|
||||||
|
EntryHistoryEntity(
|
||||||
|
type = it.type.name,
|
||||||
|
identificator = it.readerId,
|
||||||
|
time = it.time.toString(),
|
||||||
|
)
|
||||||
|
}.toList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private companion object {
|
||||||
|
private val simpleDateFormat = SimpleDateFormat(
|
||||||
|
"yyyy-MM-dd'T'HH:mm:ss",
|
||||||
|
Locale.US
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
package ru.myitschool.work.data.repo
|
||||||
|
|
||||||
|
import dagger.Lazy
|
||||||
|
import dagger.Reusable
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import ru.myitschool.work.data.mapper.EntryInfoMapper
|
||||||
|
import ru.myitschool.work.data.mapper.UserInfoMapper
|
||||||
|
import ru.myitschool.work.data.source.AccountNetworkDataSource
|
||||||
|
import ru.myitschool.work.data.source.EntryNetworkDataSource
|
||||||
|
import ru.myitschool.work.domain.entry.entities.EntryEntity
|
||||||
|
import ru.myitschool.work.domain.entry.repo.EntryRepository
|
||||||
|
import ru.myitschool.work.domain.profile.entities.UserInfoEntity
|
||||||
|
import ru.myitschool.work.domain.profile.repo.UserInfoRepository
|
||||||
|
import ru.myitschool.work.ui.entrylist.adapter.EntryHistoryEntity
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@Reusable
|
||||||
|
class EntryRepositoryImpl @Inject constructor(
|
||||||
|
private val entryNetworkDataSource: EntryNetworkDataSource,
|
||||||
|
private val entryInfoMapper: Lazy<EntryInfoMapper>,
|
||||||
|
): EntryRepository {
|
||||||
|
override suspend fun getEntries(basicAuth: String): Result<List<EntryHistoryEntity>> {
|
||||||
|
return withContext(Dispatchers.IO) {
|
||||||
|
entryNetworkDataSource.getEntries(basicAuth).fold(
|
||||||
|
onSuccess = { value -> entryInfoMapper.get().invoke(value) },
|
||||||
|
onFailure = { error -> Result.failure(error) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
12
app/src/main/java/ru/myitschool/work/data/source/EntryApi.kt
Normal file
12
app/src/main/java/ru/myitschool/work/data/source/EntryApi.kt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package ru.myitschool.work.data.source
|
||||||
|
|
||||||
|
import retrofit2.http.GET
|
||||||
|
import retrofit2.http.Header
|
||||||
|
import ru.myitschool.work.data.dto.EntriesDto
|
||||||
|
|
||||||
|
interface EntryApi {
|
||||||
|
@GET("api/employee/visits")
|
||||||
|
suspend fun getEntries(
|
||||||
|
@Header("Authorization") basicAuth: String
|
||||||
|
) : List<EntriesDto>
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
package ru.myitschool.work.data.source
|
||||||
|
|
||||||
|
import dagger.Reusable
|
||||||
|
import retrofit2.Retrofit
|
||||||
|
import ru.myitschool.work.data.dto.EntriesDto
|
||||||
|
import ru.myitschool.work.data.dto.OpenQrDto
|
||||||
|
import ru.myitschool.work.data.dto.UserInfoDto
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@Reusable
|
||||||
|
class EntryNetworkDataSource @Inject constructor(
|
||||||
|
private val retrofit: Retrofit
|
||||||
|
) {
|
||||||
|
private val api by lazy {
|
||||||
|
retrofit.create(EntryApi::class.java)
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun getEntries(basicAuth: String): Result<List<EntriesDto>> {
|
||||||
|
return kotlin.runCatching { api.getEntries(basicAuth = basicAuth) }
|
||||||
|
}
|
||||||
|
}
|
@ -7,9 +7,6 @@ import javax.inject.Inject
|
|||||||
class LoginUseCase @Inject constructor(
|
class LoginUseCase @Inject constructor(
|
||||||
private val repo: AuthorizationRepository,
|
private val repo: AuthorizationRepository,
|
||||||
) {
|
) {
|
||||||
// suspend operator fun invoke(login: String): Result<Unit> {
|
|
||||||
// return repo.login(username = login)
|
|
||||||
// }
|
|
||||||
suspend operator fun invoke(data: LoginDto): Result<Unit>{
|
suspend operator fun invoke(data: LoginDto): Result<Unit>{
|
||||||
return repo.login(data=data)
|
return repo.login(data=data)
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
package ru.myitschool.work.domain.entry
|
||||||
|
|
||||||
|
import ru.myitschool.work.domain.auth.GetLoginUseCase
|
||||||
|
import ru.myitschool.work.domain.entry.repo.EntryRepository
|
||||||
|
import ru.myitschool.work.ui.entrylist.adapter.EntryHistoryEntity
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class EntryListUseCase @Inject constructor(
|
||||||
|
private val repo: EntryRepository,
|
||||||
|
private val getLoginUseCase: GetLoginUseCase,
|
||||||
|
) {
|
||||||
|
suspend operator fun invoke(): Result<List<EntryHistoryEntity>> {
|
||||||
|
return getLoginUseCase().fold(
|
||||||
|
onSuccess = { basicAuth -> repo.getEntries(basicAuth) },
|
||||||
|
onFailure = { error -> Result.failure(error) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package ru.myitschool.work.domain.entry.entities
|
||||||
|
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
|
||||||
|
class EntryEntity(
|
||||||
|
val username: String,
|
||||||
|
val time: LocalDateTime,
|
||||||
|
val type: EntryType,
|
||||||
|
val readerId: String,
|
||||||
|
)
|
@ -0,0 +1,5 @@
|
|||||||
|
package ru.myitschool.work.domain.entry.entities
|
||||||
|
|
||||||
|
enum class EntryType {
|
||||||
|
SCANNER, NFC
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package ru.myitschool.work.domain.entry.repo
|
||||||
|
|
||||||
|
import ru.myitschool.work.ui.entrylist.adapter.EntryHistoryEntity
|
||||||
|
|
||||||
|
interface EntryRepository {
|
||||||
|
suspend fun getEntries(basicAuth: String) : Result<List<EntryHistoryEntity>>
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package ru.myitschool.work.ui.entrylist
|
package ru.myitschool.work.ui.entrylist
|
||||||
|
|
||||||
|
import android.content.res.ColorStateList
|
||||||
import androidx.fragment.app.viewModels
|
import androidx.fragment.app.viewModels
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
@ -8,8 +9,11 @@ import android.view.LayoutInflater
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||||
|
import com.squareup.picasso.Picasso
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import ru.myitschool.work.R
|
import ru.myitschool.work.R
|
||||||
import ru.myitschool.work.databinding.FragmentEntryListBinding
|
import ru.myitschool.work.databinding.FragmentEntryListBinding
|
||||||
@ -21,6 +25,8 @@ import ru.myitschool.work.ui.login.LoginViewModel
|
|||||||
import ru.myitschool.work.ui.profile.ProfileDestination
|
import ru.myitschool.work.ui.profile.ProfileDestination
|
||||||
import ru.myitschool.work.ui.profile.ProfileViewModel
|
import ru.myitschool.work.ui.profile.ProfileViewModel
|
||||||
import ru.myitschool.work.utils.collectWhenStarted
|
import ru.myitschool.work.utils.collectWhenStarted
|
||||||
|
import ru.myitschool.work.utils.visibleOrGone
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class EntryListFragment : Fragment(R.layout.fragment_entry_list) {
|
class EntryListFragment : Fragment(R.layout.fragment_entry_list) {
|
||||||
|
|
||||||
@ -29,22 +35,49 @@ class EntryListFragment : Fragment(R.layout.fragment_entry_list) {
|
|||||||
|
|
||||||
private val viewModel: EntryListViewModel by viewModels()
|
private val viewModel: EntryListViewModel by viewModels()
|
||||||
|
|
||||||
|
private lateinit var swipeRefreshLayout: SwipeRefreshLayout
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
_binding = FragmentEntryListBinding.bind(view)
|
_binding = FragmentEntryListBinding.bind(view)
|
||||||
initCallback()
|
initCallback()
|
||||||
subscribe()
|
subscribe()
|
||||||
|
|
||||||
|
swipeRefreshLayout = binding.swipeRefreshLayout2
|
||||||
|
|
||||||
|
swipeRefreshLayout.setOnRefreshListener {
|
||||||
|
viewModel.updateEntryList()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initCallback() {
|
private fun initCallback() {
|
||||||
binding.floatingActionButton2.setOnClickListener { viewModel.closeEntryList() }
|
binding.floatingActionButton2.setOnClickListener { viewModel.closeEntryList() }
|
||||||
|
|
||||||
|
|
||||||
binding.recyclerView.adapter = AdapterEntryHistory(viewModel.getEntryList())
|
// binding.recyclerView.adapter = AdapterEntryHistory(viewModel.getEntryList())
|
||||||
binding.recyclerView.layoutManager = LinearLayoutManager(requireContext())
|
binding.recyclerView.layoutManager = LinearLayoutManager(requireContext())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun subscribe() {
|
private fun subscribe() {
|
||||||
|
viewModel.state.collectWhenStarted(this) { state ->
|
||||||
|
binding.recyclerView.visibleOrGone(state is EntryListViewModel.State.Show)
|
||||||
|
binding.error2.visibleOrGone(state is EntryListViewModel.State.Error)
|
||||||
|
|
||||||
|
when(state) {
|
||||||
|
is EntryListViewModel.State.Loading -> {
|
||||||
|
swipeRefreshLayout.isRefreshing = true
|
||||||
|
}
|
||||||
|
is EntryListViewModel.State.Error -> {
|
||||||
|
swipeRefreshLayout.isRefreshing = false
|
||||||
|
binding.error2.text = state.errorText
|
||||||
|
}
|
||||||
|
is EntryListViewModel.State.Show -> {
|
||||||
|
swipeRefreshLayout.isRefreshing = false
|
||||||
|
binding.recyclerView.adapter = AdapterEntryHistory(state.entryList)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
viewModel.action.collectWhenStarted(this) { action ->
|
viewModel.action.collectWhenStarted(this) { action ->
|
||||||
when (action) {
|
when (action) {
|
||||||
is EntryListViewModel.Action.OpenProfile -> {
|
is EntryListViewModel.Action.OpenProfile -> {
|
||||||
|
@ -3,31 +3,38 @@ package ru.myitschool.work.ui.entrylist
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import dagger.Lazy
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.asSharedFlow
|
import kotlinx.coroutines.flow.asSharedFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
|
import kotlinx.coroutines.flow.update
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import ru.myitschool.work.R
|
||||||
|
import ru.myitschool.work.domain.entry.EntryListUseCase
|
||||||
import ru.myitschool.work.ui.entrylist.adapter.EntryHistoryEntity
|
import ru.myitschool.work.ui.entrylist.adapter.EntryHistoryEntity
|
||||||
import ru.myitschool.work.ui.profile.ProfileViewModel
|
|
||||||
import ru.myitschool.work.ui.profile.ProfileViewModel.Action
|
|
||||||
import ru.myitschool.work.ui.profile.ProfileViewModel.State
|
|
||||||
import ru.myitschool.work.utils.MutablePublishFlow
|
import ru.myitschool.work.utils.MutablePublishFlow
|
||||||
import java.text.SimpleDateFormat
|
|
||||||
import java.util.Locale
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
class EntryListViewModel @Inject constructor(
|
class EntryListViewModel @Inject constructor(
|
||||||
@ApplicationContext private val context: Context,
|
@ApplicationContext private val context: Context,
|
||||||
|
private val entryUseCase: Lazy<EntryListUseCase>,
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
private val _action = MutablePublishFlow<Action>()
|
private val _action = MutablePublishFlow<Action>()
|
||||||
val action = _action.asSharedFlow()
|
val action = _action.asSharedFlow()
|
||||||
|
|
||||||
|
private val _state = MutableStateFlow<EntryListViewModel.State>(initialState)
|
||||||
|
val state = _state.asStateFlow()
|
||||||
|
|
||||||
|
init {
|
||||||
|
updateEntryList()
|
||||||
|
}
|
||||||
|
|
||||||
// Новый список данных
|
// Новый список данных
|
||||||
private val entryList = listOf(
|
private var entryList = listOf(
|
||||||
EntryHistoryEntity("type1", "2023-10-01T12:00:00", "id001"),
|
EntryHistoryEntity("type1", "2023-10-01T12:00:00", "id001"),
|
||||||
EntryHistoryEntity("type2", "2023-10-02T13:00:00", "id002"),
|
EntryHistoryEntity("type2", "2023-10-02T13:00:00", "id002"),
|
||||||
EntryHistoryEntity("type3", "2023-10-03T14:00:00", "id003"),
|
EntryHistoryEntity("type3", "2023-10-03T14:00:00", "id003"),
|
||||||
@ -36,8 +43,28 @@ class EntryListViewModel @Inject constructor(
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Функция для получения данных
|
// Функция для получения данных
|
||||||
fun getEntryList(): List<EntryHistoryEntity> {
|
fun updateEntryList() {
|
||||||
return entryList
|
viewModelScope.launch {
|
||||||
|
_state.update { State.Loading }
|
||||||
|
entryUseCase.get().invoke().fold(
|
||||||
|
onSuccess = { entryListEntity ->
|
||||||
|
entryList = entryListEntity
|
||||||
|
_state.update {
|
||||||
|
State.Show(
|
||||||
|
entryList = entryListEntity
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onFailure = { error ->
|
||||||
|
_state.update {
|
||||||
|
State.Error(
|
||||||
|
errorText = error.localizedMessage
|
||||||
|
?: context.resources.getString(R.string.login_error)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun closeEntryList(){
|
fun closeEntryList(){
|
||||||
@ -49,4 +76,20 @@ class EntryListViewModel @Inject constructor(
|
|||||||
sealed interface Action {
|
sealed interface Action {
|
||||||
data object OpenProfile: Action
|
data object OpenProfile: Action
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sealed interface State {
|
||||||
|
data object Loading : State
|
||||||
|
|
||||||
|
data class Error(
|
||||||
|
val errorText: String,
|
||||||
|
) : State
|
||||||
|
|
||||||
|
data class Show(
|
||||||
|
val entryList: List<EntryHistoryEntity>
|
||||||
|
) : State
|
||||||
|
}
|
||||||
|
|
||||||
|
private companion object {
|
||||||
|
val initialState = State.Loading
|
||||||
|
}
|
||||||
}
|
}
|
@ -36,8 +36,8 @@ class AdapterEntryHistory(private val datas: List<EntryHistoryEntity>) : Recycle
|
|||||||
|
|
||||||
|
|
||||||
holder.dateText.text = LocalDateTime.parse(datas[position].time).format(DateTimeFormatter.ofPattern("d MMMM yyyy, HH:mm:ss", Locale.getDefault()))
|
holder.dateText.text = LocalDateTime.parse(datas[position].time).format(DateTimeFormatter.ofPattern("d MMMM yyyy, HH:mm:ss", Locale.getDefault()))
|
||||||
holder.identificatorText.text = datas[position].identificator.toString()
|
holder.identificatorText.text = datas[position].identificator
|
||||||
holder.typeText.text = datas[position].type.toString()
|
holder.typeText.text = if (datas[position].type == "SCANNER") "Сканер (Телефон)" else "NFC-карта"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,40 +1,59 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout 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:id="@+id/frameLayout2"
|
android:id="@+id/swipeRefreshLayout2"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent">
|
||||||
android:padding="16dp"
|
|
||||||
tools:context=".ui.entrylist.EntryListFragment">
|
|
||||||
|
|
||||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:id="@+id/floatingActionButton2"
|
android:layout_width="match_parent"
|
||||||
style="@style/Theme.UiTemplate.FAB.Gray"
|
android:layout_height="match_parent"
|
||||||
android:layout_width="wrap_content"
|
android:padding="16dp"
|
||||||
android:layout_height="wrap_content"
|
tools:context=".ui.entrylist.EntryListFragment">
|
||||||
android:clickable="true"
|
|
||||||
android:src="@drawable/ic_back"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/textView5"
|
android:id="@+id/error2"
|
||||||
style="@style/Theme.UiTemplate.TextH2"
|
style="@style/Theme.UiTemplate.TextH5"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/entry_history"
|
android:layout_marginHorizontal="16dp"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/floatingActionButton2"
|
android:textAlignment="center"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
android:visibility="gone"
|
||||||
app:layout_constraintStart_toEndOf="@+id/floatingActionButton2"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="@+id/floatingActionButton2" />
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
tools:text="Something wrong. Try later" />
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
android:id="@+id/recyclerView"
|
android:id="@+id/floatingActionButton2"
|
||||||
android:layout_width="0dp"
|
style="@style/Theme.UiTemplate.FAB.Gray"
|
||||||
android:layout_height="0dp"
|
android:layout_width="wrap_content"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
android:layout_height="wrap_content"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
android:clickable="true"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
android:src="@drawable/ic_back"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/floatingActionButton2" />
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/textView5"
|
||||||
|
style="@style/Theme.UiTemplate.TextH2"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/entry_history"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/floatingActionButton2"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/floatingActionButton2"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/floatingActionButton2" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/recyclerView"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/floatingActionButton2" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
@ -1,40 +1,60 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout 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:id="@+id/frameLayout2"
|
android:id="@+id/swipeRefreshLayout2"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent">
|
||||||
android:padding="16dp"
|
|
||||||
tools:context=".ui.entrylist.EntryListFragment">
|
|
||||||
|
|
||||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:id="@+id/floatingActionButton2"
|
android:layout_width="match_parent"
|
||||||
style="@style/Theme.UiTemplate.FAB.Gray"
|
android:layout_height="match_parent"
|
||||||
android:layout_width="wrap_content"
|
android:padding="16dp"
|
||||||
android:layout_height="wrap_content"
|
tools:context=".ui.entrylist.EntryListFragment">
|
||||||
android:clickable="true"
|
|
||||||
android:src="@drawable/ic_back"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/textView5"
|
android:id="@+id/error2"
|
||||||
style="@style/Theme.UiTemplate.TextH2"
|
style="@style/Theme.UiTemplate.TextH5"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/entry_history"
|
android:layout_marginHorizontal="16dp"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/floatingActionButton2"
|
android:textAlignment="center"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
android:visibility="gone"
|
||||||
app:layout_constraintStart_toEndOf="@+id/floatingActionButton2"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="@+id/floatingActionButton2" />
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
tools:text="Something wrong. Try later" />
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
android:id="@+id/recyclerView"
|
android:id="@+id/floatingActionButton2"
|
||||||
android:layout_width="0dp"
|
style="@style/Theme.UiTemplate.FAB.Gray"
|
||||||
android:layout_height="0dp"
|
android:layout_width="wrap_content"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
android:layout_height="wrap_content"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
android:clickable="true"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
android:src="@drawable/ic_back"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/floatingActionButton2" />
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/textView5"
|
||||||
|
style="@style/Theme.UiTemplate.TextH2"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/entry_history"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/floatingActionButton2"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/floatingActionButton2"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/floatingActionButton2" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/recyclerView"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/floatingActionButton2" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
Loading…
x
Reference in New Issue
Block a user