Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Comment thread
malilex marked this conversation as resolved.
Comment thread
angirb marked this conversation as resolved.
Comment thread
angirb marked this conversation as resolved.
Comment thread
angirb marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
---
title: NavigationBar
---

Верхняя панель интерфейса, служащая для навигации и отображения ключевых действий.
В качестве текста, контента и action может принимать произвольный контент.

```xml
<!-- @sample: com/sdds/uikit/fixtures/NavigationBar_Simple.xml -->
```

## Стиль NavigationBar

Существует набор сгенерированных стилей. Так же можно настроить стиль самостоятельно.
Для настройки стиля NavigationBar в формате xml предусмотрены следующие атрибуты:

|Название атрибута|Описание|Формат данных|
|:-:|:-:|:-:|
|sd_iconButtonStyleOverlay|оверлэй стиль компонента IconButton|reference|
|sd_shadowAppearance|стиль тени|reference|
|sd_shapeAppearance|форма компонента|reference|
|sd_contentPaddingStart|отступ в начале блока, содержащего actions|dimension|
|sd_contentPaddingEnd|отступ в конце блока, содержащего actions|dimension|
|sd_contentPaddingTop|верхний отступ блока, содержащего actions|dimension|
|sd_contentPaddingBottom|нижний отступ блока, содержащего actions|dimension|
|sd_descriptionMargin|отступ между Title и Description|dimension, reference|
|sd_backIcon|ссылка на ресурс иконки "назад"|reference|
|sd_backIconMargin|отступ от иконки "назад" и ActionStart|dimension|
|sd_textBlockTopMargin|верхний отступ от текстового блока если он находится ниже actions|dimension|
|sd_horizontalSpacing|отступ от actions и между контентом в блоке с actions|dimension|
|sd_actionStartColor|цвет action в начале|reference, color|
|sd_actionEndColor|цвет action в конце|reference, color|
|sd_titleAppearance|стиль текста Title|reference|
|sd_titleColor|цвет текста Title|color|
|sd_backIconTint|окрас иконки "назад"|reference|
|sd_descriptionAppearance|стиль текста Description|reference|
|sd_descriptionColor|цвет текста Description|color|
|sd_background|цвет фона|reference, color|
|sd_navbarContentPlacement|расположение компонента с ролью Content|enum(INLINE, bottom)|
|sd_navbarTextPlacement|расположение компонентов с ролью Title и Description|enum(INLINE, bottom)|
|sd_navbarTextAlignment|выравнивание компонентов с ролью Title и Description|enum(start, center, end)|
|sd_contentAlignmentBetweenActions|выравнивание контента, находящегося между ActionStart и ActionEnd по горизонтали|enum(start, center, end)|
|sd_centerAlignmentStrategy|центрирование контента, находящегося в одном блоке с ActionStart и ActionEnd по горизонтали|enum(absolute, relative)|

### Для расположения дочерних view

|Название атрибута|Описание|Формат данных|
|:-:|:-:|:-:|
|layout_navigationBarContent|роли компонентов, размещаемых внутри NavigationBar|enum(title, description, action_start,action_end, content)|

## Роли компонентов внутри NavigationBar

Роли компонентов через xml задаются с помощью атрибута layout_navigationBarContent. В коде реализованы удобные сеттеры
для каждой роли, например `setContent(content: View, params: NavigationBarLayoutParams? = null)`. При использовании
таких сеттеров, задавать параметры не обязательно, они сгенерируются автоматически. Однако, при добавлении view через
стандартную функцию addView(), при отсутствии NavigationBarLayoutParams и роли компонента в этих параметрах, будет
установлена роль Content (как по умолчанию).

## Структура компонента NavigationBar

NavigationBar наследник LinearLayout, ориентация - вертикальная. Верхнеуровнево компонент разделен на две части.
1 - Верхняя часть включает в себя блок, где по бокам расположены actions (ActionStart и ActionEnd), а между ними -
место для размещения контента при `textPlacement = TEXT_PLACEMENT_INLINE` и/или `contentPlacement = CONTENT_PLACEMENT_INLINE`.
Ниже блока с actions, при `textPlacement = TEXT_PLACEMENT_BOTTOM` располагается текстовый блок, содержащий Title
и Description. Вся верхняя часть ограничена заданными padding, с помощью атрибутов
(sd_contentPaddingStart sd_contentPaddingTop и т.д.) или через функцию ????????.
2 - Нижняя часть компонента, не ограничена padding. В ней размещается Content при
`contentPlacement = CONTENT_PLACEMENT_BOTTOM`.

## Расположение компонентов с ролями Title и Description внутри NavigationBar

За расположение Title и Description отвечает атрибут sd_navbarTextPlacement или свойство textPlacement.
Как упоминалось выше, при `textPlacement = TEXT_PLACEMENT_BOTTOM`, текстовый блок, содержащий Title и Description,
будет размещен в верхней части NavigationBar, ниже блока с actions. При установке `textPlacement = TEXT_PLACEMENT_INLINE`
текстовый блок будет размещен между ActionStart и ActionEnd.

## Расположение компонента с ролью Content внутри NavigationBar

