Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement backgroundImage for PageViewModel #214

Merged
merged 1 commit into from
Feb 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,9 @@ You can provide many parameters to customize each pages:
- `body: "Body of the page"` or `bodyWidget: Text("Custom widget for body")`
- `image: Image.asset(...)` image of the page.
- It's expecting a Widget, so if you want to pass a Video, Text, or anything else, you can.
- `backgroundImage: 'assets/fullscreen.jpg'` background image of the page (optional).
- It's expecting a String with a path to an image asset. Works just like the `image` parameter under the hood while making an asset span all over the screen.
- Doesn't affect the `image` nor `fullscreen` parameters: can be used together with them to build more complex layouts.
- `footer: ElevatedButton(...)`, display a widget below body
- Like image param, it's expecting a Widget, you can pass what you want.
- `decoration: PageDecoration(...)`, page decoration to customize page
Expand Down
15 changes: 3 additions & 12 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import 'package:introduction_screen/introduction_screen.dart';

void main() => runApp(const App());

const backgroundImage = 'assets/fullscreen.jpg';

class App extends StatelessWidget {
const App({super.key});

Expand Down Expand Up @@ -39,16 +41,6 @@ class OnBoardingPageState extends State<OnBoardingPage> {
);
}

Widget _buildFullscreenImage() {
return Image.asset(
'assets/fullscreen.jpg',
fit: BoxFit.cover,
height: double.infinity,
width: double.infinity,
alignment: Alignment.center,
);
}

Widget _buildImage(String assetName, [double width = 350]) {
return Image.asset('assets/$assetName', width: width);
}
Expand Down Expand Up @@ -117,10 +109,9 @@ class OnBoardingPageState extends State<OnBoardingPage> {
title: "Full Screen Page",
body:
"Pages can be full screen as well.\n\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc id euismod lectus, non tempor felis. Nam rutrum rhoncus est ac venenatis.",
image: _buildFullscreenImage(),
backgroundImage: backgroundImage,
decoration: pageDecoration.copyWith(
contentMargin: const EdgeInsets.symmetric(horizontal: 16),
fullScreen: true,
bodyFlex: 2,
imageFlex: 3,
safeArea: 100,
Expand Down
14 changes: 14 additions & 0 deletions lib/src/helper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,17 @@ extension CustomList<T> on List<T> {
return null;
}
}

bool isBackgroundImageAssetPathValid(String assetPath) {
const validExtensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'];

bool hasValidExtension = validExtensions.any((extension) {
return assetPath.toLowerCase().endsWith('.$extension');
});

if (!hasValidExtension) {
return false;
}

return true;
}
15 changes: 14 additions & 1 deletion lib/src/model/page_view_model.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import 'package:flutter/material.dart';
import 'package:introduction_screen/src/helper.dart';

import '/src/model/page_decoration.dart';

class PageViewModel {
Expand All @@ -18,6 +20,12 @@ class PageViewModel {
/// Tips: Wrap your image with an alignment widget like Align or Center
final Widget? image;

/// Background image of a page.
/// Spans all over the screen.
///
/// Tips: can be used alone or as a background image together with the "image" parameter.
final String? backgroundImage;

/// Footer widget, you can add a button for example
final Widget? footer;

Expand All @@ -43,6 +51,7 @@ class PageViewModel {
this.body,
this.bodyWidget,
this.image,
this.backgroundImage,
this.footer,
this.reverse = false,
this.decoration = const PageDecoration(),
Expand All @@ -65,5 +74,9 @@ class PageViewModel {
assert(
(body == null) != (bodyWidget == null),
"You can not provide both body and bodyWidget.",
);
),
assert(
backgroundImage == null ||
isBackgroundImageAssetPathValid(backgroundImage),
"You must provide a valid image asset path");
}
1 change: 1 addition & 0 deletions lib/src/ui/intro_content.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';

import '/introduction_screen.dart';

class IntroContent extends StatelessWidget {
Expand Down
12 changes: 11 additions & 1 deletion lib/src/ui/intro_page.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';

import '/src/helper.dart';
import '/src/model/page_view_model.dart';
import '/src/ui/intro_content.dart';
Expand Down Expand Up @@ -28,6 +29,14 @@ class _IntroPageState extends State<IntroPage>

return Stack(
children: [
if (page.backgroundImage != null)
Image.asset(
page.backgroundImage!,
fit: BoxFit.cover,
height: double.infinity,
width: double.infinity,
alignment: Alignment.center,
),
if (page.image != null) page.image!,
Positioned.fill(
child: Column(
Expand Down Expand Up @@ -126,7 +135,8 @@ class _IntroPageState extends State<IntroPage>
Widget build(BuildContext context) {
super.build(context);

if (widget.page.decoration.fullScreen) {
if (widget.page.decoration.fullScreen ||
widget.page.backgroundImage != null) {
return _buildStack();
}
return _buildFlex(context);
Expand Down