最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

android - Jetpack Compose NavigationBarItem Icon - Stack Overflow

programmeradmin1浏览0评论

I'm using NavigationBar in Jetpack Compose and defining icons for each item, where the selected item should display a filled icon, and the unselected ones should show the default icon. However, the selected icon is always applied, even when an item is unselected.

Here’s my implementation:

@Composable
fun MyNavBar() {
    var selectedItemIndex by rememberSaveable { mutableIntStateOf(0) }
    val itemsBarList = listOf(
        BottomNavigationItem(
            selectedIcon = Icons.Filled.Group,
            unselectedIcon = Icons.Default.Group,
        ),
        BottomNavigationItem(
            selectedIcon = Icons.Filled.Person,
            unselectedIcon = Icons.Default.Person,
        ),
        BottomNavigationItem(
            selectedIcon = Icons.Filled.Settings,
            unselectedIcon = Icons.Default.Settings,
        ),
    )

    NavigationBar {
        itemsBarList.forEachIndexed { index, item ->
            Log.i("HomePager", "index: $index , selectedItemIndex: $selectedItemIndex")
            NavigationBarItem(
                selected = index == selectedItemIndex,
                onClick = {
                    selectedItemIndex = index
                },
                icon = {
                    Icon(
                        imageVector = if (index == selectedItemIndex) item.selectedIcon else item.unselectedIcon,
                        contentDescription = "",
                    )
                },
                alwaysShowLabel = true,
            )
        }
    }
}

The BottomNavigationItem data class is defined as:

data class BottomNavigationItem(
    val selectedIcon: ImageVector,
    val unselectedIcon: ImageVector,
)

Whenever I select a new item, selectedItemIndex updates correctly, but the index variable always seems to end up as 2. As a result, the selected icon is applied to all items instead of just the selected one.

Logs:

//here, i selected friends (index 0 on the list)
I  index: 0 , selectedItemIndex: 0
I  index: 1 , selectedItemIndex: 0
I  index: 2 , selectedItemIndex: 0
//changed to profile (index 1 on the list)
I  index: 0 , selectedItemIndex: 1
I  index: 1 , selectedItemIndex: 1
I  index: 2 , selectedItemIndex: 1

even though selectedItemIndex is correct, index always seems to end up as 2, affecting all items and their respective icons, and I don't have any clue about why this is happening. any help here is appreciated. thanks!

Edit: This NavigationBar is used alongside a Pager, allowing users to navigate either by tapping the bottom navigation items or by swiping left and right. However, since the issue seems to be related to how items are indexed, and it occurs regardless of whether I select an item via the NavigationBar or swipe in the Pager, I didn't initially include the Pager in the code snippet. As the forum guidelines suggest providing a minimal reproducible example, I focused only on the navigation bar, since it alone is apparently enough to reproduce the issue.

I'm using NavigationBar in Jetpack Compose and defining icons for each item, where the selected item should display a filled icon, and the unselected ones should show the default icon. However, the selected icon is always applied, even when an item is unselected.

Here’s my implementation:

@Composable
fun MyNavBar() {
    var selectedItemIndex by rememberSaveable { mutableIntStateOf(0) }
    val itemsBarList = listOf(
        BottomNavigationItem(
            selectedIcon = Icons.Filled.Group,
            unselectedIcon = Icons.Default.Group,
        ),
        BottomNavigationItem(
            selectedIcon = Icons.Filled.Person,
            unselectedIcon = Icons.Default.Person,
        ),
        BottomNavigationItem(
            selectedIcon = Icons.Filled.Settings,
            unselectedIcon = Icons.Default.Settings,
        ),
    )

    NavigationBar {
        itemsBarList.forEachIndexed { index, item ->
            Log.i("HomePager", "index: $index , selectedItemIndex: $selectedItemIndex")
            NavigationBarItem(
                selected = index == selectedItemIndex,
                onClick = {
                    selectedItemIndex = index
                },
                icon = {
                    Icon(
                        imageVector = if (index == selectedItemIndex) item.selectedIcon else item.unselectedIcon,
                        contentDescription = "",
                    )
                },
                alwaysShowLabel = true,
            )
        }
    }
}

The BottomNavigationItem data class is defined as:

data class BottomNavigationItem(
    val selectedIcon: ImageVector,
    val unselectedIcon: ImageVector,
)