За расположение Content отвечает атрибут sd_navbarContentPlacement или свойство contentPlacement. Как упоминалось выше,
при `contentPlacement = CONTENT_PLACEMENT_BOTTOM`, компонент с ролью Content будет размещен в нижней части
NavigationBar (как обычный элемент вертикального LinearLayout). При установке `contentPlacement = CONTENT_PLACEMENT_INLINE`
Content будет размещаться в верхней части NavigationBar между ActionStart и ActionEnd. Если Title и Description
так же находятся в блоке с actions, Content всегда будет размещаться после них (по горизонтали).

## Выравнивание компонента с ролью Content внутри NavigationBar

Так как NavigationBar наследник LinearLayout, выравнивание Content при `contentPlacement = CONTENT_PLACEMENT_BOTTOM`
осуществляется с помощью установки Gravity самого NavigationBar. Выравнивание при
`contentPlacement = CONTENT_PLACEMENT_INLINE` описано ниже.

## Выравнивание компонентов с ролями Title и Description внутри NavigationBar

Как упоминалось выше, NavigationBar разделен на две части, поскольку текстовый блок, содержащий Title и Description
находится в верхней части, он не "подчиняется" Gravity самого компонента. Если
`textPlacement = TEXT_PLACEMENT_BOTTOM` или атрибут `sd_navbarTextPlacement = bottom` используйте атрибут
sd_navbarTextAlignment или свойство textBlockAlignment. Стоит отметить, что при выравнивании
всего текстового блока, так же выравнивается контент внутри него, например, при установке
`textBlockAlignment = TEXT_ALIGNMENT_START` текстовый блок будет выровнен по краю в начале NavigationBar, а
Title и Description будут выровнены по краю в начале самого текстового блока. Аналогично для случаев с
TEXT_ALIGNMENT_CENTER и TEXT_ALIGNMENT_END.

## Выравнивание контента, находящегося между ActionStart и ActionEnd

За выравнивание в этом блоке отвечает атрибут sd_contentAlignmentBetweenActions или свойство
contentAlignmentBetweenActions.

## Стратегия выравнивания контента, находящегося между ActionStart и ActionEnd

С помощью атрибута sd_centerAlignmentStrategy или свойства centerAlignmentStrategy определяется как именно
будет выровнен контент в этом блоке. При `centerAlignmentStrategy = ALIGNMENT_STRATEGY_ABSOLUTE` и
`contentAlignmentBetweenActions = CONTENT_ALIGNMENT_BETWEEN_ACTIONS_CENTER` возможно добиться центрирования
контента относительно центра самого компонента NavigationBar, даже, при отсутствии контента в одном из actions.
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,10 @@ import com.sdds.playground.sandbox.indicator.compose.IndicatorScreen
import com.sdds.playground.sandbox.list.compose.ListScreen
import com.sdds.playground.sandbox.loader.compose.LoaderScreen
import com.sdds.playground.sandbox.modal.compose.ModalScreen
import com.sdds.playground.sandbox.navigationbar.NavigationBarPreview
import com.sdds.playground.sandbox.navigationbar.NavigationBarScreen
import com.sdds.playground.sandbox.navigationbar.collapsing.CollapsingNavigationBarPreview
import com.sdds.playground.sandbox.navigationbar.collapsing.CollapsingNavigationBarScreen
import com.sdds.playground.sandbox.navigationbar.compose.NavigationBarPreview
import com.sdds.playground.sandbox.navigationbar.compose.NavigationBarScreen
import com.sdds.playground.sandbox.note.compose.NoteCompactPreview
import com.sdds.playground.sandbox.note.compose.NoteCompactScreen
import com.sdds.playground.sandbox.note.compose.NotePreview
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import com.sdds.playground.sandbox.indicator.vs.IndicatorFragment
import com.sdds.playground.sandbox.list.vs.ListFragment
import com.sdds.playground.sandbox.loader.vs.LoaderFragment
import com.sdds.playground.sandbox.modal.vs.ModalFragment
import com.sdds.playground.sandbox.navigationbar.vs.NavigationBarFragment
import com.sdds.playground.sandbox.navigationdrawer.NavigationDrawerFragment
import com.sdds.playground.sandbox.note.vs.NoteCompactFragment
import com.sdds.playground.sandbox.note.vs.NoteFragment
Expand Down Expand Up @@ -111,6 +112,7 @@ import com.sdds.testing.vs.list.listView
import com.sdds.testing.vs.loader.loader
import com.sdds.testing.vs.mask.maskedTextField
import com.sdds.testing.vs.modal.modalTrigger
import com.sdds.testing.vs.navigationbar.navigationBar
import com.sdds.testing.vs.navigationdrawer.NavigationDrawerUiState
import com.sdds.testing.vs.navigationdrawer.navigationDrawer
import com.sdds.testing.vs.note.note
Expand Down Expand Up @@ -429,6 +431,10 @@ internal sealed class ComponentScreen(
object File : ComponentScreen(
{ item -> fragment<FileFragment>(item.route, item.defaultBuilder) },
)

object NavigationBar : ComponentScreen(
{ item -> fragment<NavigationBarFragment>(item.route, item.defaultBuilder) },
)
}

@Suppress("CyclomaticComplexMethod", "LongMethod")
Expand Down Expand Up @@ -493,6 +499,7 @@ private fun CoreComponent.screen(): ComponentScreen {
CoreComponent.CAROUSEL -> ComponentScreen.Carousel
CoreComponent.AUTOCOMPLETE -> ComponentScreen.Autocomplete
CoreComponent.FILE -> ComponentScreen.File
CoreComponent.NAVIGATION_BAR -> ComponentScreen.NavigationBar
else -> throw NoSuchElementException("Component not implemented")
}
}
Expand Down Expand Up @@ -559,6 +566,7 @@ private fun ComponentKey.routeId(): Int? {
CoreComponent.CAROUSEL -> R.id.nav_carousel
CoreComponent.AUTOCOMPLETE -> R.id.nav_autocomplete
CoreComponent.FILE -> R.id.nav_file
CoreComponent.NAVIGATION_BAR -> R.id.nav_navigation_bar
else -> null
}?.let { it + hashCode() }
}
Expand Down Expand Up @@ -671,6 +679,7 @@ internal fun MenuItem.preview(context: Context, style: Int): View {
CoreComponent.CAROUSEL -> carousel(context, style)
CoreComponent.AUTOCOMPLETE -> autocomplete(context, style)
CoreComponent.FILE -> file(context, style)
CoreComponent.NAVIGATION_BAR -> navigationBar(context, style)
else -> throw NoSuchElementException("Component not implemented")
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.sdds.playground.sandbox.navigationbar
package com.sdds.playground.sandbox.navigationbar.compose

import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.RowScope
Expand All @@ -18,6 +18,7 @@ import com.sdds.compose.uikit.NavigationBarStyle
import com.sdds.compose.uikit.NavigationBarTextAlign
import com.sdds.compose.uikit.NavigationBarTextPlacement
import com.sdds.compose.uikit.Text
import com.sdds.icons.R
import com.sdds.playground.sandbox.SandboxTheme
import com.sdds.playground.sandbox.core.compose.ComponentScaffold
import com.sdds.playground.sandbox.core.integration.component.ComponentKey
Expand Down Expand Up @@ -71,7 +72,7 @@ private fun actionStart(hasAction: Boolean): (@Composable RowScope.() -> Unit)?
return if (hasAction) {
@Composable {
Icon(
painter = painterResource(com.sdds.icons.R.drawable.ic_search_24),
painter = painterResource(R.drawable.ic_search_24),
contentDescription = "",
)
}
Expand All @@ -84,7 +85,7 @@ private fun actionEnd(hasAction: Boolean): (@Composable RowScope.() -> Unit)? {
return if (hasAction) {
@Composable {
Icon(
painter = painterResource(com.sdds.icons.R.drawable.ic_menu_24),
painter = painterResource(R.drawable.ic_menu_24),
contentDescription = "",
)
}
Expand All @@ -111,7 +112,7 @@ private fun textContent(text: String): (@Composable () -> Unit)? {
Spacer(Modifier.width(4.dp))
Icon(
modifier = Modifier,
painter = painterResource(com.sdds.icons.R.drawable.ic_clip_24),
painter = painterResource(R.drawable.ic_clip_24),
contentDescription = "",
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.sdds.playground.sandbox.navigationbar
package com.sdds.playground.sandbox.navigationbar.compose

import com.sdds.compose.uikit.NavBarCenterAlignmentStrategy
import com.sdds.compose.uikit.NavigationBarContentPlacement
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.sdds.playground.sandbox.navigationbar
package com.sdds.playground.sandbox.navigationbar.compose

import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.sdds.playground.sandbox.navigationbar.vs

import android.view.ContextThemeWrapper
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import android.widget.FrameLayout
import android.widget.FrameLayout.LayoutParams
import androidx.core.view.setMargins
import androidx.lifecycle.ViewModelProvider
import com.sdds.playground.sandbox.core.vs.ComponentFragment
import com.sdds.testing.vs.navigationbar.NavigationBarUiState
import com.sdds.testing.vs.navigationbar.applyState
import com.sdds.testing.vs.navigationbar.navigationBar
import com.sdds.uikit.NavigationBar

/**
* Фрагмент с компонентом NoteCompact
*/
internal class NavigationBarFragment :
ComponentFragment<NavigationBarUiState, NavigationBar, NavigationBarParametersViewModel>() {

override val viewModelFactory: ViewModelProvider.Factory by lazy {
NavigationBarParametersViewModelFactory(
defaultState = getState { NavigationBarUiState() },
componentKey = componentKey,
)
}

override val defaultLayoutParams: FrameLayout.LayoutParams
get() = LayoutParams(MATCH_PARENT, WRAP_CONTENT).apply { setMargins(50) }

override fun getComponent(contextWrapper: ContextThemeWrapper): NavigationBar {
return navigationBar(contextWrapper)
}

override fun onComponentUpdate(component: NavigationBar?, state: NavigationBarUiState) {
component?.applyState(state)
}
}
Loading
Loading