Add selected state, create abstract bottom sheet dialog class

This commit is contained in:
Naveen 2022-11-11 05:54:30 +05:30
parent 12bf27fcd2
commit 975833b3d8
11 changed files with 195 additions and 149 deletions

View file

@ -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)

View file

@ -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)
}
}
}
}

View file

@ -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)
}
}
}
}

View file

@ -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"
}
}

View file

@ -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
}
}
}

View 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>

View 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>

View file

@ -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>

View file

@ -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>

View 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" />

View file

@ -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}")