Вы делаете замечательную компонуемую функцию. Он имеет сложный пользовательский интерфейс с привлекательной анимацией и большим количеством возможностей для настройки. Вы тратите часы на эту функцию, пытаясь сделать ее идеальной. Но у него слишком много параметров для настройки.
@Composable fun MyFancyComponent( value: Int, onValueChanged: (Int) -> Unit, modifier: Modifier = Modifier, primaryColor: Color = Color.Black, accentColor: Color = Color.Red, itemSpacing: Dp = 8.dp, componentStyle: ComponentStyle = ComponentStyle.Normal, // [...] ) {/* ... */}
В то время как некоторые люди предпочли бы использовать этот подход для своих составных объектов и вызывать функции с именованными параметрами, некоторые не хотели бы, чтобы их список параметров был загроможден, и хотели бы найти альтернативу. Что-то похожее на то, как работают Modifier
.
Modifier
— это интерфейс, в котором вы можете связать свойства, которые вы хотите, чтобы ваш макет компоновался в соответствии с вашим дизайном. Давайте попробуем применить эту технику для функции MyFancyComponent
.
В вашем проекте давайте создадим класс и назовем его MyFancyComponentAttributes
. Это будет иметь все свойства, необходимые для этой составной функции. Для каждого свойства, которое вы хотите добавить, сохраните его общедоступным со значением по умолчанию и частным сеттером и добавьте функцию с тем же именем, что и свойство.
Например, мы создали класс и хотим добавить атрибут primaryColor
, мы можем написать,
class MyFancyComponentAttributes { var primaryColor: Color = Color.Black priavte set fun primaryColor(value: Color) = apply { primaryColor = value } // [...] }
Функция примет цвет в качестве параметра и вернет тот же объект с измененным свойством. Продолжайте делать это для всех свойств.
Теперь измените компонуемую функцию на
/* in your composable file */ @Composable fun MyFancyComponent( value: Int, onValueChanged: (Int) -> Unit, modifier: Modifier = Modifier, attrs: MyFancyComponentAttributes = MyFancyComponentAttributes() ) { // Access properties by attrs.primaryColor, etc } /* while calling the composable function */ MyFancyComponent( value = number, onValueChanged = { number = it}, modifier = Modifier .padding(horizontal = 16.dp), attrs = MyFancyComponentAttributes() .primaryColor(Color.White) .accentColor(Color.Purple) .itemSpacing(12.dp) )
Это простой, но мощный метод отделения необходимых атрибутов от загромождения определения функции, и он согласуется с шаблоном Modifier
, предоставленным Google.