Reputation: 17
I have containers with various specialties. They are taken from the API. I have a problem with updating the state of the buttons. I will give an example in the video of how it should work and how it works
This is how it should have worked enter image description here
Now it works like this enter image description here
That is, I click on different categories, specialists who are attached to these categories are also displayed, but the state of the buttons is not updated. Please help
Here is the code:
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/svg.dart';
import 'package:google_fonts/google_fonts.dart';
import '../../../../../constrats/app_colors.dart';
import '../../../../authorization/screens/sign_in/api/sign_in/repository/client_dio.dart';
import '../../../../authorization/screens/sign_in/api/sign_in/repository/token_storage.dart';
import '../api/categories/bloc/bloc/category_bloc.dart';
import '../api/categories/model/category_model.dart';
import '../api/categories/repository/category_repository.dart';
import '../api/home/specialist/bloc/bloc/specialist_bloc.dart';
import '../api/home/specialist/repository/specialist_repository.dart';
class FilterContainersWidget extends StatefulWidget {
const FilterContainersWidget({
super.key,
// required this.selectedIndex,
});
// final int selectedIndex;
@override
State<FilterContainersWidget> createState() => _FilterContainersWidgetState();
}
class _FilterContainersWidgetState extends State<FilterContainersWidget> {
int selectedIndex = 0;
// @override
// void initState() {
// super.initState();
// selectedIndex = widget.selectedIndex; // Встановлення початкового індексу
// }
@override
Widget build(BuildContext context) {
return MultiBlocProvider(
providers: [
BlocProvider(
create: (context) => CategoryBloc(
CategoryRepository(
Dio(),
DioClient(
// Dio(),
TokenStorage()),
),
)..add(LoadCategoryEvent()),
),
BlocProvider(
create: (context) => SpecialistBloc(
SpecialistRepository(
Dio(),
DioClient(
// Dio(),
TokenStorage()),
),
),
),
],
child: BlocBuilder<CategoryBloc, CategoryState>(
builder: (context, categoryState) {
if (categoryState is CategoryLoading) {
return const Center(
child: CircularProgressIndicator(),
);
}
if (categoryState is CategorySuccess) {
final categories = categoryState.categoryModel;
return BlocBuilder<SpecialistBloc, SpecialistState>(
builder: (context, specialistState) {
if (specialistState is SpecialistCategorySelected) {
selectedIndex = specialistState.selectedIndex;
}
return Row(
children: List.generate(
categories.length,
(index) {
final category = categories[index];
return Padding(
padding: const EdgeInsets.only(left: 8),
child: _buildFilterContainer(
category: category.title,
index: index,
isSelected: selectedIndex == index,
icon: _buildIcon(category),
label: category.title,
),
);
},
),
);
},
);
}
if (categoryState is CategoryError) {
return Center(
child: Text(
categoryState.error,
style: const TextStyle(color: Colors.red),
),
);
}
return const SizedBox(
child: Text('no data'),
);
},
),
);
}
Widget _buildFilterContainer({
required int index,
required bool isSelected,
required Widget icon,
required String label,
required String category,
}) {
return GestureDetector(
// onTap: () {
// if (selectedIndex != index) {
// context.read<SpecialistBloc>().add(UpdateSelectedIndexEvent(index));
// context.read<SpecialistBloc>().add(LoadSpecialistEvent(category));
// }
// },
onTap: () {
setState(() {
selectedIndex = index;
});
context
.read<SpecialistBloc>()
.add(UpdateSelectedIndexEvent(selectedIndex));
context.read<SpecialistBloc>().add(LoadSpecialistEvent(category));
},
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16),
gradient: LinearGradient(
colors: isSelected
? [firstColorGrad, secondColorGrad] // Для вибраної кнопки
: [lightRose, lightRose], // Для не вибраної кнопки
),
),
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ShaderMask(
shaderCallback: (bounds) => LinearGradient(
colors: isSelected
? [Colors.white, Colors.white]
: [firstColorGrad, secondColorGrad],
begin: Alignment.centerLeft,
end: Alignment.centerRight,
).createShader(
Rect.fromLTWH(0, 0, bounds.width, bounds.height)),
child: icon,
),
const SizedBox(height: 6),
SizedBox(
width: _getLabelWidthByIndex(index).toDouble(),
child: Text(
textAlign: TextAlign.center,
label,
style: GoogleFonts.geologica(
fontSize: 12,
fontWeight: FontWeight.w400,
color: isSelected ? Colors.white : Colors.black,
),
),
),
],
),
),
),
);
}
Widget _buildIcon(CategoryModel category) {
final imageUrl = 'http://141.148.245.77:5001/${category.image}';
if (category.image.isEmpty) {
return SvgPicture.asset('assets/specialists/overview.svg');
}
return SvgPicture.network(
imageUrl,
color: Colors.white,
placeholderBuilder: (context) => const CircularProgressIndicator(),
);
}
int _getLabelWidthByIndex(int index) {
const widths = [28, 99, 74, 88, 74, 80, 81, 76, 71, 81];
return widths[index];
}
}
Upvotes: 1
Views: 51