I have to create dynamic ScrollableTabRow where i will intially have 3 tab but i can add multiple tab at the runtime also all the newly add tab will have close Icon to remove the tab. and also each new Screen will have seperate BottomNavigation(each screen will have 6 to 7 bottom Navitems scrollable). how can i make this efficiently
i am facing one issue it opening the same instance on adding the Tab.
@Composable
fun HomeScreenWithScrollableTabRow(
modifier: Modifier= Modifier,
tabsViewModel: TabLayoutVM = viewModel()){
val scope = rememberCoroutineScope()
Column(
modifier = modifier.fillMaxSize()) {
ScrollableTabRow(
edgePadding = 4.dp,
modifier = Modifier
.fillMaxWidth()
.background(MaterialTheme.colorScheme.onSurface),
selectedTabIndex = tabsViewModel.selectedTabIndex.intValue) {
tabsViewModel.tabs.forEachIndexed{index, title ->
Tab(
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.padding(horizontal = 10.dp),
selected = tabsViewModel.selectedTabIndex.intValue == index,
onClick = {
tabsViewModel.selectTab(index)
},
text = {
Row(
verticalAlignment = Alignment.CenterVertically
){
Text(
title,
fontWeight = FontWeight.Bold
)
if (index >= 3) {
Spacer(modifier = Modifier.width(1.dp))
IconButton(
onClick = {
tabsViewModel.removeTab(index)
}){
Icon(Icons.Default.Close, contentDescription = "Close Icon")
}
}
}
}
)
}
}
TabContent(
tabs = tabsViewModel.tabs,
selectedIndex = tabsViewModel.selectedTabIndex.intValue,
onAddTab = { newTabName ->
tabsViewModel.addTab(newTabName)
scope.launch {
delay(100)
tabsViewModel.selectTab(tabsViewModel.tabs.size.minus(1))
}
},
onPress = {
tabsViewModel.currentSelectedDeviceForGraph(it)
},
currentSelectedDevice = tabsViewModel.currentSelectedDevice.value,
tabsViewModel = tabsViewModel
)
}
}
@Composable
fun TabContent(
selectedIndex:Int,
tabs: List<String>,
onPress:(String)->Unit,
onAddTab: (String) -> Unit,
currentSelectedDevice:String?,
tabsViewModel: TabLayoutVM){
Box(
modifier = Modifier
.fillMaxSize()
.padding(8.dp),
contentAlignment = Alignment.TopStart){
when (selectedIndex) {
0 -> ScannerScreen(currentSelectedDevice,onPress,onAddTab)
1 -> BondedScreen()
2 -> AdvertiserScreen()
else -> {
TabScreen()
}
}
}
}
class TabLayoutVM: ViewModel() {
private val _tabs = mutableStateListOf("Scanner", "Bonded", "Advertiser")
val tabs: List<String> = _tabs
private var _selectedTabIndex = mutableIntStateOf(0)
val selectedTabIndex: MutableIntState = _selectedTabIndex
var currentSelectedDevice = mutableStateOf<String?>(null)
private set
fun addTab(deviceName:String) {
_tabs.add(deviceName)
}
fun removeTab(index: Int) {
if (_tabs.size > 3) {
_tabs.removeAt(index)
if (selectedTabIndex.intValue >= _tabs.size) {
selectedTabIndex.intValue = _tabs.size - 1
}
}
}
fun selectTab(index: Int) {
selectedTabIndex.intValue = index
}
fun currentSelectedDeviceForGraph(device: String?){
currentSelectedDevice.value = device
}
@Composable
fun TabScreen(deviceName:String, genericVM: GenericVM= viewModel()) {
val bottomNavIndex = genericVM.bottomNavIndex.value
val tabs = listOf("GPS", "GSM", "CAN", "ACC", "DEVICE")
Scaffold(
topBar = {
//Add Top App Bar inside Tab Layout if have
},
bottomBar = {
ScrollableTabRow(
selectedTabIndex = bottomNavIndex,
modifier = Modifier.fillMaxWidth(),
edgePadding = 4.dp
) {
tabs.forEachIndexed { index, title ->
Tab(
text = { Text(title) },
selected = bottomNavIndex == index,
onClick = { genericVM.setBottomNavIndex(index)},
icon = {
when (index) {
0 -> Icon(imageVector = Icons.Default.GpsFixed, contentDescription = null)
1 -> Icon(imageVector = Icons.Default.SettingsInputAntenna, contentDescription = null)
2 -> Icon(imageVector = Icons.Default.Settings, contentDescription = null)
3 -> Icon(imageVector = Icons.Default.Lock, contentDescription = null)
4 -> Icon(imageVector = Icons.Default.Devices, contentDescription = null)
}
}
)
}
}
}
) { paddingValues ->
Box(
modifier = Modifier
.padding(paddingValues)
.fillMaxSize(),
contentAlignment = Alignment.Center
) {
when (bottomNavIndex) {
0 -> Text("${tabs[0]} Content")
1 -> Text("${tabs[1]} Content")
2 -> Text("${tabs[2]} Content")
3 -> Text("${tabs[3]} Content")
4 -> Text("${tabs[4]} Content")
}
}
}
}