Home > Back-end >  How to use different kinds of placeholders in enum classes
How to use different kinds of placeholders in enum classes

Time:06-11

Is it possible within an enum class to enable it for different kinds of placeholders? I want to use 1 item that has 1 placeholder, then another item that has 2 placeholders. The current code I have seems to only allow me to use 1 placeholder.

strings.xml

<string name="size_placeholder">Size %1$d</string>
<string name="sizes_placeholder_and_placeholder">Sizes %1$d and %2$d</string>

MainActivity.kt

enum class Clothes(@StringRes val nameId: Int, val sizeId: Int, val onePlaceholder: Int, val twoPlaceholders: Int) {
    ItemA(R.string.item_a, R.string.size_placeholder, 8),
    ItemB(R.string.item_B, R.string.sizes_placeholder_and_placeholder, 0, 2);
}
...

LazyColumn(
    state = listState,
    modifier = Modifier.weight(1f)
        .padding(it)
) {
    items(items) {
        Column() {
            Text(text = stringResource(id = it.nameId))
            Text(text = stringResource(id = it.sizeId, it.onePlaceholder, it.twoPlaceholders))
        }
    }
}

Expected result

enter image description here

UPDATE (MainActivity.kt)

enum class Clothes(@StringRes val nameId: Int, val sizeId: Int, val myPlaceholder: Int, vararg myPlaceholders: Any) {
    ItemA(R.string.item_a, R.string.size_placeholder, 8),
    ItemB(R.string.item_B, R.string.sizes_placeholder_and_placeholder, arrayOf(0, 2));
}
...

LazyColumn(
    state = listState,
    modifier = Modifier.weight(1f)
        .padding(it)
) {
    items(items) {
        Column() {
            Text(text = stringResource(id = it.nameId))
            Text(text = stringResource(id = it.sizeId, it.myPlaceholders))
        }
    }
}

CodePudding user response:

stringResource() takes a vararg for placeholder values. So, you use:

stringResource(id = it.sizeId, it.onePlaceholder, it.twoPlaceholders)

For example, I created a scrap project in Android Studio Chipmunk, using the Empty Compose Activity template. I set up strings.xml to be:

<resources>
  <string name="app_name">My Application</string>
  <string name="size_placeholder">Size %1$d</string>
  <string name="sizes_placeholder_and_placeholder">Sizes %1$d and %2$d</string>
  <string name="item_a">Item A</string>
  <string name="item_B">Item B</string>

</resources>

And I set up MainActivity.kt to be:

package com.commonsware.myapplication

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.annotation.StringRes
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import com.commonsware.myapplication.ui.theme.MyApplicationTheme

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MyApplicationTheme {
                // A surface container using the 'background' color from the theme
                Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colors.background) {
                    Content()
                }
            }
        }
    }
}

enum class Clothes(@StringRes val nameId: Int, val sizeId: Int, val onePlaceholder: Int, val twoPlaceholders: Int) {
    ItemA(R.string.item_a, R.string.size_placeholder, 8, 1337),
    ItemB(R.string.item_B, R.string.sizes_placeholder_and_placeholder, 0, 2);
}

@Preview
@Composable
fun Content() {
    val listState = rememberLazyListState()

    LazyColumn(
        state = listState
    ) {
        items(listOf(Clothes.ItemA, Clothes.ItemB)) {
            Column {
                Text(text = stringResource(id = it.nameId))
                Text(text = stringResource(id = it.sizeId, it.onePlaceholder, it.twoPlaceholders))
            }
        }
    }
}

The result, while lacking your desired formatting, matches the desired content:

Output of above composable

CodePudding user response:

If I understand your question, you wanted to define a specific groupings of a some type and have them some distinction from each other.

Regardless, I would approach this with sealed classes or a simple object of a class with varying arguments varargs of placeholder strings.

sealed class Clothes {
  data class FixedSizeClothing(val size: String, val placeholder: String) : Clothes()

  data class MultiSizeClothing(val sizes: List<String>, val placeholders: 
  List<String>): Clothes()
}
  • Related