Various UI and code changes to SourcesDialog.kt

This commit is contained in:
Arty Bishop committed 2022-02-19 12:11:50 +00:00
1 parent 22d0db1d78
commit 97e6f8b7f5
8 files changed
+164 -152

No files matched your search

@@ -20,51 +20,69 @@ package com.rtbishop.look4sat.presentation.settingsScreen
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.widget.doOnTextChanged import androidx.core.widget.doOnTextChanged
import androidx.recyclerview.widget.AsyncListDiffer
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.rtbishop.look4sat.databinding.ItemSourceBinding import com.rtbishop.look4sat.databinding.ItemSourceBinding
import com.rtbishop.look4sat.framework.model.DataSource import com.rtbishop.look4sat.framework.model.DataSource
class SourcesAdapter(private val sources: MutableList<DataSource> = mutableListOf()) : class SourcesAdapter(private val clickListener: SourcesClickListener) :
RecyclerView.Adapter<SourcesAdapter.TleSourceHolder>() { RecyclerView.Adapter<SourcesAdapter.SourceHolder>() {
fun getSources(): List<DataSource> { private val diffCallback = object : DiffUtil.ItemCallback<DataSource>() {
return sources.filter { source -> source.url.contains("https://") } override fun areItemsTheSame(oldItem: DataSource, newItem: DataSource): Boolean {
} return oldItem.url == newItem.url
}
fun setSources(list: List<DataSource>) { override fun areContentsTheSame(oldItem: DataSource, newItem: DataSource): Boolean {
sources.clear() return oldItem.url == newItem.url
sources.addAll(list) }
} }
private val differ = AsyncListDiffer(this, diffCallback)
private val httpsString = "https://"
fun getSources() = differ.currentList.filter { source -> source.url.contains(httpsString) }
fun addSource() { fun addSource() {
sources.add(DataSource()) submitList((getSources() as MutableList).apply { add(DataSource(httpsString)) })
notifyItemInserted(itemCount - 1)
} }
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TleSourceHolder { fun removeSource(source: DataSource) {
val binding = ItemSourceBinding submitList((getSources() as MutableList).apply { remove(source) })
.inflate(LayoutInflater.from(parent.context), parent, false)
return TleSourceHolder(binding)
} }
override fun onBindViewHolder(holder: TleSourceHolder, position: Int) { fun submitList(items: List<DataSource>) = differ.submitList(items)
holder.bind(sources[position])
override fun getItemCount(): Int = differ.currentList.size
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SourceHolder {
return SourceHolder.from(parent)
} }
override fun getItemCount(): Int { override fun onBindViewHolder(holder: SourceHolder, position: Int) {
return sources.size holder.bind(differ.currentList[position], clickListener)
} }
inner class TleSourceHolder(private val binding: ItemSourceBinding) : class SourceHolder(private val binding: ItemSourceBinding) :
RecyclerView.ViewHolder(binding.root) { RecyclerView.ViewHolder(binding.root) {
fun bind(source: DataSource) { fun bind(source: DataSource, listener: SourcesClickListener) {
binding.sourceUrl.setText(source.url) binding.run {
binding.sourceUrl.doOnTextChanged { txt, _, _, _ -> source.url = txt.toString() } sourceText.setText(source.url)
binding.sourceBtn.setOnClickListener { sourceText.doOnTextChanged { text, _, _, _ -> source.url = text.toString() }
sources.remove(source) sourceInput.setEndIconOnClickListener { listener.removeSource(source) }
notifyItemRemoved(adapterPosition) }
}
companion object {
fun from(parent: ViewGroup): SourceHolder {
val inflater = LayoutInflater.from(parent.context)
return SourceHolder(ItemSourceBinding.inflate(inflater, parent, false))
} }
} }
} }
interface SourcesClickListener {
fun removeSource(source: DataSource)
}
} }
@@ -25,6 +25,7 @@ import android.view.WindowManager
import androidx.appcompat.app.AppCompatDialogFragment import androidx.appcompat.app.AppCompatDialogFragment
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.rtbishop.look4sat.R
import com.rtbishop.look4sat.databinding.DialogSourcesBinding import com.rtbishop.look4sat.databinding.DialogSourcesBinding
import com.rtbishop.look4sat.domain.IDataRepository import com.rtbishop.look4sat.domain.IDataRepository
import com.rtbishop.look4sat.framework.model.DataSource import com.rtbishop.look4sat.framework.model.DataSource
@@ -33,11 +34,12 @@ import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject import javax.inject.Inject
@AndroidEntryPoint @AndroidEntryPoint
class SourcesDialog : AppCompatDialogFragment() { class SourcesDialog : AppCompatDialogFragment(), SourcesAdapter.SourcesClickListener {
@Inject @Inject
lateinit var repository: IDataRepository lateinit var repository: IDataRepository
private lateinit var binding: DialogSourcesBinding private lateinit var binding: DialogSourcesBinding
private lateinit var sourcesAdapter: SourcesAdapter
override fun onCreateView(inflater: LayoutInflater, group: ViewGroup?, state: Bundle?): View { override fun onCreateView(inflater: LayoutInflater, group: ViewGroup?, state: Bundle?): View {
binding = DialogSourcesBinding.inflate(inflater, group, false) binding = DialogSourcesBinding.inflate(inflater, group, false)
@@ -46,27 +48,29 @@ class SourcesDialog : AppCompatDialogFragment() {
override fun onViewCreated(view: View, state: Bundle?) { override fun onViewCreated(view: View, state: Bundle?) {
super.onViewCreated(view, state) super.onViewCreated(view, state)
dialog?.window?.setBackgroundDrawableResource(R.color.transparent)
dialog?.window?.setLayout( dialog?.window?.setLayout(
WindowManager.LayoutParams.MATCH_PARENT, (resources.displayMetrics.widthPixels * 0.94).toInt(),
WindowManager.LayoutParams.WRAP_CONTENT WindowManager.LayoutParams.WRAP_CONTENT
) )
lifecycleScope.launchWhenResumed { lifecycleScope.launchWhenResumed {
val adapter = SourcesAdapter() val sources = repository.getDataSources().map { url -> DataSource(url) }
val layoutManager = LinearLayoutManager(requireContext()) val layoutManager = LinearLayoutManager(requireContext())
adapter.setSources(repository.getDataSources().map { url -> DataSource(url) }) sourcesAdapter = SourcesAdapter(this@SourcesDialog).apply { submitList(sources) }
binding.run { binding.run {
sourcesRecycler.apply { sourcesRecycler.apply {
setHasFixedSize(true) this.adapter = sourcesAdapter
this.adapter = adapter
this.layoutManager = layoutManager this.layoutManager = layoutManager
} }
sourcesBtnAdd.setOnClickListener { adapter.addSource() } sourcesBtnAdd.setOnClickListener { sourcesAdapter.addSource() }
sourcesBtnNeg.setOnClickListener { dismiss() } sourcesBtnNeg.setOnClickListener { dismiss() }
sourcesBtnPos.setOnClickListener { sourcesBtnPos.setOnClickListener {
setNavResult("sources", adapter.getSources().map { source -> source.url }) setNavResult("sources", sourcesAdapter.getSources().map { item -> item.url })
dismiss() dismiss()
} }
} }
} }
} }
override fun removeSource(source: DataSource) = sourcesAdapter.removeSource(source)
} }
+75 -71
View File
@@ -1,82 +1,86 @@
<?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.cardview.widget.CardView 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"
android:id="@+id/sources_root" style="@style/SurfaceCard"
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@color/surfaceCard"> android:layout_gravity="center">
<TextView <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/sources_title" android:layout_width="match_parent"
style="@style/DialogTitle" android:layout_height="match_parent">
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:text="@string/sources_title"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView <TextView
android:id="@+id/sources_warning" android:id="@+id/sources_title"
style="@style/DialogTitle" style="@style/DialogTitle"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="0dp"
android:layout_marginTop="4dp" android:layout_marginStart="22dp"
android:gravity="center" android:layout_marginEnd="8dp"
android:text="@string/sources_https" android:text="@string/sources_title"
app:layout_constraintStart_toStartOf="@+id/sources_title" android:textSize="18sp"
app:layout_constraintTop_toBottomOf="@+id/sources_title" /> app:layout_constraintBaseline_toBaselineOf="@+id/sources_btn_add"
app:layout_constraintEnd_toStartOf="@+id/sources_btn_add"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_constraintStart_toStartOf="@+id/sources_btn_neg" />
<ImageButton <Button
android:id="@+id/sources_btn_add" android:id="@+id/sources_btn_add"
android:layout_width="48dp" style="@style/NormalButton"
android:layout_height="48dp" android:layout_width="wrap_content"
android:backgroundTint="@color/surfaceButton" android:layout_height="wrap_content"
android:src="@drawable/ic_add" android:layout_marginStart="8dp"
app:layout_constraintBottom_toBottomOf="@+id/sources_warning" android:layout_marginTop="8dp"
app:layout_constraintDimensionRatio="h,1:1" android:text="@string/btn_add"
app:layout_constraintEnd_toEndOf="@+id/sources_recycler" app:layout_constraintEnd_toEndOf="@+id/sources_btn_pos"
app:layout_constraintTop_toTopOf="@+id/sources_title" app:layout_constraintHorizontal_bias="0.5"
app:tint="@color/themeAccent" /> app:layout_constraintStart_toEndOf="@+id/sources_title"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/sources_recycler" android:id="@+id/sources_recycler"
style="@style/Recycler" style="@style/Recycler"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="280dp" android:layout_height="0dp"
android:layout_marginStart="16dp" android:layout_marginStart="2dp"
android:layout_marginTop="8dp" android:layout_marginTop="2dp"
android:layout_marginEnd="16dp" android:layout_marginEnd="2dp"
app:layout_constraintEnd_toEndOf="parent" android:layout_marginBottom="2dp"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintBottom_toTopOf="@+id/sources_btn_pos"
app:layout_constraintTop_toBottomOf="@+id/sources_warning"> app:layout_constraintDimensionRatio="w,1:1"
app:layout_constraintEnd_toEndOf="@+id/sources_btn_pos"
app:layout_constraintStart_toStartOf="@+id/sources_btn_neg"
app:layout_constraintTop_toBottomOf="@+id/sources_btn_add" />
</androidx.recyclerview.widget.RecyclerView> <Button
android:id="@+id/sources_btn_neg"
style="@style/NormalButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:text="@string/btn_cancel"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/sources_btn_pos"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_constraintStart_toStartOf="parent" />
<Button <Button
android:id="@+id/sources_btn_neg" android:id="@+id/sources_btn_pos"
style="@style/DialogButton" style="@style/NormalButton"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="12dp" android:layout_marginStart="8dp"
android:text="@string/btn_cancel" android:layout_marginEnd="8dp"
app:layout_constraintBaseline_toBaselineOf="@+id/sources_btn_pos" android:text="@string/btn_accept"
app:layout_constraintHorizontal_chainStyle="spread_inside" app:layout_constraintBaseline_toBaselineOf="@+id/sources_btn_neg"
app:layout_constraintStart_toStartOf="parent" /> app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/sources_btn_neg" />
<Button </androidx.constraintlayout.widget.ConstraintLayout>
android:id="@+id/sources_btn_pos"
style="@style/DialogButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginEnd="12dp"
android:layout_marginBottom="12dp"
android:text="@string/btn_accept"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/sources_recycler" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.cardview.widget.CardView>
+15 -32
View File
@@ -1,38 +1,21 @@
<?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" <com.google.android.material.textfield.TextInputLayout 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"
android:id="@+id/source_root" android:id="@+id/source_input"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingTop="4dp" android:layout_marginStart="4dp"
android:paddingBottom="4dp"> android:layout_marginTop="4dp"
android:layout_marginEnd="4dp"
android:layout_marginBottom="4dp"
android:hint="@string/sources_hint"
app:endIconDrawable="@drawable/ic_clear"
app:endIconMode="custom">
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputEditText
android:id="@+id/source_input" android:id="@+id/source_text"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox" android:layout_width="match_parent"
android:layout_width="0dp" android:layout_height="match_parent"
android:layout_height="wrap_content" android:inputType="textUri" />
android:hint="@string/sources_hint"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/source_btn"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.textfield.TextInputEditText </com.google.android.material.textfield.TextInputLayout>
android:id="@+id/source_url"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:inputType="textUri" />
</com.google.android.material.textfield.TextInputLayout>
<ImageButton
android:id="@+id/source_btn"
style="@style/ToolbarButton"
android:rotation="45"
android:src="@drawable/ic_add"
app:layout_constraintBottom_toBottomOf="@+id/source_input"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/source_input" />
</androidx.constraintlayout.widget.ConstraintLayout>
+4 -5
View File
@@ -2,8 +2,9 @@
<resources> <resources>
<string name="yes">Да</string> <string name="yes">Да</string>
<string name="no">Нет</string> <string name="no">Нет</string>
<string name="btn_cancel">Отмена</string>
<string name="btn_accept">Принять</string> <string name="btn_accept">Принять</string>
<string name="btn_add">Добавить</string>
<string name="btn_cancel">Отмена</string>
<string name="menu_satellites">Спутники</string> <string name="menu_satellites">Спутники</string>
<string name="menu_passes">Пролеты</string> <string name="menu_passes">Пролеты</string>
@@ -11,10 +12,8 @@
<string name="menu_map">Карта</string> <string name="menu_map">Карта</string>
<string name="menu_settings">Настройки</string> <string name="menu_settings">Настройки</string>
<string name="sources_title">Управление TLE</string> <string name="sources_title">Источники данных</string>
<string name="sources_hint">URL источника</string> <string name="sources_hint">Протокол HTTPS</string>
<string name="sources_https">Только протокол HTTPS</string>
<string name="sources_error">Пожалуйста, проверьте URL</string>
<string name="entries_title">Спутники</string> <string name="entries_title">Спутники</string>
<string name="entries_update">Обновить спутники:</string> <string name="entries_update">Обновить спутники:</string>
+1
View File
@@ -21,6 +21,7 @@
<dimen name="text_size_copyright">13sp</dimen> <dimen name="text_size_copyright">13sp</dimen>
<dimen name="text_size_small">15sp</dimen> <dimen name="text_size_small">15sp</dimen>
<dimen name="text_size_medium">16sp</dimen> <dimen name="text_size_medium">16sp</dimen>
<dimen name="text_size_mediumLarge">18sp</dimen>
<dimen name="text_size_large">20sp</dimen> <dimen name="text_size_large">20sp</dimen>
<dimen name="text_size_frequency">24sp</dimen> <dimen name="text_size_frequency">24sp</dimen>
<dimen name="text_size_app_timer">42sp</dimen> <dimen name="text_size_app_timer">42sp</dimen>
+4 -5
View File
@@ -4,8 +4,9 @@
<string name="yes">Yes</string> <string name="yes">Yes</string>
<string name="no">No</string> <string name="no">No</string>
<string name="btn_cancel">Cancel</string>
<string name="btn_accept">Accept</string> <string name="btn_accept">Accept</string>
<string name="btn_add">Add</string>
<string name="btn_cancel">Cancel</string>
<string name="menu_satellites">Satellites</string> <string name="menu_satellites">Satellites</string>
<string name="menu_passes">Passes</string> <string name="menu_passes">Passes</string>
@@ -13,10 +14,8 @@
<string name="menu_map">World Map</string> <string name="menu_map">World Map</string>
<string name="menu_settings">Settings</string> <string name="menu_settings">Settings</string>
<string name="sources_title">Manage TLE sources</string> <string name="sources_title">Manage data sources</string>
<string name="sources_hint">Source URL</string> <string name="sources_hint">HTTPS Source</string>
<string name="sources_https">Protocol HTTPS only</string>
<string name="sources_error">Please check the entered URL</string>
<string name="entries_title">Satellites</string> <string name="entries_title">Satellites</string>
<string name="entries_update">TLE data update:</string> <string name="entries_update">TLE data update:</string>
+10 -6
View File
@@ -80,6 +80,7 @@
<item name="android:layout_height">wrap_content</item> <item name="android:layout_height">wrap_content</item>
<item name="android:backgroundTint">@color/surfaceButton</item> <item name="android:backgroundTint">@color/surfaceButton</item>
<item name="android:ellipsize">end</item> <item name="android:ellipsize">end</item>
<item name="android:minWidth">96dp</item>
<item name="android:maxLines">1</item> <item name="android:maxLines">1</item>
<item name="android:textAllCaps">false</item> <item name="android:textAllCaps">false</item>
<item name="android:textColor">@color/themeLight</item> <item name="android:textColor">@color/themeLight</item>
@@ -159,12 +160,18 @@
</style> </style>
<style name="DialogButton"> <style name="DialogButton">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:backgroundTint">@color/surfaceButton</item> <item name="android:backgroundTint">@color/surfaceButton</item>
<item name="android:ellipsize">end</item> <item name="android:ellipsize">end</item>
<item name="android:minWidth">96dp</item>
<item name="android:maxLines">1</item> <item name="android:maxLines">1</item>
<item name="android:textAllCaps">false</item> <item name="android:textAllCaps">false</item>
<item name="android:textColor">@color/themeAccent</item> <item name="android:textColor">@color/themeLight</item>
<item name="android:textSize">@dimen/text_size_medium</item> <item name="android:textSize">@dimen/text_size_medium</item>
<item name="cornerRadius">@dimen/btn_corner_high</item>
<item name="iconTint">@color/themeLight</item>
<item name="rippleColor">@color/themeLight</item>
</style> </style>
<style name="DialogText"> <style name="DialogText">
@@ -174,11 +181,8 @@
<item name="android:textSize">@dimen/text_size_medium</item> <item name="android:textSize">@dimen/text_size_medium</item>
</style> </style>
<style name="DialogTitle"> <style name="DialogTitle" parent="ToolbarTitle">
<item name="android:layout_width">wrap_content</item> <item name="android:textSize">@dimen/text_size_mediumLarge</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:textColor">@color/themeAccent</item>
<item name="android:textSize">@dimen/text_size_medium</item>
</style> </style>
</resources> </resources>