Simplify Dialog UI and code

This commit is contained in:
Benoit Marty 2020-09-11 09:43:10 +02:00
parent 4dc28a9d62
commit db977b8109
3 changed files with 103 additions and 183 deletions

View File

@ -17,147 +17,52 @@
package im.vector.app.features.settings package im.vector.app.features.settings
import android.app.Dialog import android.app.Dialog
import android.content.Context
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.ListView
import android.widget.RadioButton
import android.widget.TextView
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.core.view.isVisible
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import androidx.fragment.app.FragmentActivity
import im.vector.app.R import im.vector.app.R
class BackgroundSyncModeChooserDialog : DialogFragment() { class BackgroundSyncModeChooserDialog : DialogFragment() {
var interactionListener: InteractionListener? = null private var interactionListener: InteractionListener? = null
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return activity?.let { activity: FragmentActivity -> val initialMode = BackgroundSyncMode.fromString(arguments?.getString(ARG_INITIAL_MODE))
val builder = AlertDialog.Builder(activity)
// Get the layout inflater
val inflater = activity.layoutInflater
// Inflate and set the layout for the dialog val view = requireActivity().layoutInflater.inflate(R.layout.dialog_background_sync_mode, null)
// Pass null as the parent view because its going in the dialog layout val dialog = AlertDialog.Builder(requireActivity())
val view = inflater.inflate(R.layout.dialog_background_sync_mode, null) .setTitle(R.string.settings_background_fdroid_sync_mode)
view.findViewById<ListView>(R.id.dialog_background_sync_list)?.let { .setView(view)
it.adapter = Adapter( .setPositiveButton(R.string.cancel, null)
activity, .create()
BackgroundSyncMode.fromString(arguments?.getString(ARG_INITIAL_MODE))
) view.findViewById<View>(R.id.backgroundSyncModeBattery).setOnClickListener {
} interactionListener
builder.setView(view) ?.takeIf { initialMode != BackgroundSyncMode.FDROID_BACKGROUND_SYNC_MODE_FOR_BATTERY }
// Add action buttons ?.onOptionSelected(BackgroundSyncMode.FDROID_BACKGROUND_SYNC_MODE_FOR_BATTERY)
.setPositiveButton(R.string.ok) { dialog, _ ->
val mode = getSelectedOption()
if (mode.name == arguments?.getString(ARG_INITIAL_MODE)) {
// it's like a cancel, no changes
dialog.cancel()
} else {
interactionListener?.onOptionSelected(mode)
dialog.dismiss() dialog.dismiss()
} }
view.findViewById<View>(R.id.backgroundSyncModeReal).setOnClickListener {
interactionListener
?.takeIf { initialMode != BackgroundSyncMode.FDROID_BACKGROUND_SYNC_MODE_FOR_REALTIME }
?.onOptionSelected(BackgroundSyncMode.FDROID_BACKGROUND_SYNC_MODE_FOR_REALTIME)
dialog.dismiss()
} }
.setNegativeButton(R.string.cancel) { dialog, _ -> view.findViewById<View>(R.id.backgroundSyncModeOff).setOnClickListener {
interactionListener?.onCancel() interactionListener
dialog.cancel() ?.takeIf { initialMode != BackgroundSyncMode.FDROID_BACKGROUND_SYNC_MODE_DISABLED }
} ?.onOptionSelected(BackgroundSyncMode.FDROID_BACKGROUND_SYNC_MODE_DISABLED)
builder.create() dialog.dismiss()
} ?: throw IllegalStateException("Activity cannot be null")
}
private fun getSelectedOption(): BackgroundSyncMode {
options.forEach {
if (it.isSelected) return it.mode
}
// an item is always selected, should not happen
return options[0].mode
}
data class SyncMode(val mode: BackgroundSyncMode, val title: Int, val description: Int, var isSelected: Boolean)
private class Adapter(context: Context, val initialMode: BackgroundSyncMode) : ArrayAdapter<SyncMode>(context, 0, options) {
init {
// mark the currently selected option
var initialModeFound = false
options.forEach {
it.isSelected = initialMode == it.mode
initialModeFound = true
}
if (!initialModeFound) {
options[0].isSelected = true
}
}
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val syncMode = getItem(position)!!
// Only 3 items, let's keep it like that
val itemView = convertView
?: LayoutInflater.from(context).inflate(R.layout.item_custom_dialog_radio_line, parent, false)
// Lookup view for data population
itemView?.findViewById<TextView>(R.id.item_generic_title_text)?.let {
it.text = context.getString(syncMode.title)
}
itemView?.findViewById<TextView>(R.id.item_generic_description_text)?.let {
it.text = context.getString(syncMode.description)
it.isVisible = true
}
itemView?.findViewById<RadioButton>(R.id.item_generic_radio)?.let {
it.isChecked = syncMode.isSelected
it.isVisible = true
// let the item click handle that
it.setOnClickListener {
toggleChangeAtPosition(position)
}
}
itemView?.setOnClickListener {
toggleChangeAtPosition(position)
}
// Populate the data into the template view using the data object
return itemView
}
private fun toggleChangeAtPosition(position: Int) {
if (getItem(position)?.isSelected == true) {
// nop
} else {
for (i in 0 until count) {
// we change the single selection
getItem(i)?.isSelected = i == position
}
notifyDataSetChanged()
}
} }
return dialog
} }
interface InteractionListener { interface InteractionListener {
fun onCancel() {} fun onOptionSelected(mode: BackgroundSyncMode)
fun onOptionSelected(mode: BackgroundSyncMode) {}
} }
companion object { companion object {
private val options = listOf(
SyncMode(BackgroundSyncMode.FDROID_BACKGROUND_SYNC_MODE_FOR_BATTERY,
R.string.settings_background_fdroid_sync_mode_battery,
R.string.settings_background_fdroid_sync_mode_battery_description, false),
SyncMode(BackgroundSyncMode.FDROID_BACKGROUND_SYNC_MODE_FOR_REALTIME,
R.string.settings_background_fdroid_sync_mode_real_time,
R.string.settings_background_fdroid_sync_mode_real_time_description, false),
SyncMode(BackgroundSyncMode.FDROID_BACKGROUND_SYNC_MODE_DISABLED,
R.string.settings_background_fdroid_sync_mode_disabled,
R.string.settings_background_fdroid_sync_mode_disabled_description, false)
)
private const val ARG_INITIAL_MODE = "ARG_INITIAL_MODE" private const val ARG_INITIAL_MODE = "ARG_INITIAL_MODE"
fun newInstance(selectedMode: BackgroundSyncMode, interactionListener: InteractionListener): BackgroundSyncModeChooserDialog { fun newInstance(selectedMode: BackgroundSyncMode, interactionListener: InteractionListener): BackgroundSyncModeChooserDialog {

View File

@ -1,13 +1,85 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<ListView <LinearLayout
android:id="@+id/dialog_background_sync_list"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
tools:listitem="@layout/item_custom_dialog_radio_line" /> android:orientation="vertical">
</LinearLayout> <LinearLayout
android:id="@+id/backgroundSyncModeBattery"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:foreground="?attr/selectableItemBackground"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/settings_background_fdroid_sync_mode_battery"
android:textColor="?riotx_text_primary"
android:textStyle="bold" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:text="@string/settings_background_fdroid_sync_mode_battery_description"
android:textColor="?riotx_text_secondary" />
</LinearLayout>
<LinearLayout
android:id="@+id/backgroundSyncModeReal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:foreground="?attr/selectableItemBackground"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/settings_background_fdroid_sync_mode_real_time"
android:textColor="?riotx_text_primary"
android:textStyle="bold" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:text="@string/settings_background_fdroid_sync_mode_real_time_description"
android:textColor="?riotx_text_secondary" />
</LinearLayout>
<LinearLayout
android:id="@+id/backgroundSyncModeOff"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:foreground="?attr/selectableItemBackground"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/settings_background_fdroid_sync_mode_disabled"
android:textColor="?riotx_text_primary"
android:textStyle="bold" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:text="@string/settings_background_fdroid_sync_mode_disabled_description"
android:textColor="?riotx_text_secondary" />
</LinearLayout>
</LinearLayout>
</ScrollView>

View File

@ -1,57 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
android:background="?android:attr/colorBackground"
android:minHeight="50dp">
<TextView
android:id="@+id/item_generic_title_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:paddingTop="4dp"
android:paddingBottom="2dp"
android:textStyle="bold"
app:layout_constraintBottom_toTopOf="@+id/item_generic_description_text"
app:layout_constraintEnd_toStartOf="@+id/item_generic_radio"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="Item Title"
tools:textSize="14sp" />
<TextView
android:id="@+id/item_generic_description_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:paddingTop="2dp"
android:paddingBottom="4dp"
android:textColor="?android:attr/textColorSecondary"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/item_generic_radio"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/item_generic_title_text"
tools:text="At totam delectus et aliquid dolorem. Consectetur voluptas tempore et non blanditiis id optio. Dolorum impedit quidem minus nihil. "
tools:visibility="visible" />
<RadioButton
android:id="@+id/item_generic_radio"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
app:layout_constraintBottom_toBottomOf="@+id/item_generic_description_text"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/item_generic_title_text" />
</androidx.constraintlayout.widget.ConstraintLayout>