Arribats a aquest punt, l'aplicació, vista amb l'emulador, té aquest aspecte:

Un cop acabat el programa, anem a posar el contingut complet dels diferents fitxers de programa. Comencem pel programa principal:
main.dart
import 'package:flutter/material.dart'; import 'package:selector_color/screens/pant_principal.dart';
void main() {
runApp(const MainApp());
}
class MainApp extends StatelessWidget {
const MainApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: PantPral()
);
}
}
pant_principal.dart
import 'package:flutter/material.dart'; import 'package:selector_color/components/boto_seguir.dart'; import 'package:selector_color/components/cursor.dart'; import 'package:selector_color/components/mostra_color.dart'; import 'package:selector_color/core/colors.dart';
class PantPral extends StatefulWidget {
const PantPral({super.key});
@override
State<PantPral> createState() => _PantPralState();
}
class _PantPralState extends State<PantPral> {
List<double> valors = [127, 127, 127];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Tria un color"),
backgroundColor: ColorsApp.primari,
foregroundColor: ColorsApp.text,
),
backgroundColor: ColorsApp.fons,
body: Column(
children: [
Cursor(
titol: "Vermell:",
valor: valors[0],
colCurs: ColorsApp.colCursors[0],
siCanvia: (nouValor) {
setState(() {
valors[0] = nouValor;
});
},
),
Cursor(
titol: "Verd:",
valor: valors[1],
colCurs: ColorsApp.colCursors[1],
siCanvia: (nouValor) {
setState(() {
valors[1] = nouValor;
});
},
),
Cursor(
titol: "Blau:",
valor: valors[2],
colCurs: ColorsApp.colCursors[2],
siCanvia: (nouValor) {
setState(() {
valors[2] = nouValor;
});
},
),
MostraColor(compColor: valors),
BotoSeguir(vals: valors, textBoto: "Continuar...", retorn: false),
],
),
);
}
}
pant_resultat.dart
import 'package:flutter/material.dart'; import 'package:selector_color/components/boto_seguir.dart'; import 'package:selector_color/components/mostra_valors.dart'; import 'package:selector_color/components/mostra_contrast.dart'; import 'package:selector_color/core/colors.dart'; import 'package:selector_color/core/funcions.dart';
class PantResultat extends StatefulWidget {
final List<double> compon;
const PantResultat({super.key, required this.compon});
@override
State<PantResultat> createState() => _PantResultatState();
}
class _PantResultatState extends State<PantResultat> {
@override
Widget build(BuildContext context) {
List<int> colorIntRGB = intRGBfromDouble(widget.compon);
Color colorTriat = colFromList(colorIntRGB);
Color colorComp = colFromList(intRGBCompl(colorIntRGB));
return Scaffold(
appBar: AppBar(
title: Text("Color triat"),
backgroundColor: ColorsApp.primari,
foregroundColor: ColorsApp.text,
),
backgroundColor: ColorsApp.fons,
body: Column(
children: [
MostraValors(
txtRGB: txtListFromInt(colorIntRGB),
hexRGB: hexFromInt(colorIntRGB),
txtRGBcomp: txtListFromInt(intRGBCompl(colorIntRGB)),
hexRGBcomp: hexFromInt(intRGBCompl(colorIntRGB)),
),
MostraContrast(colTriat: colorTriat, colCompl: colorComp),
BotoSeguir(vals: [0, 0, 0], textBoto: "Tornar", retorn: true),
],
),
);
}
}
cursor.dart
import 'package:flutter/material.dart'; import 'package:selector_color/core/colors.dart'; import 'package:selector_color/core/estils.dart';
class Cursor extends StatefulWidget {
final String titol;
final double valor;
final Color colCurs;
final Function(double) siCanvia;
const Cursor({
super.key,
required this.titol,
required this.valor,
required this.colCurs,
required this.siCanvia,
});
@override
State<Cursor> createState() => _CursorState();
}
class _CursorState extends State<Cursor> {
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
children: [
Row(
children: [
Text(widget.titol, style: Estils.estilTextCursors),
Spacer(),
Text(
widget.valor.toStringAsFixed(0),
style: Estils.estilTextCursors,
),
],
),
Slider(
value: widget.valor, min: 0, max: 255, divisions: 255,
activeColor: widget.colCurs,
inactiveColor: ColorsApp.primari,
padding: const EdgeInsets.only(left: 4, right: 4, top: 12, bottom: 12),
onChanged: (valorNou) {
setState(() {
widget.siCanvia(valorNou);
});
},
),
],
),
);
}
}
mostra_color.dart
import 'package:flutter/material.dart';
class MostraColor extends StatefulWidget {
final List<double> compColor;
const MostraColor({super.key, required this.compColor});
@override
State<MostraColor> createState() => _MostraColorState();
}
class _MostraColorState extends State<MostraColor> {
@override
Widget build(BuildContext context) {
return Expanded(
child: Padding(
padding: const EdgeInsets.only(bottom: 20, left: 20, right: 20),
child: Container(
width: double.infinity,
decoration: BoxDecoration(
color: Color.fromARGB(
255,
widget.compColor[0].toInt(),
widget.compColor[1].toInt(),
widget.compColor[2].toInt(),
),
borderRadius: BorderRadius.circular(12),
),
),
),
);
}
}
boto_seguir.dart
import 'package:flutter/material.dart'; import 'package:selector_color/core/colors.dart'; import 'package:selector_color/core/estils.dart'; import 'package:selector_color/screens/pant_resultat.dart';
class BotoSeguir extends StatefulWidget {
final List<double> vals;
final String textBoto;
final bool retorn;
const BotoSeguir({super.key, required this.vals, required this.textBoto, required this.retorn});
@override
State<BotoSeguir> createState() => _BotoSeguirState();
}
class _BotoSeguirState extends State<BotoSeguir> {
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(left: 20, right: 20, bottom: 40),
child: SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: () {
if(widget.retorn){
Navigator.pop(context);
} else {
Navigator.push(context,
MaterialPageRoute(builder: (context) => PantResultat(compon: widget.vals)));
}
},
style: ButtonStyle(
shape: WidgetStateProperty.all(
RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
),
backgroundColor: WidgetStateProperty.all(ColorsApp.primari),
),
child: Text(widget.textBoto, style: Estils.estilTextBotons),
),
),
);
}
}
mostra_valors.dart
import 'package:flutter/material.dart'; import 'package:selector_color/core/colors.dart'; import 'package:selector_color/core/estils.dart';
class MostraValors extends StatefulWidget {
final String txtRGB;
final String hexRGB;
final String txtRGBcomp;
final String hexRGBcomp;
const MostraValors({super.key, required this.txtRGB, required this.hexRGB,
required this.txtRGBcomp, required this.hexRGBcomp});
@override
State<MostraValors> createState() => _MostraValorsState();
}
class _MostraValorsState extends State<MostraValors> {
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(top: 20, left: 20, right: 20),
child: Container(
width: double.infinity,
alignment: Alignment.center,
decoration: BoxDecoration(
color: ColorsApp.primari,
borderRadius: BorderRadius.circular(12)
),
child: Padding(
padding: const EdgeInsets.all(12),
child: Column(
children: [
Text("El color és ${widget.txtRGB}", style: Estils.estilTextNormal),
Text("En hexadecimal és ${widget.hexRGB}", style: Estils.estilTextNormal),
SizedBox(height: 12,),
Text("El complementari és ${widget.txtRGBcomp}", style: Estils.estilTextNormal),
Text("En hexadecimal és ${widget.hexRGBcomp}", style: Estils.estilTextNormal),
SizedBox(height: 12,),
Text("Mira la combinació en el requadre següent", style: Estils.estilTextNormal),
],
),
),
),
);
}
}
mostra_contrast.dart
import 'package:flutter/material.dart';
class MostraContrast extends StatefulWidget {
final Color colTriat;
final Color colCompl;
const MostraContrast({super.key, required this.colTriat, required this.colCompl});
@override
State<MostraContrast> createState() => _MostraContrastState();
}
class _MostraContrastState extends State<MostraContrast> {
@override
Widget build(BuildContext context) {
return Expanded(
child: Padding(
padding: const EdgeInsets.all(20),
child: Container(width: double.infinity,
alignment: Alignment.center,
decoration: BoxDecoration(color: widget.colTriat,
borderRadius: BorderRadius.circular(12),
),
child: Column(
children: [
Spacer(),
Container(width: 200, height: 150,
alignment: Alignment.center,
decoration: BoxDecoration(color: widget.colCompl,
borderRadius: BorderRadius.circular(12),
),
),
Spacer(),
],
),
),
),
);
}
}
colors.dart
import 'dart:ui';
class ColorsApp {
static const Color fons = Color(0xFF444444);
static const Color primari = Color(0xFF7F7F7F);
static const Color text = Color(0xFFFFFFFF);
static List<Color> colCursors = [Color(0xFFFF0000), Color(0xFF00FF00), Color(0xFF0000FF)];
}
estils.dart
import 'package:flutter/material.dart'; import 'package:selector_color/core/colors.dart';
class Estils {
static const TextStyle estilTextNormal = TextStyle(
color: ColorsApp.text,
fontSize: 14,
fontWeight: FontWeight.normal,
);
static const TextStyle estilTextCursors = TextStyle(
color: ColorsApp.text,
fontSize: 18,
fontWeight: FontWeight.bold,
);
static const TextStyle estilTextBotons = TextStyle(
color: ColorsApp.text,
fontSize: 22,
fontWeight: FontWeight.bold,
);
}
funcions.dart
import 'dart:ui';
// Converteix una llista de tres reals en una de tres enters
List<int> intRGBfromDouble(List<double> rebut){
List<int> resposta = [0, 0, 0];
for(int i = 0; i < 3; i++){
resposta[i] = rebut[i].toInt();
}
return resposta;
}
// Agafa una llista de tres enters que codifiquen un color i
// en genera el color corresponent
Color colFromList(List<int> rebut){
return Color.fromARGB(255, rebut[0], rebut[1], rebut[2]);
}
// Agafa una llista de tres enters que codifiquen un color i
// en genera una nova amb el color complementari
List<int> intRGBCompl(List<int> rebut){
List<int> resposta = [0, 0, 0];
for(int i = 0; i < 3; i++){
resposta[i] = 255 - rebut[i];
}
return resposta;
}
// Genera un text que representa un vector de tres components
// a partir d'una llista entera de tres components
// Resultat: (R, G, B)
String txtListFromInt(List<int> rebut){
String resposta = "(";
for(int i = 0; i < 3; i++){
if(i > 0){ // Posem la coma entre components
resposta += ", ";
}
resposta += rebut[i].toString();
}
resposta += ")";
return resposta;
}
// Genera un text amb la codificació hexadecimal d'un color
// a partir d'una llista d'enters que el representen
// Resultat: 0xRRGGBB
String hexFromInt(List<int> rebut){
String resposta = "0x";
for(int i = 0; i < 3; i++){
String prov = rebut[i].toRadixString(16);
if(prov.length == 1){
resposta += "0"; // Forcem que tingui dos dígits
}
resposta += prov.toUpperCase();
}
return resposta;
}

Aquesta obra d'Oriol Boix està llicenciada sota una llicència no importada Reconeixement-NoComercial-SenseObraDerivada 3.0.