Add selected state, create abstract bottom sheet dialog class
This commit is contained in:
parent
12bf27fcd2
commit
975833b3d8
11 changed files with 195 additions and 149 deletions
|
@ -7,9 +7,7 @@ import androidx.recyclerview.widget.DiffUtil
|
|||
import androidx.recyclerview.widget.ListAdapter
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.simplemobiletools.commons.R
|
||||
import com.simplemobiletools.commons.extensions.applyColorFilter
|
||||
import com.simplemobiletools.commons.extensions.getProperTextColor
|
||||
import com.simplemobiletools.commons.extensions.setImageResourceOrBeGone
|
||||
import com.simplemobiletools.commons.extensions.*
|
||||
import com.simplemobiletools.commons.models.SimpleListItem
|
||||
import kotlinx.android.synthetic.main.item_simple_list.view.*
|
||||
|
||||
|
@ -30,12 +28,19 @@ open class SimpleListItemAdapter(val activity: Activity, val onItemClicked: (Sim
|
|||
|
||||
fun bindView(item: SimpleListItem) {
|
||||
itemView.apply {
|
||||
val textColor = context.getProperTextColor()
|
||||
bottom_sheet_item_title.setText(item.textRes)
|
||||
bottom_sheet_item_title.setTextColor(textColor)
|
||||
val color = if (item.selected) {
|
||||
val primaryColor = context.getProperPrimaryColor()
|
||||
bottom_sheet_selected_icon.beVisible()
|
||||
bottom_sheet_selected_icon.applyColorFilter(primaryColor)
|
||||
primaryColor
|
||||
} else {
|
||||
context.getProperTextColor()
|
||||
}
|
||||
|
||||
bottom_sheet_item_title.setText(item.textRes)
|
||||
bottom_sheet_item_title.setTextColor(color)
|
||||
bottom_sheet_item_icon.setImageResourceOrBeGone(item.imageRes)
|
||||
bottom_sheet_item_icon.applyColorFilter(textColor)
|
||||
bottom_sheet_item_icon.applyColorFilter(color)
|
||||
|
||||
setOnClickListener {
|
||||
onItemClicked(item)
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
package com.simplemobiletools.commons.dialogs
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import com.simplemobiletools.commons.R
|
||||
import com.simplemobiletools.commons.adapters.SimpleListItemAdapter
|
||||
import com.simplemobiletools.commons.fragments.BaseBottomSheetDialogFragment
|
||||
import com.simplemobiletools.commons.models.SimpleListItem
|
||||
import kotlinx.android.synthetic.main.layout_simple_recycler_view.*
|
||||
|
||||
class BottomSheetChooserDialog : BaseBottomSheetDialogFragment() {
|
||||
|
||||
var onItemClick: ((SimpleListItem) -> Unit)? = null
|
||||
|
||||
override fun setupContentView(parent: ViewGroup) {
|
||||
val child = layoutInflater.inflate(R.layout.layout_simple_recycler_view, parent, false)
|
||||
parent.addView(child)
|
||||
setupRecyclerView()
|
||||
}
|
||||
|
||||
private fun setupRecyclerView() {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val listItems = arguments?.getParcelableArray(DATA) as Array<SimpleListItem>
|
||||
getRecyclerViewAdapter().submitList(listItems.toList())
|
||||
}
|
||||
|
||||
private fun getRecyclerViewAdapter(): SimpleListItemAdapter {
|
||||
var adapter = recycler_view.adapter as? SimpleListItemAdapter
|
||||
if (adapter == null) {
|
||||
adapter = SimpleListItemAdapter(requireActivity()) {
|
||||
onItemClick?.invoke(it)
|
||||
dismissAllowingStateLoss()
|
||||
}
|
||||
recycler_view.adapter = adapter
|
||||
}
|
||||
return adapter
|
||||
}
|
||||
|
||||
fun updateChooserItems(newItems: Array<SimpleListItem>) {
|
||||
if (isAdded) {
|
||||
getRecyclerViewAdapter().submitList(newItems.toList())
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
onItemClick = null
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "BottomSheetChooserDialog"
|
||||
private const val DATA = "data"
|
||||
|
||||
fun createChooser(
|
||||
fragmentManager: FragmentManager,
|
||||
title: Int?,
|
||||
data: Array<SimpleListItem>,
|
||||
callback: (SimpleListItem) -> Unit
|
||||
): BottomSheetChooserDialog {
|
||||
val extras = Bundle().apply {
|
||||
if (title != null) {
|
||||
putInt(BOTTOM_SHEET_TITLE, title)
|
||||
}
|
||||
putParcelableArray(DATA, data)
|
||||
}
|
||||
return BottomSheetChooserDialog().apply {
|
||||
arguments = extras
|
||||
onItemClick = callback
|
||||
show(fragmentManager, TAG)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,110 +0,0 @@
|
|||
package com.simplemobiletools.commons.dialogs
|
||||
|
||||
import android.graphics.drawable.LayerDrawable
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.content.res.ResourcesCompat
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||
import com.simplemobiletools.commons.R
|
||||
import com.simplemobiletools.commons.adapters.SimpleListItemAdapter
|
||||
import com.simplemobiletools.commons.extensions.*
|
||||
import com.simplemobiletools.commons.models.SimpleListItem
|
||||
import kotlinx.android.synthetic.main.dialog_bottom_sheet_chooser.*
|
||||
|
||||
class SimpleBottomSheetChooserDialog : BottomSheetDialogFragment() {
|
||||
|
||||
var onItemClick: ((SimpleListItem) -> Unit)? = null
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
val view = inflater.inflate(R.layout.dialog_bottom_sheet_chooser, container, false)
|
||||
val context = requireContext()
|
||||
val config = context.baseConfig
|
||||
if (!config.isUsingSystemTheme) {
|
||||
val background = ResourcesCompat.getDrawable(context.resources, R.drawable.bottom_sheet_bg, context.theme)
|
||||
val backgroundColor = context.getProperBackgroundColor()
|
||||
(background as LayerDrawable).findDrawableByLayerId(R.id.bottom_sheet_background).applyColorFilter(backgroundColor)
|
||||
view.background = background
|
||||
}
|
||||
return view
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
val title = arguments?.getInt(TITLE).takeIf { it != 0 }
|
||||
val subtitle = arguments?.getInt(SUBTITLE).takeIf { it != 0 }
|
||||
view.apply {
|
||||
bottom_sheet_title.setTextColor(context.getProperTextColor())
|
||||
bottom_sheet_title.setTextOrBeGone(title)
|
||||
bottom_sheet_subtitle.setTextColor(context.getProperTextColor())
|
||||
bottom_sheet_subtitle.setTextOrBeGone(subtitle)
|
||||
setupRecyclerView()
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private fun setupRecyclerView() {
|
||||
val listItems = arguments?.getParcelableArray(DATA) as Array<SimpleListItem>
|
||||
getAudioRouteAdapter().submitList(listItems.toList())
|
||||
}
|
||||
|
||||
private fun getAudioRouteAdapter(): SimpleListItemAdapter {
|
||||
var adapter = bottom_sheet_recycler_view.adapter as? SimpleListItemAdapter
|
||||
if (adapter == null) {
|
||||
adapter = SimpleListItemAdapter(requireActivity()) {
|
||||
onItemClick?.invoke(it)
|
||||
dismissAllowingStateLoss()
|
||||
}
|
||||
bottom_sheet_recycler_view.adapter = adapter
|
||||
}
|
||||
return adapter
|
||||
}
|
||||
|
||||
fun updateChooserItems(newItems: Array<SimpleListItem>) {
|
||||
if (isAdded) {
|
||||
getAudioRouteAdapter().submitList(newItems.toList())
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
onItemClick = null
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "BottomSheetChooser"
|
||||
private const val TITLE = "title_string"
|
||||
private const val SUBTITLE = "subtitle_string"
|
||||
private const val DATA = "data"
|
||||
|
||||
fun createChooser(
|
||||
fragmentManager: FragmentManager,
|
||||
title: Int?,
|
||||
subtitle: Int?,
|
||||
data: Array<SimpleListItem>,
|
||||
callback: (SimpleListItem) -> Unit
|
||||
): SimpleBottomSheetChooserDialog {
|
||||
val extras = Bundle().apply {
|
||||
if (title != null) {
|
||||
putInt(TITLE, title)
|
||||
}
|
||||
if (subtitle != null) {
|
||||
putInt(SUBTITLE, subtitle)
|
||||
}
|
||||
|
||||
putParcelableArray(DATA, data)
|
||||
}
|
||||
return SimpleBottomSheetChooserDialog().apply {
|
||||
arguments = extras
|
||||
onItemClick = callback
|
||||
show(fragmentManager, TAG)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package com.simplemobiletools.commons.fragments
|
||||
|
||||
import android.graphics.drawable.LayerDrawable
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.content.res.ResourcesCompat
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||
import com.simplemobiletools.commons.R
|
||||
import com.simplemobiletools.commons.extensions.*
|
||||
import kotlinx.android.synthetic.main.dialog_bottom_sheet.view.*
|
||||
|
||||
abstract class BaseBottomSheetDialogFragment : BottomSheetDialogFragment() {
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
val view = inflater.inflate(R.layout.dialog_bottom_sheet, container, false)
|
||||
val context = requireContext()
|
||||
val config = context.baseConfig
|
||||
|
||||
if (requireContext().isBlackAndWhiteTheme()) {
|
||||
view.background = ResourcesCompat.getDrawable(context.resources, R.drawable.bottom_sheet_bg_black, context.theme)
|
||||
} else if (!config.isUsingSystemTheme) {
|
||||
view.background = ResourcesCompat.getDrawable(context.resources, R.drawable.bottom_sheet_bg, context.theme).apply {
|
||||
(this as LayerDrawable).findDrawableByLayerId(R.id.bottom_sheet_background).applyColorFilter(context.getProperBackgroundColor())
|
||||
}
|
||||
}
|
||||
return view
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
val title = arguments?.getInt(BOTTOM_SHEET_TITLE).takeIf { it != 0 }
|
||||
view.apply {
|
||||
bottom_sheet_title.setTextColor(context.getProperTextColor())
|
||||
bottom_sheet_title.setTextOrBeGone(title)
|
||||
setupContentView(bottom_sheet_content_holder)
|
||||
}
|
||||
}
|
||||
|
||||
abstract fun setupContentView(parent: ViewGroup)
|
||||
|
||||
companion object {
|
||||
const val BOTTOM_SHEET_TITLE = "title_string"
|
||||
}
|
||||
}
|
|
@ -4,7 +4,7 @@ import android.os.Parcelable
|
|||
import kotlinx.android.parcel.Parcelize
|
||||
|
||||
@Parcelize
|
||||
data class SimpleListItem(val id: Int, val imageRes: Int?, val textRes: Int) : Parcelable {
|
||||
data class SimpleListItem(val id: Int, val imageRes: Int?, val textRes: Int, val selected: Boolean = false) : Parcelable {
|
||||
|
||||
companion object {
|
||||
fun areItemsTheSame(old: SimpleListItem, new: SimpleListItem): Boolean {
|
||||
|
@ -12,7 +12,7 @@ data class SimpleListItem(val id: Int, val imageRes: Int?, val textRes: Int) : P
|
|||
}
|
||||
|
||||
fun areContentsTheSame(old: SimpleListItem, new: SimpleListItem): Boolean {
|
||||
return old.imageRes == new.imageRes && old.textRes == new.textRes
|
||||
return old.imageRes == new.imageRes && old.textRes == new.textRes && old.selected == new.selected
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
16
commons/src/main/res/drawable/bottom_sheet_bg_black.xml
Normal file
16
commons/src/main/res/drawable/bottom_sheet_bg_black.xml
Normal file
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:id="@+id/bottom_sheet_background"
|
||||
android:bottom="-2dp">
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="@color/md_grey_black" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="@color/light_grey_stroke" />
|
||||
<corners
|
||||
android:topLeftRadius="@dimen/bottom_sheet_corner_radius"
|
||||
android:topRightRadius="@dimen/bottom_sheet_corner_radius" />
|
||||
</shape>
|
||||
</item>
|
||||
</layer-list>
|
3
commons/src/main/res/drawable/ic_check_circle_vector.xml
Normal file
3
commons/src/main/res/drawable/ic_check_circle_vector.xml
Normal file
|
@ -0,0 +1,3 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/>
|
||||
</vector>
|
|
@ -21,32 +21,15 @@
|
|||
tools:text="Title"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/bottom_sheet_subtitle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="@dimen/big_margin"
|
||||
android:layout_marginTop="@dimen/medium_margin"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/bottom_sheet_title"
|
||||
tools:text="This is subtitle"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/bottom_sheet_recycler_view"
|
||||
<LinearLayout
|
||||
android:id="@+id/bottom_sheet_content_holder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginVertical="@dimen/activity_margin"
|
||||
android:overScrollMode="never"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/bottom_sheet_subtitle"
|
||||
app:layout_constraintVertical_bias="0"
|
||||
tools:itemCount="3"
|
||||
tools:listitem="@layout/item_simple_list" />
|
||||
app:layout_constraintTop_toBottomOf="@id/bottom_sheet_title"
|
||||
app:layout_constraintVertical_bias="0" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -23,11 +23,25 @@
|
|||
android:id="@+id/bottom_sheet_item_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/small_margin"
|
||||
android:layout_marginHorizontal="@dimen/small_margin"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/bottom_sheet_selected_icon"
|
||||
app:layout_constraintStart_toEndOf="@id/bottom_sheet_item_icon"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="ReadMe.md" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/bottom_sheet_selected_icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/activity_margin"
|
||||
android:padding="@dimen/medium_margin"
|
||||
android:src="@drawable/ic_check_circle_vector"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/bottom_sheet_item_title"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
|
12
commons/src/main/res/layout/layout_simple_recycler_view.xml
Normal file
12
commons/src/main/res/layout/layout_simple_recycler_view.xml
Normal file
|
@ -0,0 +1,12 @@
|
|||
<androidx.recyclerview.widget.RecyclerView 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:id="@+id/recycler_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/activity_margin"
|
||||
android:layout_marginBottom="@dimen/big_margin"
|
||||
android:overScrollMode="never"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
tools:itemCount="3"
|
||||
tools:listitem="@layout/item_simple_list" />
|
|
@ -2,7 +2,7 @@ package com.simplemobiletools.commons.samples.activities
|
|||
|
||||
import android.os.Bundle
|
||||
import com.simplemobiletools.commons.activities.BaseSimpleActivity
|
||||
import com.simplemobiletools.commons.dialogs.SimpleBottomSheetChooserDialog
|
||||
import com.simplemobiletools.commons.dialogs.BottomSheetChooserDialog
|
||||
import com.simplemobiletools.commons.extensions.appLaunched
|
||||
import com.simplemobiletools.commons.extensions.toast
|
||||
import com.simplemobiletools.commons.models.SimpleListItem
|
||||
|
@ -49,14 +49,13 @@ class MainActivity : BaseSimpleActivity() {
|
|||
}
|
||||
|
||||
private fun launchBottomSheetDemo() {
|
||||
SimpleBottomSheetChooserDialog.createChooser(
|
||||
BottomSheetChooserDialog.createChooser(
|
||||
fragmentManager = supportFragmentManager,
|
||||
title = R.string.please_select_destination,
|
||||
subtitle = null,
|
||||
data = arrayOf(
|
||||
SimpleListItem(1, R.drawable.ic_settings_cog_vector, R.string.choose_video),
|
||||
SimpleListItem(2, R.drawable.ic_settings_cog_vector, R.string.choose_photo),
|
||||
SimpleListItem(4, R.drawable.ic_settings_cog_vector, R.string.choose_contact)
|
||||
SimpleListItem(1, R.drawable.ic_camera_vector, R.string.record_video),
|
||||
SimpleListItem(2, R.drawable.ic_microphone_vector, R.string.record_audio, selected = true),
|
||||
SimpleListItem(4, R.drawable.ic_add_person_vector, R.string.choose_contact)
|
||||
)
|
||||
) {
|
||||
toast("Clicked ${it.id}")
|
||||
|
|
Loading…
Reference in a new issue