or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

font-resources.mdimage-drawable-resources.mdindex.mdplural-string-resources.mdresource-environment.mdstring-array-resources.mdstring-resources.md

string-array-resources.mddocs/

0

# String Array Resources

1

2

String array resources provide type-safe access to collections of localized strings. This is useful for lists of options, categories, labels, or any collection of related text entries that need to be localized together.

3

4

## Core Types

5

6

```kotlin { .api }

7

class StringArrayResource(id: String, val key: String, items: Set<ResourceItem>) : Resource(id, items)

8

```

9

10

A string array resource represents an ordered collection of localized strings identified by a unique key. Each array can have different variants for different locales and configurations.

11

12

## Composable Functions

13

14

### String Array Loading

15

16

```kotlin { .api }

17

@Composable

18

fun stringArrayResource(resource: StringArrayResource): List<String>

19

```

20

21

Loads a string array resource within a Composable context. The function automatically selects the appropriate array variant based on the current environment and locale.

22

23

**Usage:**

24

```kotlin

25

@Composable

26

fun CategorySelection() {

27

val categories = stringArrayResource(Res.array.product_categories)

28

29

LazyColumn {

30

items(categories) { category ->

31

Text(

32

text = category,

33

modifier = Modifier

34

.fillMaxWidth()

35

.clickable { onCategorySelected(category) }

36

.padding(16.dp)

37

)

38

}

39

}

40

}

41

42

@Composable

43

fun SettingsOptions() {

44

val options = stringArrayResource(Res.array.notification_options)

45

46

options.forEachIndexed { index, option ->

47

Row(

48

modifier = Modifier.clickable { selectOption(index) },

49

verticalAlignment = Alignment.CenterVertically

50

) {

51

RadioButton(

52

selected = selectedIndex == index,

53

onClick = { selectOption(index) }

54

)

55

Text(text = option, modifier = Modifier.padding(start = 8.dp))

56

}

57

}

58

}

59

```

60

61

## Suspend Functions

62

63

### Non-Composable Array Loading

64

65

```kotlin { .api }

66

suspend fun getStringArray(resource: StringArrayResource): List<String>

67

```

68

69

Loads a string array resource outside of a Composable context using the system's resource environment.

70

71

**Usage:**

72

```kotlin

73

suspend fun loadMenuOptions(): List<String> {

74

return getStringArray(Res.array.menu_options)

75

}

76

77

class DataLoader {

78

suspend fun getAvailableLanguages(): List<String> {

79

return getStringArray(Res.array.supported_languages)

80

}

81

82

suspend fun populateDropdown() {

83

val options = getStringArray(Res.array.dropdown_items)

84

dropdownAdapter.updateItems(options)

85

}

86

}

87

```

88

89

### Environment-Specific Array Loading

90

91

```kotlin { .api }

92

suspend fun getStringArray(

93

environment: ResourceEnvironment,

94

resource: StringArrayResource

95

): List<String>

96

```

97

98

Loads string array resources using a specific resource environment. This is useful for loading arrays in different locales or for testing purposes.

99

100

**Parameters:**

101

- `environment` - The resource environment specifying locale, theme, and density

102

- `resource` - The string array resource to load

103

104

**Usage:**

105

```kotlin

106

suspend fun getLocalizedOptions(locale: Locale): List<String> {

107

val environment = ResourceEnvironment(

108

LanguageQualifier(locale.language),

109

RegionQualifier(locale.country),

110

ThemeQualifier.LIGHT,

111

DensityQualifier.MDPI

112

)

113

114

return getStringArray(environment, Res.array.localized_options)

115

}

116

117

suspend fun preloadArraysForMultipleLocales() {

118

val locales = listOf("en", "es", "fr", "de")

119

val arrays = mutableMapOf<String, List<String>>()

120

121

locales.forEach { lang ->

122

val environment = ResourceEnvironment(

123

LanguageQualifier(lang),

124

RegionQualifier(""),

125

ThemeQualifier.LIGHT,

126

DensityQualifier.MDPI

127

)

128

arrays[lang] = getStringArray(environment, Res.array.country_names)

129

}

130

131

return arrays

132

}

133

```

134

135

## String Array Definition

136

137

### XML Resource Format

138

139

```xml

140

<string-array name="days_of_week">

141

<item>Monday</item>

142

<item>Tuesday</item>

143

<item>Wednesday</item>

144

<item>Thursday</item>

145

<item>Friday</item>

146

<item>Saturday</item>

147

<item>Sunday</item>

148

</string-array>

149

150

<string-array name="notification_frequencies">

151

<item>Never</item>

152

<item>Daily</item>

153

<item>Weekly</item>

154

<item>Monthly</item>

155

</string-array>

156

157

<string-array name="file_sizes">

158

<item>Small (< 1 MB)</item>

159

<item>Medium (1-10 MB)</item>

160

<item>Large (10-100 MB)</item>

161

<item>Very Large (> 100 MB)</item>

162

</string-array>

163

```

164

165

### Localized String Arrays

166

167

```

168

res/

169

├── values/arrays.xml # Default (English)

170

├── values-es/arrays.xml # Spanish

171

├── values-fr/arrays.xml # French

172

├── values-de/arrays.xml # German

173

└── values-ja/arrays.xml # Japanese

174

```

175

176

**Example Localized Arrays:**

177

178

**values/arrays.xml (English):**

179

```xml

180

<string-array name="months">

181

<item>January</item>

182

<item>February</item>

183

<item>March</item>

184

<!-- ... -->

185

</string-array>

186

```

187

188

**values-es/arrays.xml (Spanish):**

189

```xml

190

<string-array name="months">

191

<item>Enero</item>

192

<item>Febrero</item>

193

<item>Marzo</item>

194

<!-- ... -->

195

</string-array>

196

```

197

198

## Common Use Cases

199

200

### Dropdown Menus and Spinners

201

202

```kotlin

203

@Composable

204

fun LanguageSelector() {

205

val languages = stringArrayResource(Res.array.available_languages)

206

var expanded by remember { mutableStateOf(false) }

207

var selectedIndex by remember { mutableStateOf(0) }

208

209

ExposedDropdownMenuBox(

210

expanded = expanded,

211

onExpandedChange = { expanded = it }

212

) {

213

TextField(

214

value = languages[selectedIndex],

215

onValueChange = {},

216

readOnly = true,

217

trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded) }

218

)

219

220

ExposedDropdownMenu(

221

expanded = expanded,

222

onDismissRequest = { expanded = false }

223

) {

224

languages.forEachIndexed { index, language ->

225

DropdownMenuItem(

226

text = { Text(language) },

227

onClick = {

228

selectedIndex = index

229

expanded = false

230

}

231

)

232

}

233

}

234

}

235

}

236

```

237

238

### List Navigation

239

240

```kotlin

241

@Composable

242

fun NavigationMenu() {

243

val menuItems = stringArrayResource(Res.array.main_menu_items)

244

val menuIcons = listOf(

245

Icons.Default.Home,

246

Icons.Default.Search,

247

Icons.Default.Profile,

248

Icons.Default.Settings

249

)

250

251

LazyColumn {

252

itemsIndexed(menuItems) { index, item ->

253

ListItem(

254

headlineContent = { Text(item) },

255

leadingContent = {

256

Icon(

257

imageVector = menuIcons[index],

258

contentDescription = null

259

)

260

},

261

modifier = Modifier.clickable {

262

onMenuItemClick(index)

263

}

264

)

265

}

266

}

267

}

268

```

269

270

### Form Options

271

272

```kotlin

273

@Composable

274

fun PreferencesForm() {

275

val themes = stringArrayResource(Res.array.theme_options)

276

val frequencies = stringArrayResource(Res.array.sync_frequencies)

277

278

Column {

279

Text("Theme", style = MaterialTheme.typography.h6)

280

themes.forEachIndexed { index, theme ->

281

Row(verticalAlignment = Alignment.CenterVertically) {

282

RadioButton(

283

selected = selectedTheme == index,

284

onClick = { selectedTheme = index }

285

)

286

Text(theme)

287

}

288

}

289

290

Spacer(modifier = Modifier.height(16.dp))

291

292

Text("Sync Frequency", style = MaterialTheme.typography.h6)

293

frequencies.forEachIndexed { index, frequency ->

294

Row(verticalAlignment = Alignment.CenterVertically) {

295

RadioButton(

296

selected = selectedFrequency == index,

297

onClick = { selectedFrequency = index }

298

)

299

Text(frequency)

300

}

301

}

302

}

303

}

304

```

