Android/Fuse: conditional styling issue after tap selection
Nobody has claimed this yet.
- Dominant language
- Swift
- Stars
- 330
- Forks
- 76
- Avg merge
- 3h 6m
- Merged PRs (30d)
- 1
Description
Summary
On Android in native/Fuse mode, grid cells can show stale conditional styling after selection changes.
I am building a calendar which consists of a LazyVGrid of tappable day cells with a shared @State selectedDate. Each cell receives an isSelected boolean. Logs confirm that after each tap, exactly one cell renders with isSelected == true, but visually the newly selected cell and previously tapped cells intermittently blink together. This does not happen on iOS.
Environment
- Android device: Samsung SM-G973F, Android 12
- Build: release, minified
- Mode: native / Skip Fuse
- Reproduces with:
- skip-fuse-ui 1.18.1
- skip-ui 1.59.1
- Last known working in our released app:
- skip-fuse-ui 1.13.0
- skip-ui 1.53.1
Minimal POC
import SwiftUI
struct CalendarBugRepro: View {
@State var selectedDate = Date()
private let calendar = Calendar(identifier: .gregorian)
var body: some View {
LazyVGrid(
columns: Array(repeating: GridItem(.flexible(), spacing: 0), count: 7),
spacing: 4
) {
ForEach(days, id: \.self) { date in
Button {
selectedDate = date
} label: {
ReproDayCell(
day: calendar.component(.day, from: date),
isSelected: calendar.isDate(date, inSameDayAs: selectedDate)
)
}
.buttonStyle(.plain)
}
}
.padding()
}
private var days: [Date] {
let first = calendar.date(from: DateComponents(year: 2026, month: 9, day: 1))!
return (0..<30).compactMap { calendar.date(byAdding: .day, value: $0, to: first) }
}
}
struct ReproDayCell: View {
let day: Int
let isSelected: Bool
var body: some View {
Text("\(day)")
.font(.system(size: 14, weight: isSelected ? .bold : .regular))
.foregroundStyle(isSelected ? .white : .primary)
.frame(width: 32, height: 32)
.background(Circle().fill(isSelected ? Color.accentColor : .clear))
.frame(height: 44)
}
}
Expected
Only the selected day is highlighted.
Actual
Previously selected days blink together, even though only one cell has isSelected == true.
Workaround
Keeping the view tree stable and toggling opacity avoids the issue:
.background {
Circle()
.fill(Color.accentColor)
.opacity(isSelected ? 1 : 0)
}
So the issue seems related to conditional styling like:
.background(Circle().fill(isSelected ? Color.accentColor : .clear))
.foregroundStyle(isSelected ? .white : .primary)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by running the Minimal POC using LazyVGrid, tappable day cells, and conditional styling on Android in native/Fuse mode. Compare the blinking behavior with the opacity workaround and the listed skip-fuse-ui and skip-ui versions. Done means that after selection changes, only the selected day remains highlighted without stale cells blinking.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- swift
- Domain
- frontend, mobile-dev
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100