creta_news 0.4.0
creta_news: ^0.4.0 copied to clipboard
Beautiful Headline News widget using Google News RSS for Flutter (Web, Windows, Android).
example/lib/main.dart
import 'package:creta_news/creta_news.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const DemoApp());
}
class DemoApp extends StatefulWidget {
const DemoApp({super.key});
@override
State<DemoApp> createState() => _DemoAppState();
}
class _DemoAppState extends State<DemoApp> {
ThemeMode _mode = ThemeMode.light;
Nation _nation = Nation.korea;
bool _showTitle = true;
bool _showDate = true;
int _count = 5;
final _controller = CretaHeadlineNewsController();
bool _anim = false;
HeadlineAnimationStyle _style = HeadlineAnimationStyle.ticker;
double _interval = 5;
int _total = 30;
bool _leadingIndexVisible = true;
IconData _leadingIcon = Icons.circle;
double _fontSize = 14;
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Creta News Demo',
themeMode: _mode,
theme: ThemeData.light(),
darkTheme: ThemeData.dark(),
home: Scaffold(
appBar: AppBar(
title: const Text('Creta Headline News Demo'),
actions: [
IconButton(
icon: const Icon(Icons.refresh),
onPressed: _controller.refresh,
tooltip: 'Refresh',
),
IconButton(
icon: const Icon(Icons.brightness_6),
onPressed: () => setState(() {
_mode = _mode == ThemeMode.light ? ThemeMode.dark : ThemeMode.light;
}),
tooltip: 'Toggle theme',
),
],
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.all(12),
child: Wrap(
spacing: 12,
crossAxisAlignment: WrapCrossAlignment.center,
children: [
DropdownButton<Nation>(
value: _nation,
onChanged: (v) => setState(() => _nation = v ?? Nation.korea),
items: const [
DropdownMenuItem(value: Nation.korea, child: Text('Korea')),
DropdownMenuItem(value: Nation.usa, child: Text('USA')),
DropdownMenuItem(value: Nation.japan, child: Text('Japan')),
],
),
Row(
mainAxisSize: MainAxisSize.min,
children: [
const Text('Animation'),
Switch(value: _anim, onChanged: (v) => setState(() => _anim = v)),
],
),
DropdownButton<HeadlineAnimationStyle>(
value: _style,
onChanged: (v) => setState(() => _style = v ?? HeadlineAnimationStyle.ticker),
items: const [
DropdownMenuItem(
value: HeadlineAnimationStyle.ticker, child: Text('Ticker')),
DropdownMenuItem(
value: HeadlineAnimationStyle.carousel, child: Text('Carousel')),
DropdownMenuItem(value: HeadlineAnimationStyle.fade, child: Text('Fade')),
],
),
Row(
mainAxisSize: MainAxisSize.min,
children: [
const Text('Show Title'),
Switch(value: _showTitle, onChanged: (v) => setState(() => _showTitle = v)),
],
),
Row(
mainAxisSize: MainAxisSize.min,
children: [
const Text('Show Date'),
Switch(value: _showDate, onChanged: (v) => setState(() => _showDate = v)),
],
),
Row(
mainAxisSize: MainAxisSize.min,
children: [
const Text('Count'),
Slider(
value: _count.toDouble(),
min: 1,
max: 10,
divisions: 9,
label: '$_count',
onChanged: (v) => setState(() => _count = v.toInt()),
),
],
),
Row(
mainAxisSize: MainAxisSize.min,
children: [
const Text('Total'),
Slider(
value: _total.toDouble(),
min: 10,
max: 50,
divisions: 8,
label: '$_total',
onChanged: (v) => setState(() => _total = v.toInt()),
),
],
),
Row(
mainAxisSize: MainAxisSize.min,
children: [
const Text('Leading Index'),
Switch(
value: _leadingIndexVisible,
onChanged: (v) => setState(() => _leadingIndexVisible = v),
),
],
),
if (!_leadingIndexVisible)
DropdownButton<IconData>(
value: _leadingIcon,
onChanged: (v) => setState(() => _leadingIcon = v ?? Icons.circle),
items: const [
DropdownMenuItem(value: Icons.circle, child: Text('Circle')),
DropdownMenuItem(value: Icons.arrow_right, child: Text('Arrow Right')),
DropdownMenuItem(
value: Icons.chevron_right, child: Text('Chevron Right')),
DropdownMenuItem(
value: Icons.radio_button_checked, child: Text('Radio Checked')),
],
),
Row(
mainAxisSize: MainAxisSize.min,
children: [
const Text('Interval (s)'),
Slider(
value: _interval,
min: 3,
max: 15,
divisions: 12,
label: '${_interval.toStringAsFixed(0)}s',
onChanged: (v) => setState(() => _interval = v),
),
],
),
Row(
mainAxisSize: MainAxisSize.min,
children: [
const Text('Font Size'),
Slider(
value: _fontSize,
min: 10,
max: 48,
divisions: 38,
label: _fontSize.toStringAsFixed(0),
onChanged: (v) => setState(() => _fontSize = v),
),
],
),
],
),
),
Expanded(
child: Padding(
padding: const EdgeInsets.all(16),
child: CretaHeadlineNews(
backendApiUrl: Uri.parse('http://localhost:3000/googleNews'),
width: 700,
height: double.infinity,
nation: _nation,
newsLineCount: _count,
totalNewsCount: _total,
showTitle: _showTitle,
titleText: 'Top Headlines',
showDate: _showDate,
controller: _controller,
animationEnabled: _anim,
animationStyle: _style,
animationInterval: Duration(seconds: _interval.toInt()),
leadingIndexVisible: _leadingIndexVisible,
leadingIcon: _leadingIndexVisible ? null : _leadingIcon,
textStyle:
Theme.of(context).textTheme.bodyMedium!.copyWith(fontSize: _fontSize),
outlineColor: Colors.red,
outlineWidth: 1.9,
),
),
),
],
),
),
),
);
}
}