Whenever I select a new item, selectedItemIndex updates correctly, but the index variable always seems to end up as 2. As a result, the selected icon is applied to all items instead of just the selected one.

Logs:

//here, i selected friends (index 0 on the list)
I  index: 0 , selectedItemIndex: 0
I  index: 1 , selectedItemIndex: 0
I  index: 2 , selectedItemIndex: 0
//changed to profile (index 1 on the list)
I  index: 0 , selectedItemIndex: 1
I  index: 1 , selectedItemIndex: 1
I  index: 2 , selectedItemIndex: 1

even though selectedItemIndex is correct, index always seems to end up as 2, affecting all items and their respective icons, and I don't have any clue about why this is happening. any help here is appreciated. thanks!

Edit: This NavigationBar is used alongside a Pager, allowing users to navigate either by tapping the bottom navigation items or by swiping left and right. However, since the issue seems to be related to how items are indexed, and it occurs regardless of whether I select an item via the NavigationBar or swipe in the Pager, I didn't initially include the Pager in the code snippet. As the forum guidelines suggest providing a minimal reproducible example, I focused only on the navigation bar, since it alone is apparently enough to reproduce the issue.

Share Improve this question edited Feb 10 at 18:41 tyg 16.1k4 gold badges36 silver badges48 bronze badges asked Feb 10 at 18:17 MuriloMurilo 371 silver badge4 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 2

Although I don't know what you mean by "the index variable always seems to end up as 2" (as the logs clearly indicate that that's not the case), the reason why you see the same icons regardless of the selection state is because you actually use the same icons.

For example, the icons

BottomNavigationItem(
    selectedIcon = Icons.Filled.Group,
    unselectedIcon = Icons.Default.Group,
)

are the same because Icons.Default is internally defined as:

val Default = Filled

So in both cases the same icon Icons.Filled.Group will be taken.

Make sure you actually use different icons, like - for example - the Outlined variants:

BottomNavigationItem(
    selectedIcon = Icons.Filled.Group,
    unselectedIcon = Icons.Outlined.Group,
)
发布评论

评论列表(0)

  1. 暂无评论
ok 不同模板 switch ($forum['model']) { /*case '0': include _include(APP_PATH . 'view/htm/read.htm'); break;*/ default: include _include(theme_load('read', $fid)); break; } } break; case '10': // 主题外链 / thread external link http_location(htmlspecialchars_decode(trim($thread['description']))); break; case '11': // 单页 / single page $attachlist = array(); $imagelist = array(); $thread['filelist'] = array(); $threadlist = NULL; $thread['files'] > 0 and list($attachlist, $imagelist, $thread['filelist']) = well_attach_find_by_tid($tid); $data = data_read_cache($tid); empty($data) and message(-1, lang('data_malformation')); $tidlist = $forum['threads'] ? page_find_by_fid($fid, $page, $pagesize) : NULL; if ($tidlist) { $tidarr = arrlist_values($tidlist, 'tid'); $threadlist = well_thread_find($tidarr, $pagesize); // 按之前tidlist排序 $threadlist = array2_sort_key($threadlist, $tidlist, 'tid'); } $allowpost = forum_access_user($fid, $gid, 'allowpost'); $allowupdate = forum_access_mod($fid, $gid, 'allowupdate'); $allowdelete = forum_access_mod($fid, $gid, 'allowdelete'); $access = array('allowpost' => $allowpost, 'allowupdate' => $allowupdate, 'allowdelete' => $allowdelete); $header['title'] = $thread['subject']; $header['mobile_link'] = $thread['url']; $header['keywords'] = $thread['keyword'] ? $thread['keyword'] : $thread['subject']; $header['description'] = $thread['description'] ? $thread['description'] : $thread['brief']; $_SESSION['fid'] = $fid; if ($ajax) { empty($conf['api_on']) and message(0, lang('closed')); $apilist['header'] = $header; $apilist['extra'] = $extra; $apilist['access'] = $access; $apilist['thread'] = well_thread_safe_info($thread); $apilist['thread_data'] = $data; $apilist['forum'] = $forum; $apilist['imagelist'] = $imagelist; $apilist['filelist'] = $thread['filelist']; $apilist['threadlist'] = $threadlist; message(0, $apilist); } else { include _include(theme_load('single_page', $fid)); } break; default: message(-1, lang('data_malformation')); break; } ?>