Мне нужно создать динамический ScrollableTabRow, где изначально у меня будет 3 вкладки, но я могу добавить несколько вкладок во время выполнения, также все новые добавленные вкладки будут иметь значок закрытия для удаления вкладки. а также каждый новый экран будет иметь отдельную нижнюю навигацию (каждый экран будет иметь от 6 до 7 прокручиваемых нижних элементов навигации). как я могу сделать это эффективно
Я столкнулся с одной проблемой: при добавлении вкладки открывается один и тот же экземпляр.
@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,
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 = _tabs
private var _selectedTabIndex = mutableIntStateOf(0)
val selectedTabIndex: MutableIntState = _selectedTabIndex
var currentSelectedDevice = mutableStateOf(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")
}
}
}
}
Подробнее здесь: https://stackoverflow.com/questions/790 ... ck-compose
Как сделать Dynamic ScrollableTabRow в Jetpack составленным ⇐ Android
Форум для тех, кто программирует под Android
-
Anonymous
1727358152
Anonymous
Мне нужно создать динамический ScrollableTabRow, где изначально у меня будет 3 вкладки, но я могу добавить несколько вкладок во время выполнения, также все новые добавленные вкладки будут иметь значок закрытия для удаления вкладки. а также каждый новый экран будет иметь отдельную нижнюю навигацию (каждый экран будет иметь от 6 до 7 прокручиваемых нижних элементов навигации). как я могу сделать это эффективно
Я столкнулся с одной проблемой: при добавлении вкладки открывается один и тот же экземпляр.
@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,
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 = _tabs
private var _selectedTabIndex = mutableIntStateOf(0)
val selectedTabIndex: MutableIntState = _selectedTabIndex
var currentSelectedDevice = mutableStateOf(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")
}
}
}
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79027625/how-to-make-dynamic-scrollabletabrow-in-jetpack-compose[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия