Skip to content

Commit

Permalink
Merge pull request #6 from Trendyol/feature/list-dialog
Browse files Browse the repository at this point in the history
Feature/list dialog
  • Loading branch information
bilgehankalkan authored Dec 2, 2019
2 parents 95e64ef + af4cad4 commit b8ba06d
Show file tree
Hide file tree
Showing 21 changed files with 423 additions and 130 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ UI Components for Android by Trendyol Android team.

UI Components includes several custom views for Android platform to make developers life easier!

<img src="https://raw.githubusercontent.com/Trendyol/android-ui-components/master/images/1.png" width="240"/>
<img src="https://raw.githubusercontent.com/Trendyol/android-ui-components/master/images/1.png" width="240"/> <img src="https://raw.githubusercontent.com/Trendyol/android-ui-components/master/images/2.png" width="240"/>

## Why? ##
[Trendyol](https://play.google.com/store/apps/details?id=trendyol.com) Android application, we are using several custom view implementations that can be useful for other apps.
Expand Down
Binary file added images/2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/dialogs-3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
44 changes: 35 additions & 9 deletions libraries/dialogs/README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@

<img src="https://raw.githubusercontent.com/Trendyol/android-ui-components/master/images/dialogs-1.png" width="240"/> <img src="https://raw.githubusercontent.com/Trendyol/android-ui-components/master/images/dialogs-2.png" width="240"/>
<img src="https://raw.githubusercontent.com/Trendyol/android-ui-components/master/images/dialogs-1.png" width="240"/> <img src="https://raw.githubusercontent.com/Trendyol/android-ui-components/master/images/dialogs-2.png" width="240"/> <img src="https://raw.githubusercontent.com/Trendyol/android-ui-components/master/images/dialogs-3.png" width="240"/>

$dialogsVersion = dialogs-1.0.1 [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
$dialogsVersion = dialogs-1.0.2 [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)

## Dialogs
Dialogs is a bunch of BottomSheetDialogs to use in app to show user an information, agreement or list.

# Installation
## Installation
- To implement **Dialogs** to your Android project via Gradle, you need to add JitPack repository to your root build.gradle.
```gradle
allprojects {
Expand All @@ -20,10 +20,10 @@ dependencies {
:warning: To use **Dialogs**, you have to enable dataBinding from your main project, and implement material library into app level `build.gradle`.
:warning: **Dialogs** can only usable via Kotlin.

# Usage
## Usage
You can configure your dialog with given extensions with Kotlin DSL syntax.

To show the dialog you just need to call `show(FragmentManager)` function.
To show the dialog you just need to call `showDialog(FragmentManager)` function.

* Info Dialog:

Expand Down Expand Up @@ -78,18 +78,44 @@ agreementDialog {
}
}.showDialog(supportFragmentManager)
```
# TODOs

* Selection Dialog:

Dialog with list that user can select. There will be checkBox on the left side of each line and user can change the selection.
All **Info Dialog** arguments plus these arguments will be applicable to show selection dialogs.

| Field | Type | Description | Default Value |
| ------------- |-------------|-------------| ------------- |
| `items` | List<Pair<Boolean, String>> | Item list that will be listed on dialog. | null |
| `showItemsAsHtml` | Boolean | Item texts will be parsed as Html if this flag setted as true. | false |
| `onItemSelectedListener` | (DialogFragment, Int) -> Unit | Listener to notify selected index. | null |

Sample usage:
```kotlin
selectionDialog {
title = "Selection Dialog Title"
content = getContent()
items = getItemsAsHtml()
showItemsAsHtml = true
onItemSelectedListener = { dialog, index ->
dialog.dismiss()
onItemSelected(index)
}
}
```

## TODOs
* Implement ListDialog.
* Implement SelectionDialog
* ~~Implement SelectionDialog~~
* Implement search line.
* Implement multiple selectable type.
* Provide theme for more styling.
* Update builder for Java.

# Contributors
## Contributors
This library is maintained mainly by Trendyol Android Team members but also other Android lovers contributes.

# License
## License
Copyright 2019 Trendyol.com

Licensed under the Apache License, Version 2.0 (the "License");
Expand Down
2 changes: 1 addition & 1 deletion libraries/dialogs/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ apply plugin: 'kotlin-kapt'
apply plugin: 'com.github.dcendents.android-maven'

group="com.trendyol.ui-components"
version="1.0.1"
version="1.0.2"

android {
compileSdkVersion 29
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import android.view.View
import androidx.annotation.DrawableRes
import androidx.appcompat.widget.AppCompatImageView
import androidx.databinding.BindingAdapter
import androidx.recyclerview.widget.RecyclerView
import com.trendyol.uicomponents.dialogs.list.DialogListAdapter

@BindingAdapter("drawableResource")
internal fun AppCompatImageView.setDrawableResource(@DrawableRes drawableResId: Int?) {
Expand All @@ -19,3 +21,10 @@ internal fun AppCompatImageView.setDrawableResource(@DrawableRes drawableResId:
internal fun View.setVisibility(isVisible: Boolean) {
visibility = if (isVisible) View.VISIBLE else View.GONE
}

@BindingAdapter("items")
internal fun RecyclerView.setItems(items: List<Pair<Boolean, CharSequence>>?) {
if (items != null) {
(adapter as? DialogListAdapter)?.setItems(items)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ open class InfoDialogBuilder internal constructor() : Builder() {
}
}

class AgreementDialogBuilder internal constructor() : InfoDialogBuilder() {
open class AgreementDialogBuilder internal constructor() : InfoDialogBuilder() {

var rightButtonText: String = ""
var leftButtonText: String = ""
Expand All @@ -54,3 +54,25 @@ class AgreementDialogBuilder internal constructor() : InfoDialogBuilder() {
)
}
}

class SelectionDialogBuilder internal constructor() : InfoDialogBuilder() {

var items: List<Pair<Boolean, CharSequence>> = emptyList()
var showItemsAsHtml: Boolean = false
var onItemSelectedListener: ((DialogFragment, Int) -> Unit)? = null

internal fun buildSelectionDialog(block: SelectionDialogBuilder.() -> Unit): DialogFragment =
SelectionDialogBuilder().apply(block).let {
DialogFragment(
title = it.title,
showCloseButton = it.showCloseButton,
closeButtonListener = it.closeButtonListener,
content = SpannableString(it.content),
showContentAsHtml = it.showContentAsHtml,
contentImage = it.contentImage,
items = it.items,
showItemsAsHtml = it.showItemsAsHtml,
onItemSelectedListener = it.onItemSelectedListener
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ fun infoDialog(block: InfoDialogBuilder.() -> Unit): DialogFragment =

fun agreementDialog(block: AgreementDialogBuilder.() -> Unit): DialogFragment =
AgreementDialogBuilder().buildAgreementDialog(block)

fun selectionDialog(block: SelectionDialogBuilder.() -> Unit): DialogFragment =
SelectionDialogBuilder().buildSelectionDialog(block)
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,26 @@ import androidx.annotation.DrawableRes
import androidx.fragment.app.FragmentManager
import com.trendyol.dialog.R
import com.trendyol.dialog.databinding.FragmentDialogBinding
import com.trendyol.uicomponents.dialogs.list.DialogListAdapter

class DialogFragment internal constructor(
private val title: String? = null,
private val showCloseButton: Boolean? = null,
private val closeButtonListener: ((DialogFragment) -> Unit)? = null,
private val content: SpannableString? = null,
private val content: CharSequence? = null,
private val showContentAsHtml: Boolean = false,
@DrawableRes private val contentImage: Int? = null,
private val leftButtonText: String? = null,
private val rightButtonText: String? = null,
private val leftButtonClickListener: ((DialogFragment) -> Unit)? = null,
private val rightButtonClickListener: ((DialogFragment) -> Unit)? = null
private val rightButtonClickListener: ((DialogFragment) -> Unit)? = null,
private val items: List<Pair<Boolean, CharSequence>>? = null,
private val showItemsAsHtml: Boolean = false,
private val onItemSelectedListener: ((DialogFragment, Int) -> Unit)? = null
) : BaseBottomSheetDialog<FragmentDialogBinding>() {

private val itemsAdapter by lazy { DialogListAdapter(showItemsAsHtml) }

override fun getLayoutResId(): Int = R.layout.fragment_dialog

override fun setUpView() {
Expand All @@ -33,6 +39,13 @@ class DialogFragment internal constructor(
buttonRight.setOnClickListener {
rightButtonClickListener?.invoke(this@DialogFragment)
}

recyclerViewItems.adapter = itemsAdapter
recyclerViewItems.isNestedScrollingEnabled = false

itemsAdapter.onItemSelectedListener = { position ->
onItemSelectedListener?.invoke(this@DialogFragment, position)
}
}
}

Expand All @@ -44,8 +57,10 @@ class DialogFragment internal constructor(
showContentAsHtml = showContentAsHtml,
contentImage = contentImage,
leftButtonText = leftButtonText,
rightButtonText = rightButtonText
rightButtonText = rightButtonText,
listItems = items
)

binding.viewState = viewState
binding.executePendingBindings()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,32 @@
package com.trendyol.uicomponents.dialogs

import android.text.Spanned
import androidx.annotation.DrawableRes
import androidx.core.text.HtmlCompat

data class DialogViewState(
val title: String?,
val showCloseButton: Boolean?,
private val content: Spanned,
private val content: CharSequence,
val showContentAsHtml: Boolean,
@DrawableRes val contentImage: Int?,
val leftButtonText: String? = null,
val rightButtonText: String? = null
val rightButtonText: String? = null,
val listItems: List<Pair<Boolean, CharSequence>>? = null
) {

fun isLeftButtonVisible(): Boolean = leftButtonText != null

fun isRightButtonVisible(): Boolean = rightButtonText != null

fun getContent(): Spanned = if (showContentAsHtml) {
fun getContent(): CharSequence = if (showContentAsHtml) {
HtmlCompat.fromHtml(content.toString(), HtmlCompat.FROM_HTML_MODE_COMPACT)
} else {
content
}

fun isContentVisible(): Boolean = content.isNotEmpty()

fun isContentImageVisible(): Boolean = contentImage != null

fun isListVisible(): Boolean = !listItems.isNullOrEmpty()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.trendyol.uicomponents.dialogs

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.annotation.LayoutRes
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding

internal fun <T : ViewDataBinding> ViewGroup?.inflate(
@LayoutRes layoutId: Int,
attachToParent: Boolean = true
): T {
if (this?.isInEditMode == true) {
View.inflate(context, layoutId, parent as? ViewGroup?)
}
return DataBindingUtil.inflate(
LayoutInflater.from(this!!.context),
layoutId,
this,
attachToParent
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package com.trendyol.uicomponents.dialogs.list

import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.trendyol.dialog.R
import com.trendyol.dialog.databinding.ItemListBinding
import com.trendyol.uicomponents.dialogs.inflate

internal class DialogListAdapter(
private val showItemsAsHtml: Boolean
) : RecyclerView.Adapter<DialogListAdapter.ItemViewHolder>() {

private var items: List<Pair<Boolean, CharSequence>> = emptyList()
var onItemSelectedListener: ((Int) -> Unit)? = null

fun setItems(list: List<Pair<Boolean, CharSequence>>) {
items = items.toMutableList().apply {
clear()
addAll(list)
}
notifyDataSetChanged()
}

private fun updateList(selectedItemPosition: Int) {
var firstSelectedItemPosition = 0
items = items.mapIndexed { index, item ->
if (item.first) {
firstSelectedItemPosition = index
}
item.copy(first = index == selectedItemPosition, second = item.second)
}
notifyItemChanged(firstSelectedItemPosition)
notifyItemChanged(selectedItemPosition)
}

override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
holder.bind(items[position])
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder =
ItemViewHolder(parent.inflate(R.layout.item_list, false))

override fun getItemCount(): Int = items.size

inner class ItemViewHolder(
private val binding: ItemListBinding
) : RecyclerView.ViewHolder(binding.root) {

init {
binding.radioButtonItem.setOnCheckedChangeListener { radioButton, isChecked ->
if (radioButton.isPressed && isChecked) {
updateList(selectedItemPosition = adapterPosition)
onItemSelectedListener?.invoke(adapterPosition)
}
}
}

fun bind(item: Pair<Boolean, CharSequence>) {
binding.viewState = DialogListItemViewState(
name = item.second,
showAsHtml = showItemsAsHtml,
isChecked = item.first
)
binding.executePendingBindings()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.trendyol.uicomponents.dialogs.list

import androidx.core.text.HtmlCompat

data class DialogListItemViewState(
val name: CharSequence,
val showAsHtml: Boolean,
val isChecked: Boolean
) {

fun getText(): CharSequence = if (showAsHtml) {
HtmlCompat.fromHtml(name.toString(), HtmlCompat.FROM_HTML_MODE_COMPACT)
} else {
name
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M12,7c-2.76,0 -5,2.24 -5,5s2.24,5 5,5 5,-2.24 5,-5 -2.24,-5 -5,-5zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8z"/>
</vector>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8z"/>
</vector>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

<item android:drawable="@drawable/ic_radio_button_checked" android:state_checked="true" />
<item android:drawable="@drawable/ic_radio_button_unchecked" android:state_checked="false" />
</selector>
Loading

0 comments on commit b8ba06d

Please sign in to comment.