I want to tie the CoreTheme class to the DarkTheme and LightTheme children so that they share common attributes.
What is the best way or best practice to do this?
I need the method getTheme to be static.
But the way I configured it is not a signature that justifies extending.
CoreTheme.dart:
abstract class CoreTheme {
static const String fontFamily = "GoogleSans";
}
DarkTheme.dart:
import 'package:flutter/material.dart';
import '/core/themes/core_theme.dart';
class DarkTheme implements CoreTheme {
static getTheme() {
return ThemeData(
brightness: Brightness.dark,
colorSchemeSeed: Colors.lightBlue[900],
fontFamily: CoreTheme.fontFamily,
);
}
}
LightTheme.dart:
import 'package:flutter/material.dart';
import '/core/themes/core_theme.dart';
class LightTheme implements CoreTheme {
static getTheme() {
return ThemeData(
brightness: Brightness.light,
colorSchemeSeed: Colors.lightBlue[400],
fontFamily: CoreTheme.fontFamily,
);
}
}
Thank you! =)
Related
As you can see in the pics, when I try to double click in the text field to show the copy paste dialogue, it show this issue, in the terminal it says
'
══════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The getter 'pasteButtonLabel' was called on null.
Receiver: null
Tried calling: pasteButtonLabel
The relevant error-causing widget was:
MaterialApp file:///Users/home/Desktop/the%20authentic%20home%20final/theauthentichome/lib/main.dart:136:22
════════════════════════════════════════════════════════════════════════════════════════════════════'
May you have a look at the following pics to have a better understanding about the issue.
The main.dart file :
'import 'dart:async';
import 'dart:io';
import 'package:admob_flutter/admob_flutter.dart';
import 'package:flutterstore/config/router.dart' as router;
import 'package:dynamic_theme/dynamic_theme.dart';
import 'package:flutterstore/provider/ps_provider_dependencies.dart';
import 'package:flutterstore/viewobject/common/language.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:provider/single_child_widget.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutterstore/config/ps_theme_data.dart';
import 'package:flutterstore/provider/common/ps_theme_provider.dart';
import 'package:flutterstore/repository/ps_theme_repository.dart';
import 'package:flutterstore/utils/utils.dart';
import 'package:easy_localization/easy_localization.dart';
import 'config/ps_colors.dart';
import 'config/ps_config.dart';
import 'db/common/ps_shared_preferences.dart';
Future<void> main() async {
// add this, and it should be the first line in main method
WidgetsFlutterBinding.ensureInitialized();
final FirebaseMessaging _fcm = FirebaseMessaging();
if (Platform.isIOS) {
_fcm.requestNotificationPermissions(const IosNotificationSettings());
}
final SharedPreferences prefs = await SharedPreferences.getInstance();
if (prefs.getString('codeC') == null) {
await prefs.setString('codeC', null);
await prefs.setString('codeL', null);
}
Admob.initialize(Utils.getAdAppId());
//check is apple signin is available
await Utils.checkAppleSignInAvailable();
runApp(EasyLocalization(
path: 'assets/langs',
startLocale: PsConfig.defaultLanguage.toLocale(),
supportedLocales: getSupportedLanguages(),
child: PSApp()));
}
List<Locale> getSupportedLanguages() {
final List<Locale> localeList = <Locale>[];
for (final Language lang in PsConfig.psSupportedLanguageList) {
localeList.add(Locale(lang.languageCode, lang.countryCode));
}
print('Loaded Languages');
return localeList;
}
class PSApp extends StatefulWidget {
#override
_PSAppState createState() => _PSAppState();
}
Future<dynamic> initAds() async {
if (PsConfig.showAdMob && await Utils.checkInternetConnectivity()) {
// FirebaseAdMob.instance.initialize(appId: Utils.getAdAppId());
}
}
class _PSAppState extends State<PSApp> {
Completer<ThemeData> themeDataCompleter;
PsSharedPreferences psSharedPreferences;
#override
void initState() {
super.initState();
}
Future<ThemeData> getSharePerference(
EasyLocalization provider, dynamic data) {
Utils.psPrint('>> get share perference');
if (themeDataCompleter == null) {
Utils.psPrint('init completer');
themeDataCompleter = Completer<ThemeData>();
}
if (psSharedPreferences == null) {
Utils.psPrint('init ps shareperferences');
psSharedPreferences = PsSharedPreferences.instance;
Utils.psPrint('get shared');
psSharedPreferences.futureShared.then((SharedPreferences sh) {
psSharedPreferences.shared = sh;
Utils.psPrint('init theme provider');
final PsThemeProvider psThemeProvider = PsThemeProvider(
repo: PsThemeRepository(psSharedPreferences: psSharedPreferences));
Utils.psPrint('get theme');
final ThemeData themeData = psThemeProvider.getTheme();
themeDataCompleter.complete(themeData);
Utils.psPrint('themedata loading completed');
});
}
return themeDataCompleter.future;
}
List<Locale> getSupportedLanguages() {
final List<Locale> localeList = <Locale>[];
for (final Language lang in PsConfig.psSupportedLanguageList) {
localeList.add(Locale(lang.languageCode, lang.countryCode));
}
print('Loaded Languages');
return localeList;
}
#override
Widget build(BuildContext context) {
// init Color
PsColors.loadColor(context);
return MultiProvider(
providers: <SingleChildWidget>[
...providers,
],
child: DynamicTheme(
defaultBrightness: Brightness.light,
data: (Brightness brightness) {
if (brightness == Brightness.light) {
return themeData(ThemeData.light());
} else {
return themeData(ThemeData.dark());
}
},
themedWidgetBuilder: (BuildContext context, ThemeData theme) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'مفرشي',
theme: theme,
initialRoute: '/',
onGenerateRoute: router.generateRoute,
localizationsDelegates: <LocalizationsDelegate<dynamic>>[
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
EasyLocalization.of(context).delegate,
],
supportedLocales: EasyLocalization.of(context).supportedLocales,
locale: EasyLocalization.of(context).locale,
);
}));
}
}'
images for references:
the iOS device error message
the terminal code message
A quick Google search suggests that this might be connected to the available localisations. Have you tried adding DefaultCupertinoLocalizations.delegate to your localizationsDelegates in MaterialApp?
(This is just a wild guess, may very well be that it's no use...)
I am trying the mobX State management for flutter. But whenever I am updating my #observable State directly rather than calling an #action decorated method it is throwing 'MobXException'
Below code will will give you a proper idea.
counter.dart
import 'package:mobx/mobx.dart';
part 'counter.g.dart';
class Counter = CounterBase with _$Counter;
abstract class CounterBase implements Store {
#observable
int value = 0;
#action
void increment() {
value++;
}
}
main.dart
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import './counter.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: "Counter",
home: CounterExample(),
);
}
}
class CounterExample extends StatelessWidget {
final _counter = Counter();
#override
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(
title: const Text('Counter'),
),
body: Center(
child: Observer(
builder: (_) => Text(
'${_counter.value}',
style: const TextStyle(fontSize: 50),
)),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
// _counter.increment(); // WORKING !!
_counter.value = _counter.value+1; // NOT WORKING !!
},
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
using the increment method is working but why even for some simple state change I need to make another method? why the generated setter is not sufficient?
But whenever I am updating my #observable State directly rather than calling an #action decorated method it is throwing 'MobXException'
That's a feature. MobX purposefully prevents you from mutating observables outside of an action.
Move that logic in a method of your store instead.
I know I am missing something very fundamental here but I am attempting to use some json to create a list of cards in flutter. i am very new to coding and am not understanding the creation of a class constructor and the application of the json to it. i can receive the response and by printing to the console i can see that i can parse the json but having it appear as text on the cards is where i am having issues. Any help is appreciated in applying the json to the class and I plan to use a listview to populate the card details.
This is the code for the api call and the widget build:
import 'package:flutter/material.dart';
import './views.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
class BodyText extends StatelessWidget {
final List<ViewObject> fetcheddata = [];
#override
Widget build(BuildContext context) {
testapi();
return ListView.builder(
itemCount: fetcheddata.length,
itemBuilder: cardBuilder,
);
}
Widget cardBuilder(BuildContext context, int index) {
return Card(
child: Text(thisobject.brandname), etc etc
);
}
void testapi() async {
http
.get('urlgoeshere')
.then((http.Response response) {
final Map<String, dynamic> viewslistdata = json.decode(response.body);
viewslistdata.forEach((String view, dynamic viewdata) {
ViewObject thisobject = ViewObject(
brandName: viewdata['brandname'],
appName: viewdata['appname'],
views: viewdata['Views']);
fetcheddata.add(thisobject);
});
});
}
}
and this is the class constructor
import 'package:flutter/material.dart';
class ViewObject {
final String appName;
final String brandName;
final int views;
ViewObject(
{#required this.appName , #required this.brandName, #required this.views});
}
As you can tell I am new to coding and especially dart/flutter so apologies for the bad code. I have searched for an answer but not found anything to help fully.
You need to convert your StatelessWidget into a StatefulWidget and call setState on fetcheddata.add(thisobject)
setState((){
fetcheddata.add(thisobject);
})
This is one official example of simple BarChart for Flutter app - https://google.github.io/charts/flutter/example/bar_charts/simple
I wood like fetch data from Internet for this chart. Here is the data - http://skazkimal.ru/hr-metrics/headcount.json
My code is not work, because method _createSampleData is async:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:hr_metrics/FetchChartData.dart';
import 'package:http/http.dart' as http;
class SalaryView extends StatelessWidget{
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('FFFFFFFFF'),
),
body: Padding(
padding: const EdgeInsets.all(10.0),
child: new SalaryChart.withSampleData(),
),
);
}
}
class SalaryChart extends StatelessWidget{
final List<charts.Series> seriesList;
final bool animate;
SalaryChart(this.seriesList, {this.animate});
/// Creates a [BarChart] with sample data and no transition.
factory SalaryChart.withSampleData() {
return new SalaryChart(
_createSampleData(),
// Disable animations for image tests.
animate: true,
);
}
#override
Widget build(BuildContext context) {
// This is just a simple bar chart with optional property
// [defaultInteractions] set to true to include the default
// interactions/behaviors when building the chart.
// This includes bar highlighting.
//
// Note: defaultInteractions defaults to true.
//
// [defaultInteractions] can be set to false to avoid the default
// interactions.
return new charts.BarChart(
seriesList,
animate: animate,
defaultInteractions: true,
barRendererDecorator: new charts.BarLabelDecorator<String>(),
vertical: false,
);
}
/// Create one series with sample hard coded data.
static Future<List<charts.Series<ChartData, String>>> _createSampleData() async {
final data = await fetchData(http.Client());
return [
new charts.Series<ChartData, String>(
id: 'Numbers',
domainFn: (ChartData series, _) => series.period,
measureFn: (ChartData series, _) => series.count,
data: data,
labelAccessorFn: (ChartData series, _) => '${series.count.toString()}'
)
];
}
}
/// Sample ordinal data type.
class OrdinalSalary {
final String year;
final int salary;
OrdinalSalary(this.year, this.salary);
}
You cannot use an async method in a constructor like that. Instead, you should create an async method like so:
static Future<SalaryChart> withSampleData() => _createSampleData().then((data) => SalaryChart(data, animate: true));
Which you would use elsewhere:
SalaryChart myChart = await SalaryChart.withSampleData();
Creating a earthquake information app using this api:
https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.geojson
But getting this error after running application:
Error: A value of type 'dart.core::List<#lib1::Data>' can't beassigned to a variable of type 'dart.core::List<#lib2::Data>'.
E/flutter ( 9986): Try changing the type of the left hand side, or casting the right hand side to 'dart.core::List<#lib2::Data>'.
E/flutter ( 9986): _quakes = quakes;
My flutter version: Flutter 0.5.7-pre.100 • channel master
Codes: api.dart
import 'dart:async';
import 'dart:convert';
import 'package:flutter_layout/project/quake/models/quake.dart';
import 'package:flutter_layout/project/quake/models/serializers.dart';
import 'package:http/http.dart' as http;
const String baseUrl = 'https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.geojson';
Future<List<Data>> getQuake() async {
final response = await http.get((Uri.parse(baseUrl)));
print("${response.toString()}");
Quake quake = serializers.deserializeWith(Quake.serializer, json.decode(response.body));
return quake.features.map((Properties properties) => properties.properties).toList();
}
quake.dart
import 'package:built_collection/built_collection.dart';
import 'package:built_value/built_value.dart';
import 'package:built_value/serializer.dart';
part 'quake.g.dart';
abstract class Quake implements Built<Quake, QuakeBuilder> {
BuiltList<Properties> get features;
Quake._();
factory Quake([updates(QuakeBuilder b)]) = _$Quake;
static Serializer<Quake> get serializer => _$quakeSerializer;
}
abstract class Properties implements Built<Properties, PropertiesBuilder> {
Data get properties;
Properties._();
factory Properties([updates(PropertiesBuilder b)]) = _$Properties;
static Serializer<Properties> get serializer => _$propertiesSerializer;
}
abstract class Data implements Built<Data, DataBuilder> {
double get mag;
String get place;
Data._();
factory Data([updates(DataBuilder b)]) = _$Data;
static Serializer<Data> get serializer => _$dataSerializer;
}
QuakeApp.dart
import 'package:flutter/material.dart';
import 'QuakeListView.dart';
import 'models/api.dart';
import 'models/quake.dart';
class QuakeApp extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return QuakeAppState();
}
}
class QuakeAppState extends State<QuakeApp>{
List<Data> _quakes = [];
#override
void initState() {
super.initState();
getQuake().then((quakes){
_quakes = quakes;
});
}
List<QuakeListItem> buildListWidget(){
return _quakes.map((post) => QuakeListItem(
mag: post.mag,
place: post.place,
)).toList();
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Quake App"),
centerTitle: true,
),
body: RefreshIndicator(
onRefresh: () async{
getQuake().then((quakes){
setState(() {
_quakes = quakes;
print("${quakes.length}");
});
});
},
child: AnimatedCrossFade(
duration: Duration(microseconds: 300),
firstChild: Center(
child: CircularProgressIndicator(),
),
secondChild: ListView(
children: buildListWidget(),
),
crossFadeState: _quakes != null ? CrossFadeState.showSecond : CrossFadeState.showFirst,
),
),
);
}
}
Any Solution?
I guess this is the known issue https://github.com/dart-lang/sdk/issues/33076
Do not use relative imports in lib/main.dart (only 'package:...' imports)
and do not import lib/main.dart from any other file.