hadss_adaptive_video 1.0.0-rc.0
hadss_adaptive_video: ^1.0.0-rc.0 copied to clipboard
A adaptive short video immersion and rotation rule plugin project.
example/lib/main.dart
/*
* Copyright (c) 2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import 'package:example/video_page.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:hadss_adaptive_video/hadss_adaptive_video.dart';
import 'package:provider/provider.dart';
void main() {
runApp(ChangeNotifierProvider(
create: (context) => AppState(), child: const MyApp()));
}
class AppState with ChangeNotifier {
double _topBlankHeight = 0.0;
double get topBlankHeight => _topBlankHeight;
set topBlankHeight(double height) {
_topBlankHeight = height;
notifyListeners();
}
double _bottomBlankHeight = 0.0;
set bottomBlankHeight(double height) {
_bottomBlankHeight = height;
notifyListeners();
}
double get bottomBlankHeight => _bottomBlankHeight;
Color _bottomNavColor = Colors.transparent;
Color get bottomNavColor => _bottomNavColor;
set bottomNavColor(Color color) {
_bottomNavColor = color;
notifyListeners();
}
double _currentVideoWidth = 0.0;
double get currentVideoWidth => _currentVideoWidth;
set currentVideoWidth(double width) {
_currentVideoWidth = width;
notifyListeners();
}
double _currentVideoHeight = 0.0;
double get currentVideoHeight => _currentVideoHeight;
set currentVideoHeight(double height) {
_currentVideoHeight = height;
notifyListeners();
}
double defaultBottomNavHeight = 0.0;
double defaultTopHeight = 0.0;
}
final RouteObserver<ModalRoute<dynamic>> routeObserver =
RouteObserver<ModalRoute<dynamic>>();
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
// 应用默认支持自由旋转
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
navigatorObservers: [routeObserver],
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final List<IconData> _icons = [
Icons.video_library,
Icons.search,
Icons.person
];
final List<String> _labels = ['首页', '搜索', '个人'];
late List<String> _videoDataList = [
'assets/videos/4_3.mp4',
'assets/videos/1_1.mp4',
'assets/videos/9_16_1.mp4',
'assets/videos/9_16_2.mp4',
'assets/videos/16_9.mp4',
'assets/videos/3_4.mp4'
];
@override
void initState() {
super.initState();
AdaptiveRotation().registerEvent();
SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);
SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
statusBarColor: Colors.transparent,
statusBarIconBrightness: Brightness.light,
));
// 进入页面先设置状态栏和底部导航的高度
WidgetsBinding.instance.addPostFrameCallback((_) {
Provider.of<AppState>(context, listen: false).defaultBottomNavHeight =
56.0 + MediaQuery.of(context).padding.bottom;
Provider.of<AppState>(context, listen: false).defaultTopHeight =
MediaQuery.of(context).padding.top;
// 设置顶部部空白占位高度
Provider.of<AppState>(context, listen: false).topBlankHeight =
MediaQuery.of(context).padding.top;
// 设置底部空白占位高度
Provider.of<AppState>(context, listen: false).bottomBlankHeight =
56.0 + MediaQuery.of(context).padding.bottom;
// 设置底部导航栏颜色
Provider.of<AppState>(context, listen: false).bottomNavColor =
Colors.black;
});
if (kIsWeb) {
_videoDataList = [
'videos/4_3.mp4',
'videos/1_1.mp4',
'videos/9_16_1.mp4',
'videos/9_16_2.mp4',
'videos/16_9.mp4',
'videos/21_9.mp4'
];
}
}
@override
void dispose() {
super.dispose();
AdaptiveRotation().unregisterEvent();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
Align(
alignment: Alignment.topCenter,
child: Consumer(builder: (context, AppState state, Widget? child) {
return Container(
width: double.infinity,
height: double.infinity,
color: Colors.black,
child: Column(
children: [
SizedBox(
width: double.infinity,
height: state.topBlankHeight,
),
Expanded(
child: PageView.builder(
scrollDirection: Axis.vertical,
itemCount: _videoDataList.length,
pageSnapping: true,
itemBuilder: (context, index) {
return VideoPlayerPage(
videoUrl: _videoDataList[index],
);
}),
),
SizedBox(
width: double.infinity,
height: state.bottomBlankHeight,
)
],
),
);
})),
Align(alignment: Alignment.bottomCenter, child: _bottomNav())
],
));
}
Widget _bottomNav() {
return Consumer(builder: (context, AppState state, Widget? child) {
return Container(
decoration: const BoxDecoration(
border: Border(
top: BorderSide(
color: Colors.green,
width: 2,
)),
),
child: Container(
width: double.infinity,
height: state.defaultBottomNavHeight,
color: state.bottomNavColor,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: List.generate(_icons.length, (index) {
return _buildNavItem(_icons[index], _labels[index]);
}),
),
),
);
});
}
Widget _buildNavItem(IconData icon, String label) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 6.0),
child: Column(children: [
Icon(
icon,
color: Colors.white,
size: 20,
),
Text(
label,
style: const TextStyle(color: Colors.white, fontSize: 16),
)
]),
);
}
}