I've make a about us page in my flutter application where terms,policy & other sections are listed and on click of them I store that index in some variable & I want to open its description below section name.
I successfully done it by using valuenotifier but now I want to convert in into Bloc.
Below are my files,
AboutUsState.dart
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import '../../../Model/ModelInformation.dart';
@immutable
abstract class AboutUsState extends Equatable {}
class AboutUsLoadingState extends AboutUsState {
@override
List<Object?> get props => [];
}
class AboutUsLoadedState extends AboutUsState {
final ModelInformation modelInformation;
AboutUsLoadedState(this.modelInformation);
@override
List<Object?> get props => [modelInformation];
}
class AboutUsErrorState extends AboutUsState {
final String error;
AboutUsErrorState(this.error);
@override
List<Object?> get props => [error];
}
AboutUsEvent.dart
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
@immutable
abstract class AboutUsEvent extends Equatable {
const AboutUsEvent();
}
class LoadAboutUsEvent extends AboutUsEvent {
@override
List<Object?> get props => [];
}
class UpdateSelectedViewEvent extends AboutUsEvent {
@override
List<Object?> get props => [];
}
AboutUsBloc.dart
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../../Model/ModelInformation.dart';
import 'AboutUsEvent.dart';
import 'AboutUsState.dart';
import 'Repository.dart';
class AboutUsBloc extends Bloc<AboutUsEvent,AboutUsState> {
final Repository repository;
int selectedView = -1;
AboutUsBloc(this.repository,this.selectedView) : super(AboutUsLoadingState()) {
on<LoadAboutUsEvent>((event, emit) async {
emit(AboutUsLoadingState());
try {
var dict = await repository.getAboutUs();
final ModelInformation modelInformation = ModelInformation.fromJson(dict["mainResponse"]);
emit(AboutUsLoadedState(modelInformation));
} catch (e) {
emit(AboutUsErrorState(e.toString()));
}
}
);
}
}
Repository.dart
import '../../../Services/ServiceManager.dart';
import '../../../Util/Constant.dart';
class Repository {
Future getAboutUs() async {
return await ServiceManager.callWebservice(
varMethodType: enumMethodType.POST,
strSuffixPath: ConstantApi.keyGetAboutUs,
dictParameters: {},
dictHeaders: {},
arrayUploadFile: []
);
}
}
AboutUs.dart
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../Model/ModelInformation.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import '../../Util/Constant.dart';
import 'AboutUs/AboutUsBloc.dart';
import 'AboutUs/AboutUsEvent.dart';
import 'AboutUs/AboutUsState.dart';
import 'AboutUs/Repository.dart';
class ClassAboutUs extends StatefulWidget {
@override
stateClassAboutUs createState() => stateClassAboutUs();
}
class stateClassAboutUs extends State<ClassAboutUs> {
final AboutUsBloc aboutUsBloc = AboutUsBloc(Repository(),-1);
@override
void initState() {
super.initState();
aboutUsBloc.add(LoadAboutUsEvent());
}
@override
Widget build(BuildContext context) {
return
WillPopScope(
onWillPop: () async{
Navigator.pop(context);
return true;
},
child: new Scaffold(
backgroundColor: Theme.of(context).colorScheme.background,
appBar: AppBar(
elevation: 0.5,
backgroundColor: Theme.of(context).colorScheme.background,
titleSpacing: 0,
centerTitle: false,
leading: BackButton(
color: Theme.of(context).colorScheme.onBackground.withOpacity(0.87),
onPressed: (){
Navigator.pop(context);
},
),
title: Text("About us",
style: TextStyle(
color: Theme.of(context).colorScheme.onBackground.withOpacity(0.87),
fontFamily: ConstantFont.keyPrimaryFont,
fontSize: 15,
fontWeight: FontWeight.w400,
),
),
),
body:
BlocProvider(
create: (_) => aboutUsBloc,
child: BlocBuilder<AboutUsBloc, AboutUsState>(
builder: (context, state) {
if (state is AboutUsLoadingState) {
return const Center(
child: CircularProgressIndicator(),
);
}
if (state is AboutUsErrorState) {
return const Center(child: Text("Error"));
}
if (state is AboutUsLoadedState) {
ModelInformation modelInformation = state.modelInformation;
return ListView.builder(
padding: EdgeInsets.fromLTRB(0, 0, 0, 10),
itemCount: modelInformation.mainmenu!.informationPages!.length,
itemBuilder: (context, index) {
return
aboutUsBloc.selectedView == index ?
Container(
color: Theme.of(context).colorScheme.primary.withOpacity(0.10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
InkWell(
onTap: (){
aboutUsBloc.selectedView = aboutUsBloc.selectedView== index ? -1 : index;
},
child:
Padding(
padding: const EdgeInsets.all(10),
child: Row(
children: [
Expanded(
child: Text("${modelInformation.mainmenu!.informationPages![index].headingTitle}",style: ConstantTextStyle.h2.copyWith(fontWeight: FontWeight.w600,color: Theme.of(context).colorScheme.primary)),
),
Padding(
padding: EdgeInsets.only(left: 5,top: 5,bottom: 5),
child: Icon(Icons.keyboard_arrow_up_rounded,size: 15,color: Theme.of(context).colorScheme.onBackground.withOpacity(0.60),),
),
],
)
),),
Padding(
padding: const EdgeInsets.only(left: 10,right: 10,),
child: Text("${modelInformation.mainmenu!.informationPages![index].description}",style: ConstantTextStyle.h3.copyWith(color: Theme.of(context).colorScheme.onBackground.withOpacity(0.87)),
textAlign: TextAlign.justify,
),
),
],
)
) :
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
InkWell(
onTap: (){
aboutUsBloc.selectedView = aboutUsBloc.selectedView == index ? -1 : index;
aboutUsBloc.add(UpdateSelectedViewEvent());
},
child:
Padding(
padding: const EdgeInsets.all(10),
child: Row(
children: [
Expanded(
child: Text("${modelInformation.mainmenu!.informationPages![index].headingTitle}",style: ConstantTextStyle.h2.copyWith(fontWeight: FontWeight.w600,color: Theme.of(context).colorScheme.primary)),
),
Padding(
padding: EdgeInsets.only(left: 5,top: 5,bottom: 5),
child: Icon(Icons.keyboard_arrow_down_rounded,size: 15,color: Theme.of(context).colorScheme.onBackground.withOpacity(0.60),),
),
],
)
),),
Divider(height: 1,color: Theme.of(context).colorScheme.onBackground.withOpacity(0.37),),
],
);
},
);
}
return Container();
},
),
)
),
);
}
}
I want to update listview single block based on selectedView value changes
Create one more event for updating selection:
class UpdateSelectedEvent extends AboutUsEvent {
final int selectedView;
UpdateSelectedEvent(this.selectedView);
@override
List<Object?> get props => [selectedView];
}
add this event to your bloc:
on<UpdateSelectedEvent>((event, emit) {
selectedView = event.selectedView;
if(state is AboutUsLoadedState){
emit(AboutUsLoadedState(state.modelInformation));
}
});
and add the update event on onTap:
onTap: () => aboutUsBloc.add(UpdateSelectedEvent(index)),