305

306

## Performance Considerations

307

308

### Array Caching

309

310

String arrays are loaded and cached automatically:

311

312

```kotlin

313

@Composable

314

fun OptimizedArrayUsage() {

315

// Array is loaded once and cached

316

val options = stringArrayResource(Res.array.large_option_list)

317

318

// Reuse the cached array across recompositions

319

LazyColumn {

320

items(options) { option ->

321

Text(option)

322

}

323

}

324

}

325

```

326

327

### Memory Management

328

329

**Best Practices:**

330

1. **Avoid very large arrays** - Consider pagination for large datasets

331

2. **Cache frequently used arrays** at application level

332

3. **Use lazy evaluation** for arrays that might not be needed immediately

333

334

```kotlin

335

class ArrayCache {

336

private val cache = mutableMapOf<StringArrayResource, List<String>>()

337

338

suspend fun getCachedArray(resource: StringArrayResource): List<String> {

339

return cache.getOrPut(resource) {

340

getStringArray(resource)

341

}

342

}

343

}

344

```

345

346

## Error Handling

347

348

**Common Exceptions:**

349

- `IllegalStateException` - String array with given ID is not found

350

- `MissingResourceException` - Resource file cannot be read

351

352

**Example Error Handling:**

353

```kotlin

354

@Composable

355

fun SafeArrayLoading() {

356

val options = try {

357

stringArrayResource(Res.array.menu_options)

358

} catch (e: IllegalStateException) {

359

// Provide fallback options

360

listOf("Option 1", "Option 2", "Option 3")

361

}

362

363

options.forEach { option ->

364

Text(text = option)

365

}

366

}

367

```

368

369

## Best Practices

370

371

1. **Use descriptive resource names**:

372

```kotlin

373

Res.array.notification_types // Good

374

Res.array.array1 // Bad

375

```

376

377

2. **Keep arrays reasonably sized**:

378

```xml

379

<!-- Good: Small, manageable array -->

380

<string-array name="priority_levels">

381

<item>Low</item>

382

<item>Medium</item>

383

<item>High</item>

384

<item>Critical</item>

385

</string-array>

386

387

<!-- Consider alternatives for very large arrays -->

388

```

389

390

3. **Maintain consistent ordering**:

391

```xml

392

<!-- Consistent ordering across locales -->

393

<string-array name="difficulty_levels">

394

<item>Beginner</item> <!-- Always first -->

395

<item>Intermediate</item> <!-- Always second -->

396

<item>Advanced</item> <!-- Always third -->

397

</string-array>

398

```

399

400

4. **Group related arrays logically**:

401

```xml

402

<!-- Group by feature or screen -->

403

<string-array name="profile_sections">

404

<item>Personal Info</item>

405

<item>Privacy Settings</item>

406

<item>Notifications</item>

407

</string-array>

408

409

<string-array name="profile_privacy_options">

410

<item>Public</item>

411

<item>Friends Only</item>

412

<item>Private</item>

413

</string-array>

414

```

415

416

5. **Consider enum alternatives for app logic**:

417

```kotlin

418

// For app logic, consider using enums with localized display names

419

enum class Priority {

420

LOW, MEDIUM, HIGH, CRITICAL;

421

422

@Composable

423

fun displayName(): String = when (this) {

424

LOW -> stringResource(Res.string.priority_low)

425

MEDIUM -> stringResource(Res.string.priority_medium)

426

HIGH -> stringResource(Res.string.priority_high)

427

CRITICAL -> stringResource(Res.string.priority_critical)

428

}

429

}

430

```

431

432

6. **Validate array consistency across locales**:

433

- Ensure all localized arrays have the same number of items

434

- Maintain consistent ordering across translations

435

- Test with different locales to verify proper loading