Skip to content

Commit f629f1c

Browse files
Add documentation on custom icons for Android (#1090)
1 parent 227a042 commit f629f1c

File tree

2 files changed

+83
-0
lines changed

2 files changed

+83
-0
lines changed

README.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,40 @@ Example usage:
325325
</View>
326326
</MenuView>
327327
```
328+
329+
### Custom icons (Android)
330+
331+
You might want to use custom icons in the MenuAction `image` attribute. To do so, follow these steps.
332+
333+
1. Search for your icon on e.g. [Material Icons](https://fonts.google.com/icons), customize the fill, weight, grade etc.
334+
to your liking and then press the `Android` tab and click `Download`. This wil download an xml file, e.g.
335+
`search_24px.xml`. You can create your own icon or get it somewhere else, as long as it is in a format that Android
336+
understands.
337+
2. If using bare react-native, copy the downloaded xml file to your `android/app/src/main/res/drawable` folder.
338+
If you are using Expo, add a dependency
339+
on [@expo/config-plugins,](https://www.npmjs.com/package/@expo/config-plugins) and then you can use
340+
an [expo config plugin](./plugin/withAndroidDrawables.js) to copy the file from your `assets` folder to the drawable
341+
folder. Copy the config plugin to your app and reference it in your `app.json` or `app.config.js` in the `plugins`
342+
section like this:
343+
344+
```json
345+
{
346+
"expo": {
347+
"plugins": [
348+
[
349+
"./plugin/withAndroidDrawables",
350+
{
351+
"drawableFiles": [ "./assets/my_icon.xml" ]
352+
}
353+
]
354+
]
355+
}
356+
}
357+
```
358+
3. In your `MenuAction` you can now reference the icon using its file name, without the `.xml` extension. For example,
359+
`image: 'my_icon'` will use the `my_icon.xml` file you copied to the drawable folder.
360+
4. Remember to run a new build to see changes to these icons.
361+
328362
## Testing with Jest
329363
330364
In some cases, you might want to mock the package to test your components. You can do this by using the `jest.mock` function.

plugin/withAndroidDrawables.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
const { withDangerousMod } = require('@expo/config-plugins');
2+
const fs = require('fs');
3+
const path = require('path');
4+
5+
/**
6+
* This config plugin copies files from the specified paths, like the assets
7+
* directory, to the Android drawable directory.
8+
*/
9+
function withAndroidDrawables(config, { drawableFiles }) {
10+
return withDangerousMod(config, [
11+
'android',
12+
(config) => {
13+
// Validate drawableFiles
14+
if (!Array.isArray(drawableFiles)) {
15+
throw new Error('drawableFiles must be an array of file paths');
16+
}
17+
18+
// Define the target drawable directory
19+
const drawableDir = path.join(
20+
config.modRequest.projectRoot,
21+
'android/app/src/main/res/drawable',
22+
);
23+
24+
// Create the drawable directory if it doesn't exist
25+
if (!fs.existsSync(drawableDir)) {
26+
fs.mkdirSync(drawableDir, { recursive: true });
27+
}
28+
29+
// Copy each drawable file to the drawable directory
30+
drawableFiles.forEach((filePath) => {
31+
const sourcePath = path.resolve(config.modRequest.projectRoot, filePath);
32+
const fileName = path.basename(filePath);
33+
const destPath = path.join(drawableDir, fileName);
34+
35+
if (!fs.existsSync(sourcePath)) {
36+
console.warn(`Warning: Drawable file not found: ${sourcePath}`);
37+
return;
38+
}
39+
40+
// Copy the file
41+
fs.copyFileSync(sourcePath, destPath);
42+
});
43+
44+
return config;
45+
},
46+
]);
47+
}
48+
49+
module.exports = withAndroidDrawables;

0 commit comments

Comments
 (0)